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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

6639閲覧

GASの書き方が冗長なので簡素なものになるのか見てもらいたいです

i-bunta

総合スコア20

Google Apps Script

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2017/01/31 01:23

編集2017/01/31 01:25

#やりたいこと
Googleスプレッドシートにて作成した日別のスケジュールをGoogle Calendarへイベント追加するスクリプトを組みました。
javascriptは触り始めたばかりなのですが、時間を扱っている部分がどうにも冗長だなと思っています。この辺りの簡素な書き方があれば教えて頂けたら嬉しいです。

実装したのはスプレッドシートで当日のスケジュールを立ててそれを指定のカレンダーに転記するという内容です。
表は

開始時間終了時間Todo
9:009:30text

このような表が続くイメージです。

流れとしては

  1. new Date()で当日の日付等の情報を取得し、それぞれtYやtMなどの西暦や月に分ける。
  2. スプレッドシートの9:00 ~ 9:30などの部分の時間と分をsHやeMなどの変数に代入。(getValue()で抜き出すと1899年などになってしまった為、getHours()で数字だけ抜いてます)
  3. new Date()から取得したtYや、スプレッドシートから取得したsHを元にイベントの日時情報を構成しカレンダーにイベントを作成する
function myFunction() { var title, description; var sH,sM,eH,eM; var today = new Date(); var tY = today.getFullYear(); var tM = today.getMonth(); var tD = today.getDate(); var sheet = SpreadsheetApp.getActiveSheet(); var objCalendar = CalendarApp.getCalendarById('カレンダーID'); for (var i = 2; i <= sheet.getLastRow(); i++) { if (sheet.getRange(i, 3).getValue() != ""){ title = sheet.getRange(i, 6).getValue(); sH = sheet.getRange(i, 1).getValue().getHours(); sM = sheet.getRange(i, 1).getValue().getMinutes(); eH = sheet.getRange(i, 2).getValue().getHours(); eM = sheet.getRange(i, 2).getValue().getMinutes(); description = sheet.getRange(i, 4).getValue(); objCalendar.createEvent(title, new Date( tY, tM, tD , sH, sM ), new Date( tY, tM, tD , eH, eM ), {description:description}); } } }

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

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

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

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

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

guest

回答2

0

ベストアンサー

冗長とまでは思いませんでしたが、一つしか使用していない変数が不要なので削除してみました。
また、「カレンダーID」を直接指定していたり、今日(today)を直接指定している点が汎用性にかけた為、引数を利用する形にしてみました。

JavaScript

1function myCalendar (calendarId /* [, year, month, day] */) { 2 var today = new Date(); 3 var argumentsLength = arguments.length; 4 var year = argumentsLength > 2 ? arguments[1] : today.getFullYear(); 5 var month = argumentsLength > 3 ? arguments[2] : today.getMonth(); 6 var day = argumentsLength > 4 ? arguments[3] : today.getDate(); 7 var sheet = SpreadsheetApp.getActiveSheet(); 8 var getRange = sheet.getRange.bind(sheet); 9 var objCalendar = CalendarApp.getCalendarById(calendarId); 10 11 for (var i = 2, len = sheet.getLastRow() + 1, sheetDate1, sheetDate2; i < len; i++) { 12 if (getRange(i, 3).getValue() != ""){ 13 sheetDate1 = getRange(i, 1).getValue(); 14 sheetDate2 = getRange(i, 2).getValue(); 15 objCalendar.createEvent(getRange(i, 6).getValue(), 16 new Date( year, month, day , sheetDate1.getHours(), sheetDate1.getMinutes() ), 17 new Date( year, month, day , sheetDate2.getHours(), sheetDate2.getMinutes() ), 18 {description: getRange(i, 4).getValue()} 19 ); 20 } 21 } 22}

Re: i-bunta さん

投稿2017/01/31 03:17

編集2017/01/31 04:55
think49

総合スコア18156

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

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

i-bunta

2017/01/31 04:40

ご回答ありがとうございます! ただ、 var year = argumentsLength > 2 arguments[1] : today.getFullYear(); で「ステートメントの前に;がありません」というエラーが出てしまいました... いまいちargumentsの使い方がわからず今ググって見ています。 またカレンダーIDは function myCalendar (calendarId /* [, year, month, day] */) のcalendarId に入れる形ですよね? スクリプトをいじれない方もゼロから触る可能性があるので、セル内にcalendarId を入力する箇所を用意しそこから参照しようかと思いましたのでここは自分でやってみようと思います。 何はともあれご回答ありがとうございます!
think49

2017/01/31 04:56 編集

失礼しました。三項演算子の ? が抜けていたので修正しました。 ついでに getRange の呼び出し回数が比較的多かったので sheet.getRange.bind(sheet) で this 束縛してみました。 仮引数部の year, month, day をコメントアウトすれば arguments は不要ですが、その場合は myCalendar.length === 4 になってしまう(第四引数まで必須を明示する)のであえて arguments で参照するようにしています。 カレンダーIDは第一引数で指定する認識で合っています。
guest

0

「時間を扱っている部分がどうにも冗長」という質問への回答ではないのですが、今のコードだとAPIの呼び出し回数が多いです。

本のコードだと1ループで19回のSpreadSheetのAPIを使用していますが、getValuesで一気に配列に読み込んでから処理するとよいです。

カレンダーへの登録であればそれほど数が多くないと思いますが参考にしてください。カレンダーへの登録処理は削除しています。

JavaScript

1var gasheet = "******************"; 2function test(){ 3 var title, description; 4 var sH,sM,eH,eM; 5 var today = new Date(); 6 var tY = today.getFullYear(); 7 var tM = today.getMonth(); 8 var tD = today.getDate(); 9 var ss = SpreadsheetApp.openById(gasheet); 10 var sheet = ss.getSheetByName("シート1"); 11 12 var table = sheet.getRange(2,1,sheet.getLastRow()-1,6).getValues(); 13 table.forEach(function(values){ 14 if( values[2] != ""){ // C列 15 title = values[5]; // F列 16 sH = values[0].getHours(); // A列 17 sM = values[0].getMinutes(); // A列 18 eH = values[1].getHours(); // B列 19 eM = values[1].getMinutes(); // B列 20 description = values[3]; // D列 21 } 22 }); 23}

投稿2017/02/01 04:10

hikochang

総合スコア648

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問