みの雑多ブログ

勉強したことをアウトプットしたり、しなかったり

GASを使って条件を満たす値を改行区切りでセルに入力していく

とてもコアな内容
昔はエクセルで、単純作業嫌だからマクロで作ってたけど今はスプレッドシート使いがちなので。
同じような考え方で、単純作業をスクリプトで実装してみた。
GASの細かい基礎的なところは一旦省いて、そのままアウトプット

やりたいこと

人名×好きなものリスト
f:id:yamami78651:20210507173043p:plain
今夜のディナーは?リスト
f:id:yamami78651:20210507173555p:plain
好きなものから、食材の方を参照して料理を改行区切りでセルに入力したい

あくまで例なので、これくらいの量なら、普通に入力してもよいかも。
実際のケースでは人名に当たるものが1000近くあり、食材に当たるものが100近くあるので、辛いなと思い適当にスクリプトを書いた。

スクリプト実行のボタン設置(任意)

これは無くてもいい。(エクセルでも同じ)
普通にエディタから実行できるから。
でも気分上げるためにボタン置いたり、画像置いたりする。

f:id:yamami78651:20210507181531p:plain
挿入 > 図形描画 / 画像 選んで、挿入したものをクリックして右上の・・・を押すと↑のような状態に

スクリプトを割り当てる」で、自分の書いたスクリプト(デフォルトならmyFunctionとか)入力して登録すると、
画像や図形をクリックするだけで割り当てたスクリプトが実行されるようになる。

自分以外の人が使うとき(GASに詳しくない人のために作ったとき)とかは、ボタン置いてあげると喜ばれるかも!
実際に非エンジニアに依頼されたときは、修造さんと図形にスクリプトを割り当ててる
f:id:yamami78651:20210507182119p:plain

実装

function myFunction() {

  const ss = SpreadsheetApp.getActiveSpreadsheet();

  var ffMaxRow = ss.getSheetByName('人名×好きなものリスト').getRange("B:B").getValues().filter(String).length + 1; // 入力されている行数を取得
  var favoriteFoods = ss.getSheetByName('人名×好きなものリスト').getRange("B2:B" + ffMaxRow).getValues(); // スプレッドF列を配列に入れる

  var mMaxRow = ss.getSheetByName('今夜のディナーは?リスト').getRange("A:A").getValues().filter(String).length + 1;
  var menu= ss.getSheetByName('今夜のディナーは?リスト').getRange("A2:B" + mMaxRow).getValues();

  for(var i = 0; i < favoriteFoods.length; i++) {
    // 好きなものがない人はスキップ
    if(favoriteFoods[i] == "") continue;

    var resultList = [];
    var searchWord = favoriteFoods[i].toString().split('\n'); // 改行区切りの文字列を配列に変換

    for(var j = 0; j < searchWord.length; j++) {

      for(var k = 0; k < menu.length; k++) {

        if(searchWord[j] == menu[k][0]) {
          resultList[j] = menu[k][1];
          break;
        }
      }
    }

    // 結果を入力
    ss.getSheetByName('人名×好きなものリスト').getRange("C" + (i + 2)).setValue(resultList.join('\n')); // 文字列を改行区切りに変換
  }
}

実行後
f:id:yamami78651:20210507190550p:plain

直したいところだらけやけど、列や行の指定はどこかで宣言しておいてそこ変えるだけでいいよって状態にしたい&結果を入力も配列に格納して最後に入力したい
エクセルもスプレッドシートもセルの情報は配列にぶち込んで操作するということを残しておきたかった