AIでノーコード事務アプリを自作!無料の作り方を紹介

無料GPT

アプリで打刻!電子タイムカードをAIと作ってみた

最近「キントーン」というシステム商品のCMをよく見ます。クラウド型の業務アプリ作成サービスだそう。ノーコードで簡単に事業に必要なアプリが作れる、今人気のサービス。魅力的ですが、中小や個人店には少し敷居が高い話でもあります。

AI
AI

勤怠管理アプリ風なら
【無料で】Googleで
簡単に作れますよ

ChatGPTやGoogle GeminiなどのAIにたずねると、どれもAIのサポートで「簡単に」作れると教えてくれます。本当でしょうか。やってみました。今回はその手順を紹介する記事です。

筆者の感想
筆者の感想

Geminiとの会話1ラリー
で作れました!

【勤怠管理簡単アプリ】必要なもの
①Google フォーム
②Google スプレッドシート
 ※どちらもGmailを持っていたら使えます

でき上がり状態のイメージは、下記の通りです。
スタッフが操作する画面と、店長さんが操作する画面、それぞれをご紹介します。

Googleフォームの勤怠管理画面です
スタッフさんが操作する画面のイメージ
Googleスプレッドシートです。打刻時間と名前が入力されています
店長さんが操作する画面のイメージ

今回はAIを使って、タイムカード代わりの勤怠管理システムを【簡単&無料で】作る方法をご紹介します。

ちなみに、生成AIのClaude(クロード)を使い、PC内にデータ保存する勤怠管理アプリも生成AIが作ってみております。どちらも会話1ラリーで実現しましたので、良かったら合わせてご検討下さい

「デジタル打刻」の3つのメリット

便利で確実、信頼が今でも根強い「紙のタイムカード」。一方、「デジタル打刻」に移行すると下記のメリットがあります。

メリット1.集計の手間が省ける!

まず、手間の削減。タイムカードの打刻は便利ですが、集計に膨大な手間がかかりますよね。月末になると、集計の入力作業に追われることも…。

デジタル打刻に移行すれば、スタッフも1タップで出退勤を記録できて簡単、まとめる店長は自動でデータが集積されて簡単! お互いの、月末の手間が多いに縮小します。

メリット2.データを蓄積して分析も!

データを残し続けることで、データ活用の道が開けます。蓄積したデータを元に、従業員ごとの出勤傾向や業務の偏りを分析することができ、働き方の改善にも役立ちます。データを蓄積していくことで「経営に活かせるデータ」に進化する可能性があります。

メリット3.Geminiと繋がる可能性

GoogleのAI「Gemini」のサービスはどんどん充実中。スプレッドシートの数字に関して、将来的には「まとめて」「グラフにして」「分析して」など、簡単な依頼ワードで多彩なデータ展開が見込まれます。スプレッドシートにデータを残すことは、メリットに繋がる可能性があります。

そうは言っても「紙のタイムカード」も魅力です。紙のタイムカードをAIとカメラで読み取る記もありますので、もしよろしければぜひ。

AIで簡単!電子タイムカードの作り方

さてここからは具体的な手順をお伝えします。ChatGPTと一緒に作ることも可能ですが、今回はGoogleのサービスを使うため、Geminiに話しかけてみることにしましょう。

チャットGPTに同じ質問をしても、結局実現できますので、お好きな方を使って下さい。

使ったAIプロンプトはこちら

Google Apps Scriptを使って社員の勤怠の打刻をまとめる仕組みを作りたいです。やり方を順に教えてもらえますか。

Google Apps Script(グーグル・アップス・スクリプト)とは、Google スプレッドシート、Google フォーム、Gmail、Google カレンダーなど、Googleの各サービスを自動化・拡張するための仕組みとして使われます。
Googleが提供しているクラウド上で動くプログラミング言語(JavaScriptベース)です。
Gmailを持っている人であれば無料で使えます。

ここから先はAI(今回はGemini)からの指示と、その手順通りに作業した様子をお伝えします。

Gemini
Gemini

それではシステムは以下のようにしましょう

Google Apps Script(GAS)を使って、社員の勤怠打刻を管理する基本的なシステムの作り方を、順を追ってご説明します。

Geminiが提案!システムの全体像

  1. 打刻: 社員はGoogleフォームを使って、「出勤」または「退勤」を打刻します。
  2. データ記録: 打刻データ(タイムスタンプ、氏名、打刻種別など)は、自動的にGoogleスプレッドシートに記録されます。
  3. 勤怠集計: GASがスプレッドシート上の打刻データを読み込み、社員ごと・日付ごとに整理して、別のシートに勤怠一覧表を作成します。
  4. 自動化: スクリプトの実行をトリガー(自動実行機能)に設定することで、毎日の終業後や毎月の締め日などに自動で集計処理を動かせます。

