• ベストアンサー

Google Apps Scriptのトリガー

Google Apps Scriptnの時間主導型トリガーがうまく機能してくれません。 あるプロジェクトを1分毎に自動実行するようにしたいのですが、全く実行されません。 単体のプロジェクトとしては、エラーもなく、手動では問題なく実行できます。 ためしに、別のサンプルコード(特定のセルに1分毎に現在時刻を表示させる)を使ってみたところ、こちらは問題なく自動実行してくれます。 自動実行を有効にするためには何らかの条件が必要なのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
noname#247307
noname#247307
回答No.3

>しかし、そこで新たに疑問に思うのは、最初のコードでトリガーを設定せずに端末からの手動実行した場合に、処理結果に変化がない(数値等の変化がない)にも関わらず、何故アクティブセルが移動するような挙動が端末に表示されるのかということです。 このへんは情報がないので、私も推測するしかないんですが……。おそらくシートを開いてスクリプトを実行させる場合、「シートの画面(ブラウザ内)」「サーバー内のデータ」「スクリプト(の実行エンジン)」の間でAjaxでやりとりがされていると思うのです。トリガーの場合、そのシートが実際に画面に表示されている必要はないわけで、そことの間のやりとりは必ずしも保証されていないのでは……という気がします。(シートを閉じていてもちゃんと動かなければトリガーとして役に立たないわけですから) 私もそのへんになるとはっきりした情報を持っていないので、これは推測として参考程度に考えて下さい。ただ、いずれにしても、トリガーを「現在開いているシートの表示を操作する」という目的で利用するのはやめたほうがいいように思えます。 設定したトリガーは、そのシートを閉じても、またブラウザを終了しても、パソコンを落としても、ずっとGoogleのサーバーで実行され続けている、ということを頭に入れておいたほうが良いです。そうした動きをするという前提で使い方を考えたほうがいいでしょう。

nighty
質問者

お礼

分かりやすく説明していただき、ありがとうございました。

その他の回答 (2)

noname#247307
noname#247307
回答No.2

スクリプトを見ました。こちらで試してみましたが、スクリプト自体はちゃんと動いています。ただ、動いていますが表示は変わりません。activateしてもそのセルが選択されないからです。 おそらく、時間主導型トリガーの働きを勘違いされているのだと思います。これは時間が来ると、(スプレッドシートがブラウザで開かているかどうかには関係なく)スクリプトを実行するものです。開いているシートを操作するものではなくて、どちらかといえ「Googleドライブに保存されているデータにアクセスして操作するもの」ととらえたほうがよいでしょう。 例えば、セルに値を表示する処理は、トリガーで問題なく動きます。トリガーにより指定のセルの値が変更され、開いているシートは内部で変更されたデータと同期をとるので変更が画面に反映されるのです。つまり、画面を操作しているのではなく、「データを変更する→開いたシートがデータと同期される→結果的に表示が変わる」ということです。 activateのようにセルを選択するといった動作は、データとして保存されているシートに命令しても無意味です(エラーにはなりません)。ですからトリガーで操作しても表示には何も反映されません。

nighty
質問者

お礼

shylock様、ありがとうございました。 先程のコードを少し変えて以下のようにしてみると、トリガーが機能して空白行を1で埋めていく結果が表示されました。 function onTmeEdit() { var mySheet=SpreadsheetApp.getActiveSheet(); mySheet.getRange("k200").activate(); var myRange=SpreadsheetApp.getActiveRange(); while(myRange.getValue()=="") { myRange.setValue(1); mySheet.setActiveRange(myRange.offset(-1,0)).activate(); var myRange=SpreadsheetApp.getActiveRange(); } } クラウドで処理しているのだから、処理結果(数値の変化等)だけが端末に表示され、処理結果に変化がなければ端末での表示にも変化はない、ということですね。勘違いしておりました。 しかし、そこで新たに疑問に思うのは、最初のコードでトリガーを設定せずに端末からの手動実行した場合に、処理結果に変化がない(数値等の変化がない)にも関わらず、何故アクティブセルが移動するような挙動が端末に表示されるのかということです。 時間主導型トリガーで自動実行する場合には、「Google Drive上でのトリガー起動」→「クラウドでの処理」→「処理結果がGoogle Driveに戻る」→「端末での同期」という経路を辿る為、処理結果に変化がなければ端末表示も変化しないということだと思いますが、端末から手動実行する場合も、「端末からの実行命令」→「クラウドでの処理」→「処理結果がGoogle Driveに戻る」→「端末での同期」という経路になるのなら、端末上でアクティブセルが勝手に移動する理屈が分かりません。少し話は違いますが、複数のPCで同じアカウントで同じスプレッドシートを開いた際、各端末でのアクティブセルがひとつの画面に色分けして表示される仕組みも理解できません。所詮私のような素人には難しすぎですね…

