🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Google Apps Script

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

Q&A

1回答

885閲覧

シートで作成されたカレンダーで指定曜日のイベントを取得したいです。

koroaisu

総合スコア8

Google Apps Script

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

0グッド

1クリップ

投稿2019/10/26 12:01

編集2019/10/28 09:23

前提・実現したいこと

Googleシートで作成されたカレンダーで指定の曜日のイベント及び日付などのデータを取得し、別シートにリストアップするコードを作成しました。

■希望の機能:指定した曜日にあるすべてのイベント名及び当日の日付を取得して、「test」シートの1列目に日付、2列目からすべてのイベント名を記入。
イメージ説明

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

イベント名の取得まではうまくいきましたが、イベント名を記入する際に、最初のイベントのみ記入され、すべてのイベント名は記入されません。

カレンダー詳細

イメージ説明

該当のソースコード

GAS

1var SS = SpreadsheetApp.openById("リンク先");//スプレッドシートを取得 2var TargetSheet = SS.getSheetByName("event");//カレンダー 3var ReturnSheet = SS.getSheetByName("test");//データ記入シート 4var dateRow=2; //日付の列 5var yobiRow=3; //曜日の列 6var TagetSheet_lastCol = TargetSheet.getLastColumn(); 7var TagetSheet_lastRow = TargetSheet.getLastRow(); 8var ReturnSheet_lastCol = TargetSheet.getLastColumn(); 9var ReturnSheet_lastRow = TargetSheet.getLastRow(); 10 11function getEventValue() { 12 var datelist=[]; //日付を格納する配列 13 var eventlist=[]; //イベント名を格納する配列 14 15 for(var i=0;i<TagetSheet_lastCol;i++){ 16 var yobiValue=TargetSheet.getRange(yobiRow,i+1).getValue(); 17 if(yobiValue=="木"){  //木曜日を指定 18 var dateValue=TargetSheet.getRange(dateRow,i+1).getValue(); 19 var EventDataValue=TargetSheet.getRange(6,i+1,TagetSheet_lastRow,1).getValues(); 20 var SaveDataList=[]; 21 for(var y=0;y<EventDataValue.length;y++){ 22 if(EventDataValue[y]!=""){ //イベント種類によっては列が空白になるので、空白のモノをスキップ 23 SaveDataList.push(EventDataValue[y]); //SaveDataListに一旦、当日のイベント名をすべて格納 24 } 25 26 } 27 eventlist.push(SaveDataList); //SaveDataListがリセットされるため、イベント名をこちらに渡す 28 datelist.push(dateValue) 29 } 30 } 31 for(var x=0;x<eventlist.length;x++){ 32 ReturnSheet.getRange(1,x+1).setValue(datelist[x]); 33 ReturnSheet.getRange(2,x+1).setValue(eventlist[x]); 34 } 35 }

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

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

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

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

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

papinianus

2019/10/26 13:57

行列の表現が、回答者が理解するものと合致しているか不安しかない(コードでは行方向にに変動する要素がない)ので、本当におこり得るレベルのサンプルデータを示してください。これは列方向に正規化されているかも不安だからです。説明文が足りなさすぎます。エラーがあって直すべきコードは状況の理解の参考になりません。
koroaisu

2019/10/28 02:35

この度は説明に不足があり、誤解を招いて、無駄な時間を掛せてしまい、申し訳ございません。 説明の方にカレンダーの参考画像および希望機能の画像を追加致しました。 また、忙しい中、情報不足を指摘くださって、誠にありがとうございます。
guest

回答1

0

コード未検証。おそらくこういうことだと思う

javascript

1function q219502() { 2 const spreadSheet = SpreadsheetApp.getActive(); 3 const eventSheet = spreadSheet.getSheetByName('event'); 4 const startOfDataRow = 2; //10/24 が C2 と仮定 5 const startOfDataCol = 3; //10/24 が C2 と仮定 6 const endRow = eventSheet.getLastRow(); 7 const endCol = eventSheet.getLastColumn(); 8 // 結合セルからデータをひろってくる 9 const allData = q180220_getMargedRangeValues(sheet, startOfDataRow, startOfDataCol, endRow, endCol); 10 // 曜日でフィルタ 11 const theDay = "木"; 12 const indexOfTheDays = allData[1].reduce(function(a, c ,i) { return c === theDay ? a.concat([i]) : a;},[]); 13 // // 曜日行を消す 14 allData.splice(1,1); 15 // // 曜日を行方向にして、空白をスキップしたデータに作り直す(求める姿とは行と列が逆転している。 16 const summed = indexOfTheDays.map(function(p){ return allData.reduce(function(a,c,i){ return i === p && c !== "" ? a.concat([c]) : a ;},[]);}); 17 const maxSize = summed.reduce(function(a,c){ return c.length > a ? c : a ;}, 0); 18 // // 行の長さを揃える 19 const fixed = summed.map(function(r){ return fillingArray(r, maxSize, "");} ); 20 // 行列転置 21 const transposed = fixed[0].map(function(_, c) { return fixed.map(function(r) { return r[c];});}); 22 spreadSheet.getSheetByName('test').getRange(1,1,transposed.length, transposed[0].length).setValues(transposed); 23} 24 25// getRangeと同じように 1-indexed で指定する 26function q180220_getMargedRangeValues(sheet, startRow, startCol, endRow, endCol) { 27 const targetRange = sheet.getRange(startRow, startCol, endRow, endCol); 28 var ret = targetRange.getValues(); 29 targetRange.getMergedRanges().forEach(function(rng) { 30 var startR = rng.getRow(); 31 var startC = rng.getColumn(); 32 var rngVal = rng.getValue(); 33 var rngA1 = rng.getA1Notation(); 34 var rowBoundary = startR + rng.getNumRows(); 35 var colBoundary = startC + rng.getNumColumns(); 36 for(var ri = startR; ri < rowBoundary ; ri++) { 37 var ri_a = ri - startRow; 38 if(ri_a < 0) { continue; } 39 if(ret.length <= ri_a) { break; } 40 for(var ci = startC; colBoundary; ci++) { 41 var ci_a = ci - startCol; 42 if(ci_a < 0) { continue; } 43 if(ret[ri_a].length <= ci_a) { break; } 44 ret[ri_a][ci_a] = rngVal; 45 } 46 } 47 }); 48 return ret; 49} 50 51function fillingArray(array, len, fill) { 52 var pseudo = []; 53 for(var i = 0; i < len; i++) { 54 pseudo.push(fill); 55 } 56 return array.concat(pseudo).slice(0, len); 57}

将来参考に訪れたかたへ

あなたのデータを見直してください。

列方向に組まれたデータはハンドリングが大変です。
データベースもGoogle Sheet(を加工するGoogle App Script)も行方向に1データです。

表示に最適化されすぎたデータはプログラム処理に向きません。
データモデルと表示は分離して、結合列や背景色でデータを表現しないようにしましょう。プレゼンするときにだけ、整形しましょう。またプレゼンのために新たに作らなくても、google sheetやexcelでは他のシートを参照する機能があるので、データシートと連動する表示シートを作るのはさほど難しくないはずです。

投稿2019/10/26 14:20

編集2019/10/30 07:09
papinianus

総合スコア12705

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

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

papinianus

2019/10/30 07:09

このデータ構造は加工がつらい。これは業務委託するレベル
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問