ここから先も、長〜い手順書を作ってくれました。

AIと筆者の会話内容にご興味があれば、以下をクリックしてご覧ください(会話履歴)

手順1.Googleフォームを作ろう

まず「Googleフォーム(https://workspace.google.com/intl/ja/products/forms/ )」を新規作成します。Googleにログインした状態で上記をクリックすると、すぐ下記の作成画面になります。

Googleフォームの画面です

①タイトルを変更「勤怠打刻フォーム」(AIの指示)
②「氏名」と入力(AIの指示)
③質問タイプを選択「記述式」を選ぶ(AIの指示)
④「必須」をオンして入力必須とする(AIの指示)
⑤質問項目を追加ボタンを押す

⑥「打刻種別」と入力(AIの指示)
⑦「ラジオボタン」を選択(AIの指示)
⑧「出勤」と「退勤」の選択肢を作る、必須をオンにする(AIの指示)
⑨「回答」タブをクリックして選択する(AIの指示)

「回答」をクリックすると下記の画面に移ります。「スプレッドシートにリンク」をクリック

「スプレッドシートにリンク」をクリックすると現れる画面が下記です。ファイル名を入力できますので「勤怠管理シート」と入力(これもAIの指示です)、そして「作成」をクリックします。

これでGoogleフォームとスプレッドシートが連携されました!

手順2.スプレッドシートを作ろう!

手順1の最後で「作成」をクリックすると、今度は表計算の画面(スプレッドシート)が開きます。
画面には既にGoogleフォームの設問内容とリンクした項目が入っています。

Gemini
Gemini

回答が記録されるシートと
集計結果のシートを
作りましょう

①はじめのシートを名称変更しましょう、「打刻データ」に。(AIの指示)
②新しいシートを追加しましょう、名前は「勤怠一覧」に。(AIの指示)
 ※シート名称はAIが指示した通りの名前を入力しましょう。後々響きます
③セルに入力して下さい。「A1: 年月、B1: 日付、C1: 氏名、D1: 出勤時刻 、E1: 退勤時刻 、F1: 労働時間」(AIの指示)
 ※AIに「A1に入力しましょう」と言われた時は、きちんとA1セルに入力することが大切です
④拡張機能をクリック(AIの指示)
⑤Apps Scriptをクリック(AIの指示)

さて、いよいよ次では「スクリプトを実行」という、プログラミングに入ります。
プログラミングコードは全てAIが書いてくれています。
私達はコピペするだけでOKと簡単!早速試してみましょう!

手順3.コピペだけ!Google Apps Script

Google Apps Script(GASと、よく呼ばれます)を開いた画面が下記です。文系で育った方達はおそらくここで怯みますが、恐れなくて大丈夫。全部AIが指示してくれた通りにやるだけです。コードの入力はコピペだけです。

①「コード.gs」が選択されていることを確認
②プログラミングコードを入れる画面です。
 今入っているコードを全選択して消去します。そしてAIが作った下記のコードを全文コピペします。

※下記は筆者とAIの対話の中で作られたコードです。下記をそのままコピペしても使えますし、あなたがAIと会話して、あなた用にAIが作ったコードでも、コピペすれば使えるはずです

/**
* 勤怠データを集計し、「勤怠一覧」シートに出力する関数
*/
function summarizeAttendanceData() {
// アクティブなスプレッドシートを取得
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// 「打刻データ」シートを取得
const punchDataSheet = spreadsheet.getSheetByName(PUNCH_DATA_SHEET_NAME);
// 「勤怠一覧」シートを取得
const summarySheet = spreadsheet.getSheetByName(SUMMARY_SHEET_NAME);

// 「打刻データ」シートから全データを取得 (ヘッダー行を除く)
// getLastRow()が0や1の場合を考慮
const lastRowPunch = punchDataSheet.getLastRow();
if (lastRowPunch <= HEADER_ROW_COUNT) {
Logger.log('打刻データがありません。');
summarySheet.getRange(HEADER_ROW_COUNT + 1, 1, summarySheet.getLastRow() > HEADER_ROW_COUNT ? summarySheet.getLastRow() - HEADER_ROW_COUNT : 1, summarySheet.getLastColumn()).clearContent(); // データ部分のみクリア
return;
}
const punchDataValues = punchDataSheet.getRange(HEADER_ROW_COUNT + 1, 1, lastRowPunch - HEADER_ROW_COUNT, punchDataSheet.getLastColumn()).getValues();

// データを整理するための一時オブジェクト
const attendanceRecords = {};

// 打刻データを1行ずつ処理
punchDataValues.forEach(row => {
const timestamp = new Date(row[0]); // A列: タイムスタンプ
const employeeName = String(row[1]).trim(); // B列: 氏名 (前後の空白を除去)
const punchType = String(row[2]).trim(); // C列: 打刻種別 (出勤/退勤)

if (!employeeName || !punchType) return; // 氏名または打刻種別が空の場合はスキップ

const dateKey = Utilities.formatDate(timestamp, 'JST', 'yyyy/MM/dd');
const recordKey = `${employeeName}_${dateKey}`; // 氏名と日付でユニークなキーを作成

// attendanceRecordsオブジェクトに記録がなければ初期化
if (!attendanceRecords[recordKey]) {
attendanceRecords[recordKey] = {
yearMonth: Utilities.formatDate(timestamp, 'JST', 'yyyy/MM'),
date: dateKey,
name: employeeName,
checkIn: null, // 出勤時刻
checkOut: null // 退勤時刻
};
}

// 打刻種別に応じて時刻を記録
if (punchType === '出勤') {
// 既に出勤時刻が記録されている場合は、より早い時刻を採用 (同日再打刻対応)
if (!attendanceRecords[recordKey].checkIn || timestamp < attendanceRecords[recordKey].checkIn) {
attendanceRecords[recordKey].checkIn = timestamp;
}
} else if (punchType === '退勤') {
// 既に退勤時刻が記録されている場合は、より遅い時刻を採用 (同日再打刻対応)
if (!attendanceRecords[recordKey].checkOut || timestamp > attendanceRecords[recordKez].checkOut) { // 修正: recordKey
attendanceRecords[recordKey].checkOut = timestamp;
}
}
});

// 「勤怠一覧」シートに出力するための配列を準備
const summaryOutput = [];
const sortedKeys = Object.keys(attendanceRecords).sort((a, b) => {
// 日付でソートし、次に氏名でソート
const dateA = new Date(attendanceRecords[a].date);
const dateB = new Date(attendanceRecords[b].date);
if (dateA - dateB !== 0) {
return dateA - dateB;
}
return attendanceRecords[a].name.localeCompare(attendanceRecords[b].name, 'ja');
});

sortedKeys.forEach(key => {
const record = attendanceRecords[key];
let workingHours = ''; // 労働時間

// 出勤時刻と退勤時刻が両方記録されていれば労働時間を計算
if (record.checkIn && record.checkOut) {
const diffMillis = record.checkOut.getTime() - record.checkIn.getTime();
if (diffMillis > 0) { // 退勤時刻が出勤時刻より後の場合のみ計算
const hours = diffMillis / (1000 * 60 * 60); // ミリ秒を時間に変換
workingHours = hours.toFixed(2); // 小数点以下2桁にフォーマット
} else {
workingHours = '打刻エラー'; // 退勤が出勤より早いなど
}
}

summaryOutput.push([
record.yearMonth,
record.date,
record.name,
record.checkIn ? Utilities.formatDate(record.checkIn, 'JST', 'HH:mm') : '', // HH:mm形式で出力
record.checkOut ? Utilities.formatDate(record.checkOut, 'JST', 'HH:mm') : '', // HH:mm形式で出力
workingHours
]);
});

// 「勤怠一覧」シートの既存データをクリア (ヘッダー行を除く)
const lastSummaryRow = summarySheet.getLastRow();
if (lastSummaryRow > HEADER_ROW_COUNT) {
summarySheet.getRange(HEADER_ROW_COUNT + 1, 1, lastSummaryRow - HEADER_ROW_COUNT, summarySheet.getLastColumn()).clearContent();
}

// 新しい集計結果を書き出し (データがある場合のみ)
if (summaryOutput.length > 0) {
summarySheet.getRange(HEADER_ROW_COUNT + 1, 1, summaryOutput.length, summaryOutput[0].length).setValues(summaryOutput);
}

Logger.log('勤怠データの集計が完了しました。');
}

/**
* スプレッドシートを開いた時や、手動でメニューから実行するためのカスタムメニューを追加します。
*/
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('勤怠管理')
.addItem('勤怠データを集計', 'summarizeAttendanceData')
.addToUi();
}

