2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【GAS】スプレッドシートにカレンダーを生成したい

Posted at

日付コピーしてカレンダーつくんのめんどくさい

これを
こうして.PNG
こうして
日付を.PNG
こうすんのが
いちいちコピーしてつくるのは.PNG

面倒くさい。

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。

曜日ごとの色処理について

曜日ごとに色付けする処理も考えたんですが、その日が祝日か判定して色を付けたりする処理を考えたときに一回一回セルにアクセスする必要が出そうだなぁと思ったので、いったん保留にしました。
(セルへのアクセス回数が増えると処理も遅く重くなるので……)
あ、でも祝日マスタ作って条件付き書式とかで処理できるようにしたらいけるか……?

後日ちょっと追加で考えてみます。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?