noname#247307
noname#247307
回答No.1

具体的に、どういうコードを実行させようとしていますか。実行されないのではなく、実行しようとしたがエラーになって動かない、という可能性はありませんか。 よくあるのは、例えばスプレッドシートに何か操作をするようなとき、ActiveSheetなどでSheetを取得し操作しようとしてエラーになっているといったものですね。 時間主導型のトリガーは、そのシートが閉じられている間も実行され続けます。ですから、シートを開いていなくても設定した関数は実行されるのです。結果、ActiveSheetが取得できずにエラーになってしまう、ということが多々あります。 エラーが出ている場合、1日経過後に、前の日に発生したエラー情報がどさっとメールで届くので気がつくはずです。 これ以上は、トリガーで呼び出される関数を見ないとなんともいえません……。

nighty
質問者

補足

すいません。 1分毎に自動実行させたいプロジェクトは、セルk200から、そのセルが空白行である限り1行ずつ上に上げていく以下のようなコードです。特にシートを閉じたりしていないので問題ないと思うのですが… function onTmeEdit() { var mySheet=SpreadsheetApp.getActiveSheet(); mySheet.getRange("k200").activate(); var myRange=SpreadsheetApp.getActiveRange(); while(myRange.getValue()=="") { mySheet.setActiveRange(myRange.offset(-1,0)).activate(); var myRange=SpreadsheetApp.getActiveRange(); } }