③プロジェクト名を付けます「勤怠集計スクリプト」(AIの指示)
最後に保存します。他の書類と同様に「Ctrl+S」です。

手順4.スクリプトの承認

プログラミングが動くためには「承認」が必要なようです(初回のみ)。理由は「スプレッドシート」にプログラムが勝手にアクセスして書き込むから。承認の手順をお伝えします。下記はGASの画面です。

画面の上部に「summarizeAttendanceData」と書いた「▼」ボタンがあります。そこをクリックして「summarizeAttendanceData」を選択します。

すると下図のように「承認が必要です」という画面が出現します。「権限を承認」の方をクリックして下さい。

今度は「どのアカウントが権限を承認するか」を聞いてきます(下図です)。複数のアカウントが表示される場合もあります。個人用Gmailと、仕事用Gmailなど使い分けている方は、仕事用のGmailを選んで下さい。

すると「このアプリはGoogleで確認されていません」という画面が現れます(下図)」。安全なページに戻る、の方を押すと承認がキャンセルされます。
今は承認を続行したいので、画面左下にある「詳細」をクリックして下さい。

詳細を押すと下図の画面になります。一番下段に「移動」という選択肢が現れるので、それをクリックして下さい。赤枠で囲った部分のことです。

次の画面で「アクセス権を付与」という画面が現れますので、「続行」を選択して押して下さい。
これで、プログラムがスプレッドシートに書き込むことが承認されました!

