概要
GoogleSpreadSheetにおいて
GoogleAppsScriptを用いて実装した疑似ストップウォッチを紹介
###できること
カウントの同期
途中経過時間の記録
###できないこと
カウント表示のリアルタイム自動更新
ストップウォッチの一時停止(未対応)
##こんな人のために
複数人でストップウォッチを共有したい方
- グループで行うプレゼン
- 音響等の裏方がいる規模のイベント
ストップウォッチの表示は同期されるので、スタッフ一人が操作すれば発表者・司会者はしゃべりに集中できる
####スプレッドシートとストップウォッチの機能を一つの画面で済ませたい方
- イベント司会者
- プレゼンテーター
スプレッドシートに原稿を書けばタブレットの一画面で完結でき、コンパクト
##サンプル
以下のリンクからスプレッドシートを開き、コピーを作成してすぐに利用することができます
##実装
細かい調整をしたい方のために、各ボタンに対応するスクリプトを記載しておきます
###セッティング
const SHEET_ID = /*導入したいスプレッドシートのID*/;
const DISPLAY_SHEET = /*ストップウォッチを表示したいシート名*/;
const RECORD_SHEET = /*結果を保存したいシート名*/;
//ストップウォッチの開始時刻を保存するセル、ストップウォッチを表示するセル
const TIMER_NOTATION = {
"total":{"start": "I1", "display":"A2"},
"partial":{"start": "I2", "display":"B2"}
};
// ラベル用セルの開始セル
const LABEL_NOTATION = {
"start": "A3"
};
###「開始」ボタン
// DBの開始時間を更新して画面更新
function timerStart() {
const now = Date.now();
const ss = SpreadsheetApp.openById(SHEET_ID);
var sheet = ss.getSheetByName(DISPLAY_SHEET);
sheet.getRange(TIMER_NOTATION.total.start).setValue(now);
sheet.getRange(TIMER_NOTATION.partial.start).setValue(now);
refreshCountView(sheet, now);
sheet = ss.getSheetByName(RECORD_SHEET);
sheet.appendRow([now]);
}
// DBの情報から合計時間と部分時間の表示を更新
function refreshCountView(sheet, now){
if(sheet.getSheetName()!=DISPLAY_SHEET){
Logger.log("Invarid Sheet");
return
}
for(const timer in TIMER_NOTATION){
const start = sheet.getRange(TIMER_NOTATION[timer].start).getValue();
const record = getRecord(start, now);
sheet.getRange(TIMER_NOTATION[timer].display).setValue(record);
}
}
// 経過時間を計算
function getRecord(start, end){
var time = end - start;
var second = Math.floor(time%(60*1000)/1000);
if(second < 10) second = "0" + second;
return Math.floor(time/(60*1000)) + ":" + second;
}
###「画面更新」ボタン
// 画面更新のみ
function timerReflesh() {
const now = Date.now();
const sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName(DISPLAY_SHEET);
refreshCountView(sheet, now);
}
###「次へ」ボタン
// 実行時刻をDBに反映してから画面更新、記録
function timerRecord() {
const now = Date.now();
const ss = SpreadsheetApp.openById(SHEET_ID);
var sheet = ss.getSheetByName(DISPLAY_SHEET);
sheet.getRange(TIMER_NOTATION.partial.start).setValue(now);
refreshCountView(sheet, now);
const record = sheet.getRange(TIMER_NOTATION.total.display).getValue();
sheet = ss.getSheetByName(RECORD_SHEET);
const row = sheet.getLastRow();
const column = sheet.getRange(row,sheet.getMaxColumns()).getNextDataCell(SpreadsheetApp.Direction.PREVIOUS).getColumn()+1;
sheet.getRange(row,column).setValue(record);
}
###「ラベルを更新」ボタン
// DISPLAY_SHEETからラベルと想定時間を受け取ってRECORD_SHEETの表示更新
function timerSet() {
const ss = SpreadsheetApp.openById(SHEET_ID);
var sheet = ss.getSheetByName(DISPLAY_SHEET);
var range = sheet.getRange(LABEL_NOTATION.start);
var label = sheet.getRange(range.getRow(),range.getColumn()+2);
var labels = ["開始",label.getValue()];
var labelsBackground = [, label.getBackground()];
var times = ["0:00"];
range = range.getNextDataCell(SpreadsheetApp.Direction.DOWN);
while(range.getRow()<1000){
var labelRange = sheet.getRange(range.getRow(),range.getColumn()+2);
labels.push(labelRange.getValue());
labelsBackground.push(labelRange.getBackground());
times.push(formatTime(range.getValue()));
range = range.getNextDataCell(SpreadsheetApp.Direction.DOWN);
}
sheet = ss.getSheetByName(RECORD_SHEET);
for(var i=0;i<labels.length;i++){
sheet.getRange(1,i+1).setValue(labels[i]);
sheet.getRange(1,i+1).setBackground(labelsBackground[i]);
sheet.getRange(2,i+1).setValue(times[i]);
}
}
// spreadsheetの時間型の値を分数:秒数表示に変える
function formatTime(date) {
return Utilities.formatDate(date, "Asia/Tokyo", "HH:mm");
}
##筆者情報
プログラミング学習開始から6カ月
GASでの自作は今回のストップウォッチが初めて
##参考にさせていただいた記事
その他、GASにおけるspreadsheetの基本的な扱い方についての諸記事