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

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

ただいまの
回答率

90.35%

  • Google Apps Script

    947questions

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

GASを用いたプログラムについて

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 320

Suica31R

score 2

 前提・実現したいこと

Gasを用いて、装置の予約フォームを作製しようとしています。
フォームのスプレッドシートからカレンダーに追加という動作の中で、
カレンダーを参照→タイトルとイベントを取得→同一時刻・同一装置での予約があった場合にメールを送るという部分で手詰まっています。

 発生している問題・エラーメッセージ

①「オブジェクト Calendar で関数 gettitle が見つかりません。」というメールが届きます。
② そもそもカレンダーに予定が追加されません(スプレッドシートには登録されています)

 ソースコード

function sendToCalendar(e) {
try{
//Googlesプレッドシートを開く
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

//新規予約された行番号を取得
var num_row = sheet.getLastRow();

//新規予約された行から名前を取得
var nname = sheet.getRange(num_row, 3).getValue();

//メールアドレスの取得
var nmail = sheet.getRange(num_row,2).getValue();

//予約を記載するカレンダーを取得
var cals = CalendarApp.getCalendarById("aaaa-u.ac.jp-aaaaaaa.calendar.google.com");

//予約の開始時間を取得
var stime = new Date(sheet.getRange(num_row, 6).getValue());

//予約の装置名を取得
var nMachine = sheet.getRange(num_row, 4).getValue();

//予約の終了時間を取得
var etime = new Date(sheet.getRange(num_row, 7).getValue());

var ndate = new Date(sheet.getRange(num_row, 5).getValue());
var ndates= new Date(ndate.getFullYear(),ndate.getMonth(),ndate.getDate(),stime.getHours(),stime.getMinutes(),0);
var ndatee= new Date(ndate.getFullYear(),ndate.getMonth(),ndate.getDate(),etime.getHours(),etime.getMinutes(),0);

// 先約の有無
var calEvents = cals.getEvents(ndates, ndatee);
var caltitle = cals.gettitle(nMachine);

// カレンダーに登録がないためそのまま登録可
if (calEvents.length === 0) {

//予約情報をカレンダーに追加
var r = cals.createEvent(thing, ndates, ndatee);
var thing =nname+" \n\n 予約に成功しました。"

MailApp.sendEmail(nmail,"予約完了",thing);

// カレンダーにイベントがあるので、装置に重複がないかチェック
else {
isEmpty = true;

for (var i in calEvents) {
var event = calEvents[i];

if (event.gettitle() === nMachine) {
isEmpty = false;
break;
}
}
// カレンダーに同一装置で登録がないため登録可
if (isEmpty) {

//予約情報をカレンダーに追加
var r = cals.createEvent(thing, ndates, ndatee);
var thing =nname+" \n\n 予約に成功しました。"

MailApp.sendEmail(nmail,"予約完了",thing);

// カレンダーに同時刻同一装置で登録があるため登録不可
else {
var thing =nname+" \n\n 予約に失敗しました。\n\n 日時と時間を確認してください"

MailApp.sendEmail(nmail,"予約失敗のお知らせ",thing);
}

}

} catch(exp){
//実行に失敗した時に通知
MailApp.sendEmail(nmail, exp.message, exp.message);
}
}

 試したこと

装置の重複チェックに問題があるのかと考えて、
if(cals.getEvents(ndates, ndatee)==0){
var thing = nMachine;
var r = cals.createEvent(thing, ndates, ndatee);
のみに書き直して実行すると正常に動作しました。そのため、問題点はfor文の辺りにあると分かったのですが、どこを修正すれば良いか分かりません。ご教授お願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+1

とりあえず ① ② の現状の問題だけ解決しますね。

Calendarクラスにはgettitle()というメソッドは存在しません。

下記リファレンスを読むことを強くオススメします。
(英語ですが、メソッドの一覧などがわかるので、なんとなく理解できると思います。)
https://developers.google.com/apps-script/reference/calendar/calendar

イベントのタイトルを取得したいので
CalendarEventクラスgetTitle()ですね。

var caltitle = cals.gettitle(nMachine);

カレンダーに登録されないのは、

var calEvents = cals.getEvents(ndates, ndatee);
var caltitle = cals.gettitle(nMachine);

上記でcalEventsCalendarEventクラスの配列が入っていますので、ループしてCalendarEventクラスを取り出し、それぞれにgetTitle()します。

前提として、カレンダーのタイトルに装置名が入っているとすれば、

var calEvents = cals.getEvents(ndates, ndatee, {search: nMachine});

if (calEvents.length === 0) {
    // カレンダーに同一装置で登録がないためそのまま登録可
} else {
    // カレンダーに同一装置で登録があるため登録不可
}

こんな感じでしょうか。

ただし、その他の部分でもかなり気になる部分があるので、
またエラーが出たりするかもしれませんね。。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/09 17:18

    返信有り難うございました。 
    質問の部分、解決しました。そこで、更に同一の装置名で予約が入った場合に拒否するforループ文を追加してみたところ、同一装置で時間が被ってる場合に予約を受け付けないようにできたのですが、受付拒否のメールが送信されません。


    // 先約の有無

    var calEvents = cals.getEvents(ndates, ndatee, {search: nMachine});

    if (calEvents.length === 0) {
    // カレンダーに同一時刻装置で登録がないためそのまま登録可
    var thing = nname+nMachine;"\n\n 予約完了"
    var r = cals.createEvent(thing, ndates, ndatee);
      MailApp.sendEmail(nmail,"予約",thing);
    }else {
    // カレンダーにイベントがあるので、装置に重複がないかチェック
    isEmpty = true;
    for (var i in calEvents) {
    var event = calEvents[i];

    if (event.getTitle() === {search: nMachine}) {
    isEmpty = false;
    break;
    }
    }

    if (isEmpty) {
    // カレンダーに同一装置で登録がないため登録可
    } else {
    // カレンダーに同一装置で登録があるため登録不可
    var nthing =thing; " \n\n 先約があるため、\n 予約できませんでした。"

    MailApp.sendEmail(nmail,"予約できませんでした",nthing);
    }
    }
    }
    catch(exp){
    //実行に失敗した時に通知
    MailApp.sendEmail(nmail, exp.message, exp.message);
    }
    }

    MailApp.sendの位置が悪いのでしょうか?

    キャンセル

  • 2018/07/09 17:47

    var nthing =thing; " \n\n 先約があるため、\n 予約できませんでした。"
    MailApp.sendEmail(nmail,"予約できませんでした",nthing);

    全角が入っていたり、文字列の結合ができていなかったりするからじゃないですか?

    キャンセル

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

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Google Apps Script

    947questions

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