🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

解決済

1回答

14563閲覧

GASのトリガーで関数に引数を渡したい

help_heaven

総合スコア9

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

1クリップ

投稿2021/02/27 11:14

GASのスクリプトを秘匿したい。
「5つのステップで実現するonEditトリガーを外出しする方法」というページの手法でうまく秘匿できました。
簡単に言うとスタンドアロン型のスクリプトで手動でトリガーを設置するという手法です。

問題は複数のスプレッドシートにonOpenトリガーを設置し関数に引数を渡したいがそれができない。
スプレッドシートごとにたくさんの似たような関数を書けばそれで解決するが、スッキリしたコードを書きたい。どうせ秘匿するのだけれど。

//トリガーを設定するプログラム
var id = ""; //トリガー設定対象のファイルID
function setTrigger() {
var file = SpreadsheetApp.openById(id); //スプレッドシート以外であれば他のファイル用に変更してください。
var functionName = "runScript"; //トリガーを設定したい関数名
ScriptApp.newTrigger(functionName)
.forSpreadsheet(file)
.onEdit().create();
}

どうやったら関数に引数を渡せますか?
引数は二次元配列をfor文で回してidlist[i]みたいに渡したいです。
runScript(idlist[i])のようにやってもうまくいきません。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/02/27 12:19

目的は、「for文を使用して複数のスプレッドシートにonOpenトリガーを設置したい」ということでしょうか? それとも、「setTrigger内で呼び出す関数(質問文でいうとrunScript関数)に引数を渡したい」ということでしょうか。 それとも上記の両方を満たすものを希望されているということでしょうか。 後者または両方の場合、「setTrigger内で呼び出す関数(質問文でいうとrunScript関数)に渡す引数」とは、具体的にはどのようなものなのでしょうか(どう利用するのか)
help_heaven

2021/02/27 13:22

お返事ありがとうございます。両方を満たしたいです。 複数の利用者ごとにスプレッドシートを1枚与え、利用者がスプレッドシートを開くとスクレイピングをして必要な情報をシートに書き出す関数をonOpenで呼び出したいです。引数にはスプレッドシートのIDやスクレイピング先のURLのドメインの一部など全て文字列を格納した配列を渡したいです。
guest

回答1

0

ベストアンサー

トリガー発火時、トリガー先の関数に暗黙的に引数が渡されます。、
この引数はシートごとに異なるid(18~19桁の整数)となっています。
したがって、トリガー先に渡すべき引数を、このidと紐づけて、プロジェクトのプロパティストアに保存する、という戦略になります。

下記、setup()関数の中のworksheetsという配列は、あらかじめ、各々のスプレッドシートidと紐付け先のURLを設定したものになります。
(この部分は、設定用のスプレッドーシートを別に作っておいて、そのシートからセル範囲指定で取得した方が楽かもしれませんが、それはお好みで)

そして、setup()関数を一度だけ実行します。
あとは、各シートを開けば、それぞれに紐付けられた引数(url)が渡されます。
(下のサンプルでは、単純にセルA1にurlが表示されるようになっています)

setup()は一度だけ実行すること。トリガー登録済みの状態で2回以上重ねて実行すると、同じトリガーが複数回発生してしまう。
setup内のworksheets配列を変更し反映させたい場合は、一番下のdelAllTriggers()を実行してトリガーを一度全部削除してから再度setupを実行すること。

GAS

1// V8以前にも対応できるように敢えて古い書き方をしている。 2 3// 下記setup()を一度だけ実行する。 4// テーブルの中身を変更した場合は、delAllTriggers()を実行してから再度setupする。 5function setup(){ 6 //シートIDとスクレイピング対象のURLの対応テーブル 7 var worksheets = [ 8 { id:"スプレッドシートID1", url:"スクレイピング対象のurl01" }, 9 { id:"スプレッドシートID2", url:"スクレイピング対象のurl02" }, 10 { id:"スプレッドシートID3", url:"スクレイピング対象のurl03" }, 11 { id:"スプレッドシートID4", url:"スクレイピング対象のurl04" }, 12 ]; 13 14 for(var i in worksheets){ 15 setTriggerFor(worksheets[i]); 16 } 17} 18 19// シートごとにトリガーを設定し、triggerIDごとに渡したい引数を保存する 20function setTriggerFor(sheet) { 21 var file = SpreadsheetApp.openById(sheet.id); 22 var functionName = "runScript"; //トリガーを設定したい関数名 23 var trigger = ScriptApp.newTrigger(functionName) 24 .forSpreadsheet(file) 25 .onOpen().create(); 26 27 // 関数に渡す引数をtriggerIDと紐付けして保存 28 var triggerUid = trigger.getUniqueId(); 29 var obj = {}; 30 obj['args']= {url: sheet.url}; // 「args」は単なる目印。削除の時に便利なので。 31 PropertiesService.getScriptProperties().setProperty(triggerUid, JSON.stringify(obj)); 32} 33 34 35function runScript(sender) { 36 var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); 37 38 // プロパティストアから、idに紐付いた引数を取り出す。 39 var args = getargs(sender.triggerUid); 40 41 // 以下カスタマイズ。シートごとに異なる引数を渡す処理を書く。 42 // 例:セルA1に、個別のURLを書き込む 43 sheet.getRange(1,1).setValue(args.url); 44} 45 46// プロパティストアからトリガーのidをキーとして引数を取り出す。 47function getargs(triggerUid) { 48 var props = PropertiesService.getScriptProperties(); 49 var obj = JSON.parse(props.getProperty(triggerUid)); 50 return obj['args']; 51} 52 53// トリガー/プロパティを全削除する 54function delAllTriggers() { 55 // トリガーの削除 56 var triggers = ScriptApp.getProjectTriggers(); 57 for (var i in triggers){ 58 if(triggers[i].getHandlerFunction() == "runScript"){ 59 ScriptApp.deleteTrigger(triggers[i]); 60 } 61 } 62 63 // プロパティの削除 64 var prop = PropertiesService.getScriptProperties(); 65 var keys = prop.getKeys(); 66 for (var i = 0; i < keys.length; i++) { 67 if (JSON.parse(prop.getProperty(keys[i])).args){ 68 prop.deleteProperty(keys[i]); 69 } 70 } 71} 72 73

投稿2021/02/27 15:28

編集2021/02/27 15:33
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

help_heaven

2021/02/28 09:22

希望通りの動きをするようになりました。勉強になりました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問