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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Google Apps Script

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

Q&A

解決済

1回答

1589閲覧

【GAS】B列とC列の文字を連結させてD列に反映させたい

10-mo

総合スコア21

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Google Apps Script

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

0グッド

2クリップ

投稿2021/09/24 02:16

スプレッドシートからGoogleカレンダーに反映させるための作業をしていて、9割がた完成したのですが最後の1ピースが中々解決せずにご質問させていただきました。関数であれば解決できるのですが、誤って削除・重くなるなどデメリットの方が大きいと思うのでGASで解決したいと考えています。

B列には①や②のような数字(課の番号)が入り、C列には予定のタイトル(例:打合せ)が入ります。これを連結させてD列に(①打合せ)のように反映させたいです。
現状、色分けで判別しているものの一々予定をクリックしないと、どこの課の予定か分からないので、タイトルの前に課番号を入力したいです。
関数では分かっても、これがGASになると分からなくなってしまいます。
どうかご教示のほど、よろしくお願いいたします。

※読み取り範囲を広げ、上の列を挿入する。これが完成次第、下記の順番を変更する

GAS

1// カレンダーにスケジュールを登録する 2function CreateSchedule() { 3 4 // 読み取り範囲(表の始まり行と終わり列) 5 const topRow = 3 6 const lastCol = 11 7 const statusCellCol = 1 8 9 10 // 予定の一覧バッファ内の列(0始まり) 11 const statusNum = 0     //「完了」反映される列 12 const startdayNum = 2    //開始日時 13 const startNum = 3      //開始時間 14 const enddayNum = 4     //終了日 15 const endNum = 5       //終了時間 16 const titleNum = 6     //タイトル 17 const locationNum = 7   //場所 18 const descriptionNum = 8 //説明 19 //const colorNum = 9 20 const calnameNum = 1 //カレンダー名の列 21 const EventIDCol = 11 //K列 22 23 24 // シートを取得 25 const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet() 26 27 // 予定の最終行を取得 28 const lastRow = sheet.getLastRow() 29 30 //予定の一覧をバッファに取得 31 const contents = sheet.getRange(topRow, 1, sheet.getLastRow(), lastCol).getValues() 32 33 // googleカレンダーの取得 34 let Calendar = CalendarApp.getDefaultCalendar() 35 36 // バッファの内容に従って予定を作成 37 for (let i = 0; i <= lastRow - topRow; i++) { 38 39 //「完了」の場合は無視する 40 if (contents[i][statusNum] === '完了') { 41 continue 42 } 43 44 // 値をセット 日時はフォーマットして保持 45 let startday = contents[i][startdayNum] 46 let startTime = contents[i][startNum] 47 let endday = contents[i][enddayNum] 48 let endTime = contents[i][endNum] 49 let title = contents[i][titleNum] 50 let calname = contents[i][calnameNum] //設定するカレンダー名 51 52 // 場所と詳細をセット 53 let options = { location: contents[i][locationNum], description: contents[i][descriptionNum] } 54 55 console.log(startday + " " + contents[i][titleNum]) 56 57 try { 58 let calevent 59 60 //カレンダーの設定 61 if (calname === "") { 62 calendar = CalendarApp.getDefaultCalendar() 63 } 64 else { 65 let calendars = CalendarApp.getCalendarsByName(calname); 66 for (let s in calendars) { 67 Calendar = calendars[s] 68 console.log("カレンダー指定 -> " + calendars[s].getName()) 69 } 70 } 71 72 // 終了日の有無をチェック 73 if (endday === '') { 74 endday = startday //終了日に開始日を入れておく 75 } 76 77 let startDate = new Date(startday) 78 let endDate = new Date(endday) 79 80 // 開始終了時刻が無ければ終日で設定 81 if (startTime == '' || endTime == '') { 82 endDate.setDate(endDate.getDate() + 1) //★なぜか1日プラスする 83 console.log("設定する終了日 -> " + endDate) 84 85 //終日の予定を作成 86 calevent = Calendar.createAllDayEvent( 87 title, 88 startDate, 89 endDate, 90 options 91 ) 92 93 // 時間指定ありで予定を作成する 94 } else { 95 // 開始日時を設定する 96 startDate.setHours(startTime.getHours()) 97 startDate.setMinutes(startTime.getMinutes()) 98 99 //終了日時を設定する 100 endDate.setHours(endTime.getHours()) 101 endDate.setMinutes(endTime.getMinutes()) 102 103 // 日時付きの予定を作成する 104 calevent = Calendar.createEvent( 105 title, 106 startDate, 107 endDate, 108 options 109 ) 110 } 111 112 //イベントIDをK列に追加する 113 console.log(calevent.getId()) 114 sheet.getRange(topRow + i, EventIDCol).setValue(calevent.getId()) 115 116 117 //予定が作成されたら「完了」にする 118 sheet.getRange(topRow + i, statusCellCol).setValue('完了') 119 120 // エラーの場合ログ出力する 121 } catch (e) { 122 Logger.log(e) 123 } 124 } 125}

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

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

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

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

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

