日付コピーしてカレンダーつくんのめんどくさい
面倒くさい。
1ヵ月分とかでも面倒なのに、これが1年分とかってなってくるとカーソルドラッグしながら「何に時間かけてるんだろう自分」って気持ちになってきませんか。
Dateをぐるぐる回してカレンダー配列からスプレッドシートにドバっと吐き出したい
Dateを開始日から終了日までぐるぐる回して、二次元配列で格納していけばええんとちゃう
こういう二次元配列
[[null, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6][3/7, 3/8, 3/9, 3/10, 3/11, 3/12, 3/13]...]
今回は日曜始まりのカレンダーをぐるぐる回して生成します。
実装コードは下記の通り。
カレンダー生成.gs
/**
* 定数系
*/
//カレンダー生成の開始日付用(スプレッドシートのセルから取得するように変えるといい)
var targetYear = 2021;
var targetMonth = 1;
var targetDate = 1;
// 今回、1週ごとに下に空白行をいれたいので、何行空行を生成するかの変数
var brCount = 2;
// Dateオブジェクト生成 new Data(年、月、日、時間、分、秒);
// 月に関してはインデックスが0スタートなので、-1しています
var countUpDate = new Date(targetYear, targetMonth - 1, targetDate, 0, 0, 0); //開始日付からの加算用
var endDate = new Date(targetYear, targetMonth - 1, targetDate, 0, 0, 0); //終了日付
// 今回は1年分出力しようと思うので、終了日付のYearを+1します。
endDate.setFullYear(endDate.getFullYear() + 1);
var monChkCd = countUpDate.getMonth(); // 月変わり判定用の変数
var w = 0; // 1行あたり列数カウント用
// 開始列を設定したいので開始日の曜日を取得
//(月曜スタートの場合は開始日付の列-1からスタートするといいです)
w = countUpDate.getDay();
var r = 0; // 行数カウント用
var calArr = []; // カレンダー配列
calArr[r] = []; // 1行分の配列を初期化
/**
* メイン処理
*/
while(countUpDate.getTime() < endDate.getTime()) {
// カレンダー配列に日付を格納
calArr[r][w] = Utilities.formatDate(countUpDate, 'JST', 'yyyy/MM/dd');
countUpDate.setDate(countUpDate.getDate() + 1); // 日付加算
w++; // 列数加算
if(w > 6) {
// 1週間分セットしたら改行
w = 0; // 列数を初期化
r++; // 行数を加算
calArr[r] = []; // 次の行を格納するために配列初期化
for (var j = 1; j <= brCount; j++) {
//空行追加処理
calArr[r] = [null,null,null,null,null,null,null]; // 空行埋める用
r++;
calArr[r] = [];
}
}
if (countUpDate.getMonth() > monChkCd || (countUpDate.getMonth() === 0 && monChkCd === 11)) {
// 月が変わった OR 年を越したら改行
monChkCd = countUpDate.getMonth();
if (w != 0) {
// 行内が詰まっていない場合は残り列を詰める処理
for (var j = w; j <= 6; j++) {
calArr[r][j] = null; // null埋め
}
} else {
calArr[r] = [null,null,null,null,null,null,null];
}
r++;
calArr[r] = [];
}
}
//終了日付まで処理したら処理を終了し、残り列のnull埋め処理
for (var j = w; j <= 6; j++) {
calArr[r][j] = null; // null埋め
}
もうちょっとサクッとやる方法もあるかも…? と思いながらまずは愚直にぐるぐる回してみました。
あとは
SpreadsheetApp.getActiveSheet().getRange(2, 1, r + 1, 7)
.setValues(calArr)
.setHorizontalAlignment('center') //中央揃え
.setVerticalAlignment('middle')
.setNumberFormat('MM/dd');
って感じで配列をシートに出力してあげればOK。
曜日ごとの色処理について
曜日ごとに色付けする処理も考えたんですが、その日が祝日か判定して色を付けたりする処理を考えたときに一回一回セルにアクセスする必要が出そうだなぁと思ったので、いったん保留にしました。
(セルへのアクセス回数が増えると処理も遅く重くなるので……)
あ、でも祝日マスタ作って条件付き書式とかで処理できるようにしたらいけるか……?
後日ちょっと追加で考えてみます。