計算式プラグインを使って、テーブルに月カレンダーを表示してみました。
概要
横並びプラグイン確認用に、カレンダーと画像を並べた例です。
テーブルのカレンダーを、計算式プラグインで計算しています。
計算式は、最初に日~土の項目毎に計算する仕組みでしたが、
テーブルにまとめてデータをセットする方法に変更して、パフォーマンス改善を行いました。
覚書として両方の計算式を載せておきます。
アプリの設定
計算式プラグイン設定
最初は、日~土の項目毎に日にち計算で、設定しました。
ただ日数分の計算が行われるので、テーブルにまとめて値をセットする方式に変更しました。
改善前:テーブル内項目に計算式を設定
月の日数以上に、計算が必要
- テーブルに、必要な行数を設定
- 日~土の項目毎に日にち計算
改善前.js
OPTION: 循環参照を許可
// タイトル SINGLE_LINE_TEXT
DATE_FORMAT(開始日,"YYYY年M月")
// 開始日 DATE (editable)
DATE_STARTOF(開始日,"month")
// カレンダー:テーブル1 SUBTABLE
LET(
sDate, DATE_STARTOF(開始日, "month"),
eDate, DATE_ENDOF(sDate, "month"),
fDow, DATE_FORMAT(sDate, "e"),
tDays, DATE_DIFF(sDate, eDate, "day") +fDow + 1,
CEIL(tDays / 7)
)
// テーブル1.日:日1 NUMBER
LET(
fDow,DATE_FORMAT(開始日, "e"),
eMonth,DATE_ENDOF(開始日,"month","D"),
rno,ROWNO(テーブル1),
day,1+rno*7-fDow,
IF(day>0&&day<=eMonth,day)
)
// テーブル1.月:月1 NUMBER
LET(
fDow,DATE_FORMAT(開始日, "e"),
eMonth,DATE_ENDOF(開始日,"month","D"),
rno,ROWNO(テーブル1),
day,2+rno*7-fDow,
IF(day>0&&day<=eMonth,day)
)
// テーブル1.火:火1 NUMBER
LET(
fDow,DATE_FORMAT(開始日, "e"),
eMonth,DATE_ENDOF(開始日,"month","D"),
rno,ROWNO(テーブル1),
day,3+rno*7-fDow,
IF(day>0&&day<=eMonth,day)
)
// テーブル1.水:水1 NUMBER
LET(
fDow,DATE_FORMAT(開始日, "e"),
eMonth,DATE_ENDOF(開始日,"month","D"),
rno,ROWNO(テーブル1),
day,4+rno*7-fDow,
IF(day>0&&day<=eMonth,day)
)
// テーブル1.木:木1 NUMBER
LET(
fDow,DATE_FORMAT(開始日, "e"),
eMonth,DATE_ENDOF(開始日,"month","D"),
rno,ROWNO(テーブル1),
day,5+rno*7-fDow,
IF(day>0&&day<=eMonth,day)
)
// テーブル1.金:金1 NUMBER
LET(
fDow,DATE_FORMAT(開始日, "e"),
eMonth,DATE_ENDOF(開始日,"month","D"),
rno,ROWNO(テーブル1),
day,6+rno*7-fDow,
IF(day>0&&day<=eMonth,day)
)
// テーブル1.土:土1 NUMBER
LET(
fDow,DATE_FORMAT(開始日, "e"),
eMonth,DATE_ENDOF(開始日,"month","D"),
rno,ROWNO(テーブル1),
day,7+rno*7-fDow,
IF(day>0&&day<=eMonth,day)
)
改善後1:テーブルデータをまとめてセット
月カレンダーの csv データを作成して、テーブルにまとめてセット
- テーブル行単位に、日にちを組み立てていく感じ
- 配列から CSV に変換して、テーブルにセット
改善後1.js
OPTION: 循環参照を許可
// タイトル SINGLE_LINE_TEXT
DATE_FORMAT(開始日,"YYYY年M月")
// 開始日 DATE (editable)
DATE_STARTOF(開始日,"month")
// カレンダー:テーブル1 SUBTABLE
LET(
sDate, DATE_STARTOF(開始日, "month"),
eDate, DATE_ENDOF(sDate, "month"),
mDays, DATE_ENDOF(sDate, "month","D"),
fDow, DATE_FORMAT(sDate, "e"),
tDays, DATE_DIFF(sDate, eDate, "day") +fDow + 1,
line, CEIL(tDays / 7),
csv, JOIN(ARRAY_FOR(line,x,
JOIN(ARRAY_FOR(7,y,
LET(
day,y+x*7-fDow+1,
IF(day>0&&day<=mDays,day)
)
),",")
),NEWLINE()),
CSV_TVAL("日1,月1,火1,水1,木1,金1,土1"&NEWLINE()&csv)
)
// テーブル1.日:日1 NUMBER
// テーブル1.月:月1 NUMBER
// テーブル1.火:火1 NUMBER
// テーブル1.水:水1 NUMBER
// テーブル1.木:木1 NUMBER
// テーブル1.金:金1 NUMBER
// テーブル1.土:土1 NUMBER
改善後2:ループ処理を削減
単純に csv を組み立てるだけということで、2重のループ処理を減らしてみました。
ステップが短い分、わかりやすいかも。
- 月の初めの曜日までの空文字の配列、月の日数分の日にちの配列をまとめて
- 配列を 7個単位に改行、それ以外はカンマで配列を連結
- csv をCSV_TVAL 関数でテーブルにセット
改善後2.js
// カレンダー:テーブル1 SUBTABLE
LET(
sDate, DATE_STARTOF(開始日, "month"), // 月初日
days, DATE_ENDOF(sDate, "month", "D"), // 月の日数
fDay, DATE_FORMAT(sDate, "e"), // 初曜
arr, ARRAY(ARRAY_FOR(fDay, x, ""), ARRAY_FOR(days, x, x+1)), // 配列作成
csv, JOIN(ARRAY_MAP(arr, x, idx, x & IF((idx+1)%7=0, NEWLINE(), ",")),""), // CSV変換
CSV_TVAL("日1,月1,火1,水1,木1,金1,土1"&NEWLINE()&csv) // テーブル設定
)