関連するQ&A

  • google apps scriptについて

    google apps scriptに関しては全くの初心者ですので、どなたかお力をお貸しください。 現在、Accessでシステムを作っているのですが、システムに新規案件が登録されると自動でグーグルカレンダーにも登録されるようにしています。 具体的には、システムに新規案件が登録されたタイミングで件名を「★マーク+タイトル+日付+時間」、内容に案件詳細を入れたメールをgmailに送り、google apps scriptのトリガーで一定間隔でメールを検索し、件名に★マールの入ったメールがあれば件名に入っている日付・時間でカレンダーに内容を登録するようになっています。 そこで質問なのですが、今度はシステムより同じ内容のメールを送り、そのメール内容と同じものがカレンダーで見つかるとその予定を削除するようなgoogle apps scriptを作りたいのです。 メールのサンプルとgoogle apps scriptのコードは下記のようになっています。 全くの初心者でコードもネットを色々調べて書いたのであまり内容も理解できていません。 どなたか宜しくお願い致します。 メールサンプル 件名: ★取引先と打合せ 2015/08/02_16:00-18:00 内容: 管理NO 9016 2015/08/02 16:00-18:00 発注担当者:様 場所:事務所 登録日:2015/06/19/11:51 コード function setCalLab(){ var thds = GmailApp.getInboxThreads(); var calName = "メールアドレス@gmail.com"; var cals = CalendarApp.getCalendarsByName(calName); for(var n in thds){ var thd = thds[n]; var subject = thd.getFirstMessageSubject(); var msgs = thd.getMessages(); if (subject.indexOf("★",0) != -1){ //label.addToThread(thd); //for(var m in msgs){ var msg = msgs[0]; var body = msg.getPlainBody(); var str = msg.getSubject(); var res = str.match(/\d+/g); var cal = cals[0]; var d1 = new Date(); var yy = d1.getFullYear(); cal.createEvent(str,new Date(res[0],res[1]-1,res[2],res[3],res[4]),new Date(res[0],res[1]-1,res[2],res[5],res[6]),{description:body,sendInvites:false}); //} GmailApp.moveThreadToArchive(thd); } } }

  • Google Apps Scriptの記述

    フォームに入力したら、フォームに基づいてメールを送れるようにしたいと考えています。 そこで次のScriptを記述しました。しかし、フォームに入力し終わってもメールが送信されません。 Google Apps Scriptの参考サイトも無い事と、Googleも仕様を次々新しくしているので持っている書籍があまり参考になりません。 トリガーは次の通りです。 現在のプロジェクトのトリガーで、実行 mySendhokoku イベントスプレッドシートからフォーム送信時 としています。 scriptは function mySendhokoku(e) { var mail_to=e.nameValues["送信先"]; var datetime= new Date(); var hokoku=e.nameValues["報告種類"]; var kaisi=e.nameValues["開始時間"]; var shuryo=e.nameValues["終了時間"]; var kyukei=e.nameValues["休憩時間"]; var biko=e.nameValues["本文備考"]; var today=formatDate(datetime,"MM/dd"); var subject=hokoku+"連絡"+today+"名前"; var body="名前"+"\n\n"; var body=body+"開始時刻"+kaisi+"\n\n"; var body=body+"終了時刻"+shuryo+"\n\n"; var body=body+"休憩時間"+kyukei+"\n\n"; var body=body+biko+"\n\n"; MailApp.sendEmail(mail_to,subject,body); } ちなみに”名前”と言うところは実際は私の名前が入っています。読み替えてください。 日付は5/5などの様に記述したいと思っています。 初心者で至らない点ありますが、よろしくお願いいたします。

  • Google Apps Scriptについて

    Google Apps Scriptについては全くの初心者です。どなたか知恵をお借りしたいです。 accessを使い業務システムを作っているのですが、これまでgoocalproxyというサービスを使い、新規受注を入力すれば、その内容をgmailに飛ばし、自動でグーグルカレンダーに登録させてました。このgoocalproxyが数日前から機能しなくなり、色々調べた結果Google Apps Scriptを使って登録する方法を見つけたのですが、全くの初心者の為、ネットで参考にしたサンプルのコピペしかできず、下記のようなコードを使用しております。 function setCalLab(){ //var dstr = "本日の予定"; //var label = GmailApp.createLabel(dstr); var thds = GmailApp.getInboxThreads(); var calName = "本日の予定"; var cals = CalendarApp.getCalendarsByName(calName); for(var n in thds){ var thd = thds[n]; var subject = thd.getFirstMessageSubject(); var msgs = thd.getMessages(); if (subject.indexOf("本日の予定",0) != -1){ //label.addToThread(thd); //for(var m in msgs){ var msg = msgs[0]; var body = msg.getPlainBody(); var str = msg.getSubject(); var res = str.match(/\d+/g); var cal = cals[0]; var d1 = new Date(); var yy = d1.getFullYear(); var dd = new Date(yy,res[0]-1,res[1]); cal.createAllDayEvent(str,dd,{description:body}); //} GmailApp.moveThreadToArchive(thd); } } } これですと、カレンダーに自動登録は出来るのですが、終日の予定になってしまいます。 やりたい事は、gmail宛てに予定の件名、日付、開始時間、終了時間を送りそれを自動でグーグルカレンダーに開始時間から終了時間までの予定で反映させたいと思っています。 別のサイトで、 function createEvent(){ var calendar = CalendarApp.getCalendarById('xxxxxxxxxx@group.calendar.google.com'); calendar.createEvent('歯医者', new Date('2012/3/12 18:00:00'), new Date('2012/3/12 20:00:00')); } 時間指定のほかに、予定の概要、場所情報を設定することもできる。 function createEvent2(){ var calendar = CalendarApp.getCalendarById('xxxxxxxxxx@group.calendar.google.com'); calendar.createEvent('歯医者', new Date('2012/3/12 18:00:00'), new Date('2012/3/12 20:00:00'), {description: '概要', location: '◯◯病院'} ); } というような情報も見つけたのですが、幾分全くの初心者の為、これをどうすれば思い通りのコードになるのかわかりません。 どなたかご教授お願い致します。

  • Google Apps Scriptのシート名選択

    初めまして。 3日前位からGoogleスプレッドシートのScriptを勉強し始めて 「シート1のA1セルが編集されたらB1に自動で現在時刻を打刻する」 というスクリプトを作っていました。 サイトを見ながらなんとかA1判定からB1自動打刻までいけたのですが シート名がうまく指定出来ていないみたいで シート1だけでなく【シート2】のA1 を編集してもシート1のB1に打刻されてしまいます。 スプレッドシートは極められたのでその先へ行きたいのですが 最初はやっぱり難しくて苦悩しています; 色々間違えてるかもしれませんが、ぜひ身に付けてみたいので 初めの一歩だけご教授をどうかよろしくお願いします。 function insertLastUpdated() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName('シート1'); // rangeXとYにカーソル座標を代入 var rangeX = sheet.getActiveCell().getColumn(); var rangeY = sheet.getActiveCell().getRow(); // シートの座標1,1(A1)が編集されたらB1に現在時刻を打刻(トリガーを編集時に指定) if(rangeX==1&&rangeY==1){ sheet.getRange("B1").setValue(new Date()); } }

  • Google Appsの費用について教えて下さい。

    近々にGoogle Apps for Businessの契約を検討しているのですが、 費用について教えて頂けないでしょうか。 for Businessでは「1ユーザー アカウントあたり月600 円」と書いてありますが、 例えば以下の構成でしたら「月600円×6名=月々3,600円」となるのでしょうか? <例> Aさん@domain.com Bさん@domain.com Cさん@domain.com Dさん@domain.com Eさん@domain.com Fさん@domain.com 昨日、試しに未使用ドメインで無償版を登録して 「組織とユーザー」> 「新しいユーザーを作成」で 各メールアカウントを取得できる事は確認しました。 for Businessも「月600円」で6名分のメール(@domain.com)を発行できるなら、 直ぐ契約したのですが、 「月600円×6名=月々3,600円」であれば厳しいのでレンタルサーバーを借りようと思っています。

  • トリガーの設定が出来ません。

    先日アドバイスを頂き、テストした分は上手く働いたのですが、本番で使用するため、追加のトリガー設定をしたら追加分が起動しませんでした。 ヘルプも読みましたが当方の理解力では、内容を理解出来ませんでした。 「起動できない」、「実行できない」といった表示があるので、何かしら設定ミスをしているのは間違いありません。 誠に申し訳ないですが、再度ご説明をして頂ける方はいらっしゃいませんでしょうか。 <前回頂いた回答> タスク スケジューラで任意の時刻に「Windows Media Player」が起動するようにトリガー設定すればいいでしょう。 添付画像は毎日6:00にトリガー設定する例です。 どの音楽を起動するかはオプション設定で引数を設定すればいいでしょう。 1日のうちで複数回の起動時間を設定しておくことも応用すればかのうです。 タスク スケジューラの使い方はWin7ヘルプを読めば、初心者でも理解できるでしょう。(初心者のためにヘルプが用意されているわけですから・・・)

  • シェルスクリプトの書き方

    お忙しい所失礼します。 以下の内容のようなことを行うにはどうすればいいでしょうか? (例) /home/testフォルダ直下に以下の3つのフォルダがあります。 ・sampleフォルダ ・sample1111フォルダ ・sample2222フォルダ このファイルをそれぞれ別のディレクトリに移動させます。 ・sampleフォルダ→/usr/testフォルダに移動 ・sample1111フォルダ→/usr/test1111フォルダに移動 ・sample2222フォルダ→/usr/test2222フォルダに移動 これが通常なのですが、sample1111と2222が無いときはコピーを実行しないスクリプトを書きたいのですがどう書けばいいのでしょうか? 手動でやる分には楽なんですけど、100個位フォルダがあり…日によって50の時もあれば100の時もあって…自動化したいのです… もし参考になるサイトなどあれば教えてください。 よろしくお願い致します。

  • Google スプレッドシートで日付表示形式を..

    Google スプレッドシートで質問です。 セル(A1)に「May 01, 2020 at 11:01AM」とあるとします。 これを隣のセルに「2020/05/01」と自動で表示させたいのですが、 どのようにすればよいでしょう? 時刻の部分は不要です。いろいろ調べてみましたが、うまくできません。 どうぞよろしくお願いします。

  • EXCEL VBA シート内の特定のセルに値が入…

    EXCEL VBA シート内の特定のセルに値が入力された際に処理を実行するプログラム EXCELシート内の特定のセルに値が入力された際に処理を実行するプログラムをEXCEL VBAで作成したいと考えています。 EXCELに計測データを取込み、このデータが設定値以外の場合のみ、トリガーを出す様なイメージで使いたいと思います。 どの様に考えれば良いでしょうか?サンプル等ありましたら紹介ください。 上記質問の”トリガー”について補足します。 あるセルに値が入力されたら、マクロを実行するという風にしたいという意味です。 単純にマクロ実行を手動で行うのでは無く、ある値が判定値以外の場合に他アプリケーションを操作したいという意味です。。

  • Google apps scriptについて

    Googleドライブのスプレッドシートで作成したスケジュールをGoogleカレンダーに反映するGoogle apps scriptを作成したいと思っています。 下記のサイトが、ほぼイメージに近いのですが、コチラのコードでは、時間の指定ができません。 ○時から○時までという時間の指定をするには、どのようにコードを追加すればよろしいですか? http://pc.nikkeibp.co.jp/article/column/20140210/1120685/?P=6 以上よろしくお願いします。

専門家に質問してみよう