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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Google Apps Script

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

Q&A

解決済

2回答

4755閲覧

スプレッドシート内に複数のタブ(シート)がある場合の.getSheetByNameがうまく作動しない

misato03

総合スコア12

Google Apps Script

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

0グッド

1クリップ

投稿2018/11/14 03:48

編集2018/11/14 05:48

# 課題:.getSheetByName がうまく動作しない(GAS)

## 状況:
・スプレッドシート内に複数タブ(シート名:A,B,C,D,E)があり、それぞれを呼び出す.getSheetByNameを記述しているが、実行反映されるのがシート名:Eのみになってしまう

やりたいこと:

・Twitterのフォロワーを自動取得
・参考スクリプト:https://yurilog.cc/3375
・5アカウントあるためシートを5つ作っている(シート名:A,B,C,D,E)ため、それぞれのシートが更新されるようにしたい

### やったこと:
・上記参考スクリプトをまず実装し挙動確認
・その後、.getSheetByName部分を各シート名(シート名:A,B,C,D,E)に変更
・毎日更新したいため、毎日0-1時でトリガーセット

function writeData() { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); var sheet = spreadsheet.getSheetByName('A'); var today = Utilities.formatDate(new Date(), "JST","yyyy/MM/dd") var row = sheet.getLastRow() + 1; sheet.getRange(row, 1).setValue(today); getTwitterFollowers(row, 2); } function getTwitterFollowers(row, col) { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); var sheet = spreadsheet.getSheetByName("A"); var url = sheet.getRange(1, col).getValue(); var postheader = {![イメージ説明](27c2c96675ed7aab8c8ffb6e5f85e377.png) "timeout":"50000" } var parameters = { "method":"get", "muteHttpExceptions": true, "headers": postheader } var html = UrlFetchApp.fetch(url, parameters).getContentText('UTF-8'); Logger.log(html); var searchTag = 'followers'; var index = html.indexOf(searchTag) if (index !== -1) { html = html.substring(index + searchTag.length); //searchTag = '<div class="statnum">'; //searchTag = 'data-count='; searchTag = 'title="'; index = html.indexOf(searchTag); if (index !== -1) { html = html.substring(index + searchTag.length); //index = html.indexOf('</div>'); //index = html.indexOf(' '); index = html.indexOf(' Followers"'); if (index !== -1) { sheet.getRange(row, col).setValue(html.substring(0, index)); } } } }

イメージ説明

fanction名変更後のキャプチャ
イメージ説明

トリガー設定画面
イメージ説明

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

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

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

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

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

papinianus

2018/11/14 04:09

トリガーの設定を教えてください。それと、例えばE.gsの関数はなんという名前ですか?同じ名前ではないですか?
misato03

2018/11/14 05:48

先にmacaron_xxx さんからの回答に対してfanction名を変更してみました。トリガーの設定は現在各ファンクションに対してセットしているものをキャプチャ追加しました。ご確認宜しくお願い致します。
papinianus

2018/11/14 06:11

そういう対策をするのであれば、getTwitterFollowersについても同じ処置をしなければなりません。つまり、getTwitterFollowersA,getTwitterFollowersB…といった風に
papinianus

2018/11/14 06:12

この場合、writeDataAの閉じカッコの最後にあるgetTwitterFollowersはgetTwitterFollowersAとしなければいけません。
misato03

2018/11/14 06:20

なるほど!ありがとうございます、試してみます。ぜひ回答のほうにもコメント転記いただければ高評価つけさせていただきたく。ご検討くださいませ
misato03

2018/11/14 06:25

できました!ありがとうございました!ぜひコメント欄のほうにも回答いただければ幸いです
guest

回答2

0

ベストアンサー

引数で対応

とは、こういう感じです。未検証。
これで、loopAllだけトリガに設定すれば勝手に全部のシートを巡回してくれる(はず)。

ポイントを箇条書きで書くと、こういう感じですかね
0. getsheetbynameを関数内でやるから同じことを繰り返してかかないといけない
0. sheetを外から貰えばいい == 引数でうけとる
0. ということは全部のシートを巡回してくれるやつがいる(loopAll)
0. そのためには、フォロワーも書き込むのではなく、データだけ取って、書き込むところは一箇所にしたほうがいい

javascript

1function loopAll() { 2 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 3 const sheets = spreadsheet.getSheets(); //全部のシートが取れる 4 for(var i = 0; i < sheets.length; i++) { 5 const url = sheets[i].getRange(1, 2).getValue(); //シートからurlをとる 6 const dat = [[Utilities.formatDate(new Date(), "JST","yyyy/MM/dd"), fetchTwitterFollowers(url)]]; //とったurlを関数に渡す 7 appendTo(sheets[i], dat); //作ったデータを書いてもらう 8 } 9} 10 11function appendTo(sheet, dat) { //末尾にデータを書くやつ、シートとデータは外からもらう 12 const rowToSet = sheet.getLastRow() + 1; 13 sheet.getRange(rowToSet, 1, dat.length, dat[0].length).setValues(dat); 14} 15function fetchTwitterFollowers(url) { //フォロワーだけ取得する(書き込まない)、urlは外からもらう 16 const postheader = { 17 "timeout":"50000" 18 } 19 const parameters = { 20 "method":"get", 21 "muteHttpExceptions": true, 22 "headers": postheader 23 } 24 var html = UrlFetchApp.fetch(url, parameters).getContentText('UTF-8'); 25 var searchTag = 'followers'; 26 var index = html.indexOf(searchTag) 27 if (index === -1) { return "error1"; } 28 html = html.substring(index + searchTag.length); 29 searchTag = 'title="'; 30 index = html.indexOf(searchTag); 31 if (index === -1) { return "error2"; } 32 html = html.substring(index + searchTag.length); 33 index = html.indexOf(' Followers"'); 34 if (index === -1) { return "error3"; } 35 return html.substring(0, index); 36}

投稿2018/11/14 06:43

papinianus

総合スコア12705

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

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

0

たぶん全部同じfunction名にしているため、後勝ちになっているんだと思います。

  1. function名をすべてA~E固有につける
  2. functionA~Eをすべてトリガーを設定する。

あるいは
0. function名をすべてAE固有につける
0. functionA
Eをすべて呼び出すfunction(親)を作成する
0. 親functionをトリガーを設定する。

投稿2018/11/14 04:16

macaron_xxx

総合スコア3191

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

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

misato03

2018/11/14 05:44

早急な回答ありがとうございます! さっそく >function名をすべてA~E固有につける >functionA~Eをすべてトリガーを設定する。 こちら変更後、Aのみ実行してみたところ、また取得反映されたのがEのシートになってしまいました。 ほかの記述も変える必要があれば追加教えていただけると嬉しいです。 変更後のキャプチャも追加しました。
misato03

2018/11/14 05:56

追記します。 行った変更&挙動結果 になります。 変更点 ・全部 function writeData になっていたものを、それぞれ function writeDataA、function writeDataB、、、と変更 ・その後トリガー設定で それぞれfunction writeDataA~function writeDataEを選択しなおして再設定 挙動 ・その後、 A.gs のGAS画面から実行を押す ・Aシートには日付のみはいる ・Eシートにフォロワー数がはいる という結果でした。
macaron_xxx

2018/11/14 06:23

あー getTwitterFollowersも固有の関数名にしてください。 ようは、同じプロジェクト上に同じ関数名を宣言しないでください。
macaron_xxx

2018/11/14 06:25

functionわけずに引数で対応したほうがよい気がした。
misato03

2018/11/14 06:28

papinianusさんからも同様の指摘をうけまして、変更してみたところ希望する挙動が確認できました! 参考までに、 >functionわけずに引数で対応 というのがどういうことか、お手すきでお伺いできると非常に嬉しいです。ご検討いただけると幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問