guest

回答1

0

ベストアンサー

B列には①や②のような数字(課の番号)が入り、
C列には予定のタイトル(例:打合せ)が入ります。
これを連結させてD列に(①打合せ)のように反映させたいです。

forを抜けた後に、以下の記述を追加すればどうでしょうか。

GAS

1 const B = 2 2 const D = 4 3 const ROWS = lastRow - topRow + 1 4 const merge = sheet.getRange(topRow, B, ROWS, 2) 5 .getDisplayValues() 6 .map( v => [ v.join('') ] ) 7 sheet.getRange(topRow, D, ROWS).setValues(merge)

投稿2021/09/24 03:50

編集2021/09/24 03:53
mayu-

総合スコア335

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

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

mayu-

2021/09/24 11:04 編集

結合処理のタイミングを重要視してなかったため、こちらに追記します。 ご提示のGASをもう一度拝見したところ ループ中に「連結値」を利用出来るというご期待を見落としていたかもしれません。 もし、その懸念が的中しているようでしたら、お手数ですが回答のコードを //予定の一覧をバッファに取得 の直前に記述するよう、位置の変更をお願いいたします。
10-mo

2021/09/25 06:02

mayu様 ありがとうございます!すごいです!合体できました! ただ一つ問題がおきまして、エラーが発生してしまいました…どこが悪いのか検討つかず、こちらもご教示いただきますでしょうか?
10-mo

2021/09/25 06:03 編集

