先日、もり(@moripro3)さんから、「スプレッドシートの二次元配列の要素をGASでカッコよく検索できないか?」というツイートがありました。
【HELP】
GASで、スプレッドシートの二次元配列に[指定の要素が存在するか]をカッコよく検索できる方法を探しています。
二重ループはいまいち…
indexOfは一次元配列のみ…
someメソッド使う…?VBAのFindメソッドのように、1行で書ける方法はないでしょうか…
— もり (@moripro3) 2019年1月29日
二次元配列の検索となると、findIndex関数か?とも思ったのですが、今のGASでは使えません。
仕方が無いので、Array.prototype.concat.applyを使って一次元配列にしてからindexOfを使う方法を考えてみました。
function myFunction() { var cells = SpreadsheetApp.getActiveSheet().getRange(2, 2, 3, 3); var result = Array.prototype.concat.apply([],cells.getValues()).indexOf("なにぬねの"); if (result >= 0) { SpreadsheetApp.getUi().alert("指定した値のセルが見つかりました。"); } else { SpreadsheetApp.getUi().alert("指定した値のセルが見つかりませんでした。"); } }
無理やり感はありますが、大分シンプルです。
ただ、個人的にはヒットしたセルをオブジェクトとして使えるようにしたいところですので、下記のようなコードも書いてみました。
function myFunction2() { var cells = SpreadsheetApp.getActiveSheet().getRange(2, 2, 3, 3); var cell = getMatchRange(cells, "わをん"); if(cell === void 0){ SpreadsheetApp.getUi().alert("指定した値のセルが見つかりませんでした。"); } else { cell.activate(); } } //指定した値にマッチする最初のセルを返す function getMatchRange(cells, str) { var reg = new RegExp("^" + str + "$"); //必要に応じて条件は変更 for (var col = 1; col <= cells.getNumColumns(); col++) { for (var row = 1; row <= cells.getNumRows(); row++) { var cell = cells.getCell(row, col); if (cell.getValue().match(reg)) { return cell; } } } }
セル範囲を1つずつ調べていき、ヒットしたらRangeを返すという、非常に泥臭い処理ですが、ヒットしたセルに対して何らかの処理を行いたい場合には使えるコードだと思います。
これで一先ず目的は達することが出来ましたが、もっとスマートな方法はないものか・・・!?🤔
2019/2/1 追記:
もり(@moripro3)さんがご自身のブログで記事を書かれていました。
同じ目的でも書き方は色々あって面白いですね!
この記事へのコメントはありません。