※ GAC 記事一覧
以下の調整を行う。
- カレンダーの終了時刻を開始時刻と同じ値にする
- カード種別と金額の間に":"を付加する
Code.gs
// ==========================================
// 設定項目
// ==========================================
const CALENDAR_NAME_UNPROCESSED = '未処理';
const CALENDAR_NAME_PROCESSED = '処理済';
const STATUS_UNPROCESSED = '未処理';
const STATUS_PROCESSED = '処理済';
const GOOGLE_MAPS_API_KEY = 'YOUR_GOOGLE_MAPS_API_KEY'; // ご自身のAPIキー
function doGet() {
const template = HtmlService.createTemplateFromFile('index');
template.apiKey = GOOGLE_MAPS_API_KEY;
return template.evaluate()
.setTitle('カード明細管理')
.addMetaTag('viewport', 'width=device-width, initial-scale=1');
}
function getCalendarByName(name) {
const calendars = CalendarApp.getCalendarsByName(name);
if (calendars.length === 0) {
throw new Error(`カレンダー「${name}」が見つかりませんでした。`);
}
return calendars[0];
}
/**
* 指定日の「未処理」イベント一覧を取得する関数
*/
function getUnprocessedEventsByDate(dateStr) {
const calUnprocessed = getCalendarByName(CALENDAR_NAME_UNPROCESSED);
const targetDate = new Date(dateStr);
const startOfDay = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate(), 0, 0, 0);
const endOfDay = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate(), 23, 59, 59);
const events = calUnprocessed.getEvents(startOfDay, endOfDay);
return events.map(event => {
return {
id: event.getId(),
title: event.getTitle(),
location: event.getLocation(),
description: event.getDescription(),
time: Utilities.formatDate(event.getStartTime(), Session.getScriptTimeZone(), "HH:mm")
};
});
}
/**
* イベントIDを指定して「未処理」から「処理済」へ移動する関数
*/
function processEventById(eventId, paymentDate) {
const calUnprocessed = getCalendarByName(CALENDAR_NAME_UNPROCESSED);
const calProcessed = getCalendarByName(CALENDAR_NAME_PROCESSED);
const event = calUnprocessed.getEventById(eventId);
if (!event) {
throw new Error("対象の未処理イベントが見つかりませんでした。");
}
const title = event.getTitle();
const startTime = event.getStartTime();
const endTime = new Date(startTime.getTime()); // 開始時刻と同じ値に設定
const loc = event.getLocation();
let desc = event.getDescription();
// ステータス更新 & 支払い日の追記
desc = desc.replace(`【ステータス】: ${STATUS_UNPROCESSED}`, `【ステータス】: ${STATUS_PROCESSED}`);
if (paymentDate) {
desc += `\n【カード支払い日】: ${paymentDate}`;
}
// 処理済カレンダーに新規作成
const newProcessedEvent = calProcessed.createEvent(title, startTime, endTime, {
location: loc,
description: desc
});
// 未処理側を削除
event.deleteEvent();
return { success: true, title: title };
}
/**
* 店舗の使用頻度履歴を更新
*/
function updateStoreHistory(cardCode, storeName) {
if (!cardCode || !storeName) return;
const userProps = PropertiesService.getUserProperties();
const key = `HISTORY_${cardCode.toUpperCase()}`;
let history = JSON.parse(userProps.getProperty(key) || '{}');
history[storeName] = (history[storeName] || 0) + 1;
userProps.setProperty(key, JSON.stringify(history));
}
/**
* カード種別ごとの店舗利用履歴を取得
*/
function getStoreHistoryByCard(cardCode) {
if (!cardCode) return [];
const userProps = PropertiesService.getUserProperties();
const key = `HISTORY_${cardCode.toUpperCase()}`;
const history = JSON.parse(userProps.getProperty(key) || '{}');
const sortedStores = Object.keys(history).sort((a, b) => history[b] - history[a]);
return sortedStores.slice(0, 5);
}
/**
* フォームからの登録処理
*/
function submitCardUsage(formData) {
const isProcessed = formData.mode === 'processed';
const targetCalName = isProcessed ? CALENDAR_NAME_PROCESSED : CALENDAR_NAME_UNPROCESSED;
const statusStr = isProcessed ? STATUS_PROCESSED : STATUS_UNPROCESSED;
const cal = getCalendarByName(targetCalName);
const cardCode = formData.cardCode.toUpperCase();
const amount = formData.amount;
const dateStr = formData.date;
const timeStr = formData.time || '00:00';
const location = formData.location || '';
const note = formData.note || '';
const paymentDate = formData.paymentDate || '';
const title = `${cardCode}:${amount}`;
const startTime = new Date(`${dateStr}T${timeStr}:00`);
const endTime = new Date(startTime.getTime()); // 開始時刻と同じ値に設定
let description = `【ステータス】: ${statusStr}\n【メモ】: ${note}`;
if (isProcessed && paymentDate) {
description += `\n【カード支払い日】: ${paymentDate}`;
}
const event = cal.createEvent(title, startTime, endTime, {
location: location,
description: description
});
if (location) {
updateStoreHistory(cardCode, location);
}
return {
success: true,
title: title,
date: dateStr,
time: timeStr,
mode: formData.mode
};
}
完成イメージ
かなりいい感じになった。
まずはこれで完成とする。
実際に運用を開始したが、いままでカレンダー画面でチマチマ入力したのに比べ、かなり作業効率が良くなった。
未処理登録画面
処理済登録画面
公開:2026.10.07(水) 05:40


0 件のコメント:
コメントを投稿