// カレンダーにスケジュールを登録する function CreateSchedule() { // 読み取り範囲(表の始まり行と終わり列) const topRow = 3 const lastCol = 11 const statusCellCol = 1 // 予定の一覧バッファ内の列(0始まり) const statusNum = 0     //「完了」反映される列 const startdayNum = 3    //開始日時 const startNum = 4      //開始時間 const enddayNum = 5     //終了日 const endNum = 6       //終了時間 const titleNum = 7     //タイトル const locationNum = 8   //場所 const descriptionNum = 9 //説明 //const colorNum = 10 const calnameNum = 1 //カレンダー名の列 const EventIDCol = 11 //K列 // シートを取得 const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet() // 予定の最終行を取得 const lastRow = sheet.getLastRow() //B列とC列の値を合体させて、H列に反映させる=カレンダーに反映される内容 const B = 2 const D = 8 const ROWS = lastRow - topRow + 1 const merge = sheet.getRange(topRow, B, ROWS, 2) .getDisplayValues() .map( v => [ v.join('') ] ) sheet.getRange(topRow, D, ROWS).setValues(merge) //予定の一覧をバッファに取得 const contents = sheet.getRange(topRow, 1, sheet.getLastRow(), lastCol).getValues() // googleカレンダーの取得 let Calendar = CalendarApp.getDefaultCalendar() // バッファの内容に従って予定を作成 for (let i = 0; i <= lastRow - topRow; i++) { //「完了」の場合は無視する if (contents[i][statusNum] === '完了') { continue } // 値をセット 日時はフォーマットして保持 let startday = contents[i][startdayNum] let startTime = contents[i][startNum] let endday = contents[i][enddayNum] let endTime = contents[i][endNum] let title = contents[i][titleNum] let calname = contents[i][calnameNum] //設定するカレンダー名 // 場所と詳細をセット let options = { location: contents[i][locationNum], description: contents[i][descriptionNum] } console.log(startday + " " + contents[i][titleNum]) try { let calevent //カレンダーの設定 if (calname === "") { calendar = CalendarApp.getDefaultCalendar() } else { let calendars = CalendarApp.getCalendarsByName(calname); for (let s in calendars) { Calendar = calendars[s] console.log("カレンダー指定 -> " + calendars[s].getName()) } } // 終了日の有無をチェック if (endday === '') { endday = startday //終了日に開始日を入れておく } let startDate = new Date(startday) let endDate = new Date(endday) // 開始終了時刻が無ければ終日で設定 if (startTime == '' || endTime == '') { endDate.setDate(endDate.getDate() + 1) //★なぜか1日プラスする console.log("設定する終了日 -> " + endDate) //終日の予定を作成 calevent = Calendar.createAllDayEvent( title, startDate, endDate, options ) // 時間指定ありで予定を作成する } else { // 開始日時を設定する startDate.setHours(startTime.getHours()) startDate.setMinutes(startTime.getMinutes()) //終了日時を設定する endDate.setHours(endTime.getHours()) endDate.setMinutes(endTime.getMinutes()) // 日時付きの予定を作成する calevent = Calendar.createEvent( title, startDate, endDate, options ) } // //色の設定 // if (contents[i][colorNum] != "") { // let color = getcolornum(contents[i][colorNum]) // // console.log(title) // calevent.setColor(color) // } //ここから追加 //イベントIDをK列に追加する console.log(calevent.getId()) sheet.getRange(topRow + i, EventIDCol).setValue(calevent.getId()) //ここまで追加 //予定が作成されたら「完了」にする sheet.getRange(topRow + i, statusCellCol).setValue('完了') // エラーの場合ログ出力する } catch (e) { Logger.log(e) } } // 完了通知 // Browser.msgBox("予定を追加しました。") }* Googleカレンダーからイベントを削除する * 先頭カラムが空白の行のイベントを削除する */ function DeletEvent() { // 読み取り範囲(表の始まり行と終わり列) const topRow = 3 const lastCol = 11 const statusCellCol = 1 const EventIDCol = 11 //K列 // 予定の一覧バッファ内の列(0始まり) const statusNum = 0 const startdayNum = 3 const startNum = 4 const enddayNum = 5 const endNum = 6 const titleNum = 7 const locationNum = 8 const descriptionNum = 9 //const colorNum = 10 //色の列 const calnameNum = 1 //カレンダー名の列 const eventNum = 11 //イベントID // シートを取得 const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet() //カレンダーの設定 let Calendar = CalendarApp.getDefaultCalendar() // 予定の最終行を取得 let lastRow = sheet.getLastRow() //B列とC列の値を合体させて、H列に反映させる=カレンダーに反映される内容 const B = 2 const D = 8 const ROWS = lastRow - topRow + 1 const merge = sheet.getRange(topRow, B, ROWS, 2) .getDisplayValues() .map( v => [ v.join('') ] ) sheet.getRange(topRow, D, ROWS).setValues(merge) //予定の一覧をバッファに取得 const contents = sheet.getRange(topRow, 1, sheet.getLastRow(), lastCol).getValues() //順に予定を作成 for (let i = 0; i <= lastRow - topRow; i++) { //「完了」の場合は無視する if (contents[i][statusNum] === "完了") { continue } let title = contents[i][titleNum] let CalendarName = contents[i][calnameNum] //設定するカレンダー名 let eventID = contents[i][eventNum] console.log(eventID) try { let event //カレンダーの切り替え if (CalendarName !== "") { let calendars = CalendarApp.getCalendarsByName(CalendarName); for (let i in calendars) { Calendar = calendars[i] console.log(calendars[i].getName()) } } //保持していたイベントIDからイベントを削除する let delevent = Calendar.getEventById(eventID) //イベントの削除 delevent.deleteEvent() // エラーの場合ログ出力する } catch (e) { Logger.log(e) } } // 完了通知 // Browser.msgBox("予定を追加しました。") } //イベントの更新 function UpdateEvent() { DeletEvent() //イベントの削除 CreateSchedule() //イベントの追加 }
10-mo

2021/09/25 06:04

エラーの内容 Exception: Invalid argument: iCalId undefined と表示されます。 お忙しい中、大変恐縮ですが、よろしくお願いいたします。
mayu-

2021/09/25 08:09 編集

問題があるとしたら、DeletEvent() のロジックでしょうか。 セル範囲を代入した配列 contents に対する参照は 添字が 0スタートのため、A列からK列までに置き換えると以下のようになります contents[0][0] = A3の値 contents[0][1] = B3の値 contents[0][2] = C3の値 contents[0][3] = D3の値 contents[0][4] = E3の値 contents[0][5] = F3の値 contents[0][6] = G3の値 contents[0][7] = H3の値 contents[0][8] = I3の値 contents[0][9] = J3の値 contents[0][10] = K3の値 シートに対する列の位置は   const EventIDCol = 11 //K列   const eventNum = 11 となっているため、 K列の値をイベントIDとして変数に代入するのでしたら   let eventID = contents[i][eventNum] ではなく   let eventID = contents[i][eventNum - 1] ではないでしょうか。 同様に let CalendarName = contents[i][calnameNum] //設定するカレンダー名 もB列の値になっています。 const calnameNum = 1 //カレンダー名の列 A列にカレンダー名が記載されているのでしたら let CalendarName = contents[i][calnameNum - 1]
10-mo

2021/09/25 09:29

mayu様 ありがとうございます。エラー表示が消えましたが、イメージしている通りにプログラムが動きません。もう少し私もいじって思い通りに動くように修正します! この度はありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問