質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.10%

【GAS】テキストファインダー、部分一致でセル検索がうまくいかない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,930

前提・実現したいこと

GoogleFormとSpreadsheetを使用して報告書の代わりにするアプリを作成しています。
ここで、日本語文字列を正規表現を使い textFinder.findAll() で検索する際にエラーが発生しました。

実現したいのは日本語の文字列を該当のセル範囲の中から部分一致で検索しRangeを取得することです。

今回、該当のセル範囲とは
1行目の空白でない最後の列まで
です。

発生している問題・エラーメッセージ

ログは以下のように出力されます。
問題は配列の中身が存在していないことです。
つまり、検索機能がうまく機能していないものと考えられるのです。

実際にはB1、つまり、行1列2に会場名という文字列を含んだテキストが存在しています。

[20-03-20 23:58:57:135 JST] lastCol:237
[20-03-20 23:58:57:151 JST] modiKey:
/.*会場名.*/
[20-03-20 23:58:57:259 JST] []

該当のソースコード

function myFunction() {
//アクティブなスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();

//ListというシートをSheetAnswerという変数に代入
  var SheetAnswer = ss.getSheetByName("List");

//検索範囲を決定するために最終列を取得
  var lastCol = SheetAnswer.getLastColumn();

//検索範囲のRangeを代入
  var findRange = SheetAnswer.getRange(1, 1, 1, lastCol);

//検索したい文字列を変数に代入
  var key = "会場名";

//変数を使っているので正規表現化できないため、RegExp()を使用
  var modiKey = new RegExp(".*" + key + ".*");

//正規表現が出力されるか確認
  Logger.log("modiKey:" + modiKey);

//上記の正規表現を使ったtextFinderを正規表現を使用する形でtfという変数に代入
  var tf = findRange.createTextFinder(modiKey).useRegularExpression(true);

//textFinder.findAll()の関数を利用してRangeを配列に格納する
  var values = tf.findAll();

//配列の中身を確認
  Logger.log(values);

//配列内のRangeをA1Notationで出力
  for( var value in values){
   Logger.log(values[value].getA1Notation());
  }
}

試したこと

日本語文字列が問題で、英語ではどうかと思い、以下のソースコードを試しました。

function myFunction() {
//アクティブなスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();

//ListというシートをSheetAnswerという変数に代入
  var SheetAnswer = ss.getSheetByName("List");

//検索範囲を決定するために最終列を取得
  var lastCol = SheetAnswer.getLastColumn();

//検索範囲のRangeを代入
  var findRange = SheetAnswer.getRange(1, 1, 2, lastCol);

//検索したい文字列を変数に代入
  var key = "test";

//変数を使っているので正規表現化できないため、RegExp()を使用
  var modiKey = new RegExp(".*" + key + ".*");

//正規表現が出力されるか確認
  Logger.log("modiKey:" + modiKey);

//上記の正規表現を使ったtextFinderを正規表現を使用する形でtfという変数に代入
  var tf = findRange.createTextFinder(modiKey).useRegularExpression(true);

//textFinder.findAll()の関数を利用してRangeを配列に格納する
  var values = tf.findAll();

//配列の中身を確認
  Logger.log(values)

//配列内のRangeをA1Notationで出力
  for( var value in values){
   Logger.log(values[value].getA1Notation());
  }
}

それでも正常に機能せず、ログは以下のようになります。
また、testという文字列を含むセルはC2、つまり、行2列3に存在しています。

[20-03-21 00:12:07:243 JST] lastCol:237
[20-03-21 00:12:07:259 JST] modiKey:
/.*test.*/
[20-03-21 00:12:07:492 JST] []

また、正規表現に誤りがあるかと考え、こちら(http://okumocchi.jp/php/re.php)の正規表現チェッカーを使用してテストしましたが、やはり正規表現に問題はありませんでした。

補足情報(FW/ツールのバージョンなど)

ちなみに、SpreadSheetのツールからスクリプトを開いて通常のGASの使用をしています。
インポートしたライブラリー等はありません。

以上により完全に行き詰ってしまいました。
どなたかご教授いただけますと幸甚です。

補足情報2

GASのドキュメンテーションを繰り返し読んでみたら、textFinderの中にMatchCaseというものを見つけました。

それにより、完全一致検索がデフォルトではないと分かり、正規表現を使わずに試してみたところ、うまくいきました。

しかし、今回はうまくいきましたが、正規表現を利用した検索をする機会が今後もあると思います。

もし原因お分かりの方いましたら、ぜひご回答お願い致します。

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();

  var SheetAnswer = ss.getSheetByName("List");
  SheetAnswer.activate();
  var lastCol = SheetAnswer.getLastColumn();
  var lastRow = SheetAnswer.getLastRow();

  Logger.log("lastCol:" + lastCol);

  var findRange = SheetAnswer.getRange(1, 1, lastRow, lastCol);

  var key = "会場名";

  var values = findRange.createTextFinder(key).findAll();

  Logger.log(values);

  for ( var value in values){
    Logger.log("A1Notation:" + values[value].getA1Notation());
  }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

テストしてない状態で無責任な回答をします。
(検索対象データがある、は質問者様を信頼します)

createTextFinderはstringを取るので予めRegExにしてしまうとそれがtoSringされてログにあるような文字列と解釈され、検索時にスラッシュを含むものを探そうとしてしまうのではないでしょうか。

検証方法として、/test/をセルに書いて見つかるか、と、.*test.*を文字列のままcreateTextFinderに渡して対象が見つかるか、のいずれかが利用できると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/22 23:53

    ".*test.*を文字列のままcreateTextFinderに渡して対象が見つかるか、"

    こちらの方法で上手くいきました。
    ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る