目次
解決したいこと
スプレッドシートはブック内に、いくつもシートを作成することができます。
しかしスプレッドシートを検索する、ような機能がありません。
そこで、スプレッドシートの検索機能を追加します。
完成図
起動するとこのようにサイドバーが出現し、サイドバーから検索でき、クリックするとシートを移動できます。
仕様
- メニューバーに新規メニュー「シート検索バーを開く」を追加
- メニューから「シート検索バーを開く」を選択すると、起動
- 起動すると、シート検索用のサイドバーを立ち上げ
- サイドバー上で目的のシートを検索
- シート名をクリックすると、そのシートが開く
作成解説
スプレッドシートを開き、以下の場所からGASを起動します。
メニューバーから呼び出せるように登録します。
1 2 3 4 5 6 |
function onOpen() { let ui = SpreadsheetApp.getUi() let menu = ui.createMenu('追加機能') menu.addItem('シート検索バーを開く', 'moveSheetByDialog') menu.addToUi() } |
これを、スプレッドシートの起動時に呼び出すように、トリガー(時計のマーク)に登録します。
権限関係でエラーが起きることがありますので、unsafe、もしくは詳細、などのボタンから、許可を選択します。
また、許可を行わないと、GASでシートにアクセスできませんので、許可ウィンドウが出てきたら、許可をします。
するとこのように、通常のメニューに機能の呼び出しが追加されます。
起動スクリプトを記述
ここではSpreadSheetの全てのシート名を取得し、Sidebar起動関数に渡します。
1 2 3 4 5 6 7 8 9 10 |
// 検索機能を呼び出し function moveSheetByDialog(){ let ss = SpreadsheetApp.getActiveSpreadsheet(); let sheets = ss.getSheets(); sheetNames = [] for (var i = 0; i < sheets.length; i++) { sheetNames.push(sheets[i].getName()); } createSearchSideBar(sheetNames) } |
サイドバー起動を記述
ここで、siderbar.htmlを呼び出し、そこにシート名のリストを渡しています。
1 2 3 4 5 6 7 8 9 10 11 |
function createSearchSideBar(sheetNames){ var template = HtmlService.createTemplateFromFile('sidebar.html'); // テンプレート内の変数に値をセット template.data = JSON.stringify(sheetNames) // HtmlOutputオブジェクトを生成 var htmlOutput = template.evaluate() .setWidth(300) SpreadsheetApp.getUi().showSidebar(htmlOutput); } |
サイドバーの中身を記述
サイドバーの中身は、シートのリストからインクリメンタル検索し、結果を表示するものです。
表示された結果のリンクをクリックすると、moveToSheet関数を呼びます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <div>シート名を検索します。</div> <div><input type="text" onkeyup="searchTab(this)"></div> <div id="data" style="display:none;"><?= data ?></div> <div id="itemList"></div> <script> function list2Links(list) { document.getElementById('itemList').innerHTML = ''; // 中身をクリア var html = list.map(function(v) { // 新しいHTMLを生成 //return `<div><a href="#" onclick="google.script.run.moveToSheet('${v}');google.script.host.close();">${v}</a></div>`; return `<div><a href="#" onclick="google.script.run.moveToSheet('${v}');">${v}</a></div>`; }).join(''); document.getElementById('itemList').innerHTML = html; // #itemList にHTMLを設定 } document.addEventListener('DOMContentLoaded', function() { var dataElement = document.getElementById('data'); var data = JSON.parse(dataElement.textContent) list2Links(data) window.searchTab = function(e) { var value = e.value var searchKeywords = value.split(' ').filter(Boolean) // dataから、すべての検索キーワードに一致する要素を探す var searchResults = data.filter(function(item) { return searchKeywords.every(function(keyword) { return item.toLowerCase().includes(keyword.toLowerCase()); }); }); list2Links(searchResults) } }); </script> </body> </html> |
シート移動のための関数を記述
シート移動のための、moveToSheet関数を記述します。
1 2 3 4 5 6 7 8 9 10 11 |
// リンクがクリックされたときに移動する関数 function moveToSheet(sheetName) { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheets = ss.getSheets(); for (var i = 0; i < sheets.length; i++) { if (sheets[i].getName().toLowerCase() === sheetName.toLowerCase()) { ss.setActiveSheet(sheets[i]); // シートに移動 break; } } } |
全コード
二つのファイルのコード全文を記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
//---- // シート選択機能追加 // Written by Sugerfield //---- // メニューにシート選択起動項目を追加 function onOpen() { let ui = SpreadsheetApp.getUi() let menu = ui.createMenu('追加機能') menu.addItem('シート検索バーを開く', 'moveSheetByDialog') menu.addToUi() } // 検索機能を呼び出し function moveSheetByDialog(){ let ss = SpreadsheetApp.getActiveSpreadsheet(); let sheets = ss.getSheets(); sheetNames = [] for (var i = 0; i < sheets.length; i++) { sheetNames.push(sheets[i].getName()); } createSearchSideBar(sheetNames) } function createSearchSideBar(sheetNames){ var template = HtmlService.createTemplateFromFile('sidebar.html'); // テンプレート内の変数に値をセット template.data = JSON.stringify(sheetNames) // HtmlOutputオブジェクトを生成 var htmlOutput = template.evaluate() .setWidth(300) //.setHeight(200); //SpreadsheetApp.getUi().showModalDialog(htmlOutput, '移動先を検索'); SpreadsheetApp.getUi().showSidebar(htmlOutput); } // リンクがクリックされたときに移動する関数 function moveToSheet(sheetName) { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheets = ss.getSheets(); for (var i = 0; i < sheets.length; i++) { if (sheets[i].getName().toLowerCase() === sheetName.toLowerCase()) { ss.setActiveSheet(sheets[i]); // シートに移動 break; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <div>シート名を検索します。</div> <div><input type="text" onkeyup="searchTab(this)"></div> <div id="data" style="display:none;"><?= data ?></div> <div id="itemList"></div> <script> function list2Links(list) { document.getElementById('itemList').innerHTML = ''; // 中身をクリア var html = list.map(function(v) { // 新しいHTMLを生成 //return `<div><a href="#" onclick="google.script.run.moveToSheet('${v}');google.script.host.close();">${v}</a></div>`; return `<div><a href="#" onclick="google.script.run.moveToSheet('${v}');">${v}</a></div>`; }).join(''); document.getElementById('itemList').innerHTML = html; // #itemList にHTMLを設定 } document.addEventListener('DOMContentLoaded', function() { var dataElement = document.getElementById('data'); var data = JSON.parse(dataElement.textContent) list2Links(data) window.searchTab = function(e) { var value = e.value var searchKeywords = value.split(' ').filter(Boolean) // dataから、すべての検索キーワードに一致する要素を探す var searchResults = data.filter(function(item) { return searchKeywords.every(function(keyword) { return item.toLowerCase().includes(keyword.toLowerCase()); }); }); list2Links(searchResults) } }); </script> </body> </html> |