はじめに
最近、spreadsheetで作業していた時にシートが多くなったときに探しずらいし見づらいなと思いました。
私の中では結構ストレスだったのでGASを使いサイドバーにシート一覧を表示させるようにしました。
完成イメージ
inputに入力すれば検索ができて、リストをクリックするとシートに移動します。
コード
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
</head>
<body>
<div class='refresh_btn' onclick="refresh()">一覧を最新に更新</div>
<div class='input_wrap'>
<input id="search_input" type='text' name='search'/>
</div>
<ul id="sheet-list">
</ul>
<script>
const searchInputDom = document.getElementById('search_input');
let allSeet = JSON.parse(<?= JSON.stringify(sheetNames) ?>);
function refresh(){
google.script.run.withSuccessHandler(function(result) {
allSeet = result;
searchSheet(searchInputDom.value)
})
.getSheetNames();
}
function searchSheet(searchWord) {
let liDomText = "";
for (let i = 0; i < allSeet.length; i++){
if(allSeet[i].includes(searchWord)){
liDomText += `<li data-sheet="${allSeet[i]}" onclick="moveSheet('${allSeet[i]}')">${allSeet[i]}</li>`;
}
}
document.getElementById("sheet-list").innerHTML = liDomText;
}
function changeActiveSheet(sheetName){
const activeSheetStyleId = "activeSheetStyle";
const styleElement = document.getElementById(activeSheetStyleId);
if(styleElement) styleElement.parentNode.removeChild(styleElement);
var newStyle = `
<style id="activeSheetStyle">
[data-sheet="${sheetName}"]{
background-color:#d3e3fd;
}
</style>
`
document.body.insertAdjacentHTML('beforeend', newStyle);
}
function moveSheet(sheetName) {
google.script.run.withSuccessHandler(function() {
changeActiveSheet(sheetName)
})
.moveToSheet(sheetName);
}
const debounceInput = _.debounce(function(event) {
searchSheet(event.target.value)
}, 300);
searchInputDom.addEventListener("input", debounceInput);
searchSheet("");
changeActiveSheet(JSON.parse(<?= JSON.stringify(activeSheetName) ?>));
</script>
<style>
.refresh_btn{
cursor:pointer;
width:fit-content;
padding:4px 12px;
background-color:rgb(26,115,232);
color:#fff;
border-radius:4px;
margin-bottom:12px;
margin-right:0;
margin-left:auto;
}
.input_wrap{
position: sticky;
margin-bottom:12px;
}
input{
width:100%;
box-sizing:border-box;
padding:8px;
font-size:14px;
}
ul{
margin:0;
padding:0;
list-style-type: none;
flex-grow:1;
}
li{
font-size:12px;
cursor:pointer;
padding:8px 8px;
border-bottom: 1px solid #cdcdcd;
}
li:hover{
opacity:.7;
}
</style>
</body>
</html>
index.gs
// メニュー作成
function onOpen() {
let ui = SpreadsheetApp.getUi();
ui.createMenu('GAS実行')
.addItem('シート検索', 'openSearchSidebar')
.addToUi();
}
// 検索サイドバーを開く
function openSearchSidebar() {
let ui = SpreadsheetApp.getUi();
let template = HtmlService.createTemplateFromFile('index');
template.sheetNames = getSheetNames()
template.activeSheetName = SpreadsheetApp.getActiveSheet().getName()
let htmlOutput = template.evaluate()
htmlOutput.setTitle('シート検索');
ui.showSidebar(htmlOutput);
}
// 検索用シートリスト取得
function getSheetNames() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheets = ss.getSheets();
sheetNameList = []
for(let i=0; i<sheets.length; i++) {
sheetNameList.push(sheets[i].getSheetName())
}
return sheetNameList;
}
// 指定されたシート名へ遷移
function moveToSheet(sheetName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
sheet = ss.getSheetByName(sheetName)
if(sheet){
ss.setActiveSheet(sheet)
}
}
さいごに
シートの一覧が縦に表示されるだけでかなりストレスがなくなりました。
課題としてはAPIをたたいているのでシートの遷移が遅いことですが、現状対策が思いつきません。
自分で使ってみて検索した状態でも目次などに関しては常に表示させたいなど改修したい点があったり、これとは別にサイドバーからドラッグでシートのソートができるものを作成していたりするのでこの投稿が好評であればまた書こうかなと思ってます。