これで出来上がりです!AIからの指示と、AIが出したコードのコピペだけで完了できました!

Q.ここまで全部Geminiが作って→ 今はまだ

Geminiがアプリ完成まで
全部作ってよ

Gemini
Gemini

私が直接作ることは
できないのです。
手順をご案内できます

2025年6月現在、GeminiはまだGoogleフォームなどを作ってはくれません。
しかし近々きっと、できるようになると(筆者は勝手に)思っています。

試運転してみましょう

さて、出勤と退勤時間をデジタルで打刻するアプリ風のものができました!
Googleフォームをもう一度開きます。

スタッフがGoogleフォームで出退勤を打刻するためには、Googleフォームの「公開」が必要です。以下はその手順になります。

まずはGoogleフォーム画面(下図)画面の右上にある「公開」ボタンを押します。

「誰に公開するか」を聞いてきます(下図)。リンクを知っている全員で良いと思います。「公開」をクリックします。

画面がはじめに戻ります(下図)右上に「リンクをコピー(赤で囲った箇所)がありますので、クリックしてください。URLが表示されます。

表示されたURLをスタッフに送信します。
あとはスタッフそれぞれがURLにアクセスして出勤と退勤を送信します。

するとスプレッドシートに自動入力されていきます!

スプレッドシートにアクセスできる人であれば、データ(時間や氏名)の修正もできます。打刻間違いにも対応できます。

もっと機能充実もAIに相談すれば実現可能!

以上が今回の「打刻アプリ」の作り方です。
とってもシンプルですが、今後どんどん機能を付け足すことができます。AIに聞いてみましょう。

このアプリをもっと機能充実させるために、どんな機能を付け足すことが可能ですか?

まず取り組みやすいおすすめ拡張はこちらです

  • 🧑‍💻 「社員名一覧」をスプレッドシートから読み込んで動的にプルダウン生成
  • 🔁 同じ日での「出勤2回」などの重複を自動チェック&無効化
  • 📩 出退勤ごとにGoogleチャット or Gmail通知を送る
  • 🎶 打刻時に「ピンポン」と音を鳴らす
  • 🙎‍♀️ スタッフの顔写真を表示する

AIと話し合いながら、どんどん機能を充実させられます。

またインターフェースをアプリっぽく変更もできます。

アプリ画面のような出退勤入力画面です。出勤と退勤がボタンになっているシンプルな画面です

今回の記事のポイントは、主に以下の3点です(まとめ):

  • 💡 ノーコードで作れる:フォームもスプレッドシートも、画面操作だけで作成可能
  • ⏱ 業務効率UP:出退勤の集計が自動化され、月末作業がラクに
  • 📊 データ活用の可能性:勤怠データを分析すれば、働き方の改善にもつながる

これからは「業務アプリを自分で作る時代」なのかもしれませんし、工夫次第で維持費を低く抑えて導入が可能です。AIがそのお手伝いをします。

気になる方は、ぜひ一度試してみてください。
最初の一歩は、Googleフォームを1つ作るだけです!

コメント

タイトルとURLをコピーしました