
はじめまして、インテグレーションサービス本部の菅谷です。
二回目です、インテグレーションサービス本部の肥沼です。
今回は、実績管理のお悩みをブログネタにしてみました。
また、エンジニアブログ初の座談会?形式でお送りします!
1.実績管理の悩み
~~とある一日~~
菅谷(以下:S)肥沼(以下:K)
K「もう火曜日だ…?」
S「とても暗い顔をしているね」
K「毎日の業務の原価管理システムへの入力がつらくて…。
特に一週間分の実績をFIXさせないといけない火曜日がつらいです。
さらに問合せや案件ごとの実績も別で管理しているのですが、
これは日次の実績管理と方法が異なるため大変でして…」
S「確かに大変だよね…」
K「(ここだけの話なのですが)つい実績入力ためちゃうんです…」
S「私はきちんと日次で入力しているけど、ためると大変だよね…。
日報でも実績を報告しているし、実績を一つにまとめられるといいのだけど…」
K「!」
S「何か思いついたの?」
K「日報をスプレッドシート化して、実績インプットを一つにするツールを
作ってみるのはどうでしょうか? GoogleAppsScript(GAS)で実装できそうな気がします!」
S「ナイスアイデアだね!要件や設計を一緒に考えるから作ってみよう!」
K「がんばります!!」
~~ とある一日 (完) ~~
2.ツール開発要件
ということで…前回記事同様GAS で頑張っていきましょう。
まずは、現状実績入力をしているものを洗い出してみました。
実績入力対象 | 入力形式 | 入力内容 | 何のために入力しているか |
---|---|---|---|
日報 | 用紙、スプレッドシートなど | 1日の業務タスクとタスクごとの実績、コメント | マネージャーが一日の業務の確認をするため |
原価管理システム | WEB入力 | 1日の業務をPJ-CDごとに登録する | プロジェクトごとの原価金額を把握するため |
問合せ/案件実績管理表 | スプレッドシート | 問合せ、保守案件ごとに実績時間を登録する | 問い合わせやトラブル対応など、1案件ごと実績時間の集約のため |
これらを原則毎日入力しなければいけないのですが、多過ぎますね。
プロジェクトに入るとプロジェクトの実績管理も追加になります…つらい。
だからサボりたくなってしまうのです…
ではこの状態から、「日報」の実績値をインプットの情報として、
他の入力作業をなくすツールを開発したいと思います。
以下に要件と今回の開発スコープをまとめました。
◎原価管理システム用開発要件
- スプレッドシートで日報のフォーマットを作成
- 1.のフォーマット上からCSV形式に変換 (日付指定可能)
- CSVファイルを出力させる
◎問合せ/案件実績管理表の実績更新用開発要件
- 加工用の第一次アウトプット作成
- 第一次アウトプットをもとに実績表を更新 ※開発途中
それでは、開発に移っていきましょう!
3.開発してみた!
要件に沿って開発者の思いを込めつつ、開発内容をまとめました。
◎原価管理システム用開発要件
- スプレッドシートで日報のフォーマット作成
日報のフォーマットはもともと本部で使っていたものをカスタムして作りました。
少し見た目は格好悪いのですが、
JOB名のプルダウンを選択すると、原価管理システムに取り込むPJ-CDが出てきます。
こちらは、エクセル便利関数VLOOKUPを使用をしました。
という感じで、時折エクセル関数も使いながらフォーマットを作り込みます。
補足ですが、PJ-CDは、「ERPマスタ」という別のスプレッドシートで管理していて、個人のシートでは基本的には更新できないようにしています。
うっかりPJ-CDを変更しちゃった!なんてことがないので、安心ですね!
因みにこのサンプルの日報シートは日次(土日祝日以外)で、8:50に自動生成(サンプルシートから毎日コピペで新シート作成)されるようにしました。
以下の日報作成関数(dailyTask)のトリガー設定用関数を書き、
トリガー設定用関数自体は毎日7~8時に手動でスクリプトエディタよりトリガーセットします。
何か不具合があったら、自分のアドレスにメールを送るようにしています。
/毎日 日報作成関数
function dailyTask() {
try {
//こいぬま連絡先
var admin = 'XXXXX@nippan.co.jp'; //管理者
//テンプレシート
var SheetName = 'テンプレ';
//週次シートの「シートファイル」を取得する
var ss = SpreadsheetApp.getActiveSpreadsheet();
//一番左のシートオブジェクトを取得
var sh = ss.getSheets()[0];
//「テンプレ」というシートを取得
var sheet = ss.getSheetByName(SheetName);
//「テンプレ」をコピーする
var newSheet = sheet.copyTo(ss).setName(getToday2());
//コピー先のシートをアクティブにする
ss.setActiveSheet(newSheet)
//コピー先のシートをスプレットシートの左に移動する
ss.moveActiveSheet(1);
deleteTrigger();
} catch (f) {
MailApp.sendEmail(admin, "【失敗】デイリーシート新シート作成 エラー発生", f.message);
return;
}
}
はい、フォーマット完成です。毎日シートをコピペコピペの面倒な作業もなし!
◎原価管理システム用開発要件
- 1.のフォーマット上からCSV形式に変換(日付指定可能)
色やらデザインやらのセンスがないですね…!
「CSV出力開始」と書かれた図形に以下のスクリプトを埋め込んでいます。
図形を押下すると、別タブのスプレッドシートに原価管理システムに取り込むCSV型に出力される仕様です。
少々雑ですが、開始日付・終了日付で範囲設定ができるようにコーディングをしています。
スプレッドシートのタブ自体が配列になっている、というのがポイントです。
GASはスプレッドシートを扱うと特に配列が多く出てきますので、配列と仲良くなりましょう。
(例えば、スプレットシートにマスタを作成して、レコードを読みに行く処理を書く場合は、
都度スプレットシートのレコードを読みにアクセスするのではなく、
二次元配列で必要なデータをまとめて取得、配列をループで回して該当レコードを取得する
という処理を書くのが一般的なようです。
GASは実行時間6分の壁があるので…処理スピードを意識し、配列を駆使しながらコーディングしていきましょう)
////////////////////////////////////////
//CSV作成ボタン押下で起動
//
////////////////////////////////////////
function csvMake() {
~~略~~
//「CSV出力」シートからCSVを出力する開始日付、終了日付を取得する。
var strDay = csvValues[1][0];//開始日付
var endDay = csvValues[1][1];//終了日付
//取得した前日の日付をyyyy/mm/dd型へ変換
var strDay2 = Utilities.formatDate(strDay, "JST", "MM/dd");//開始日付
var endDay2 = Utilities.formatDate(endDay, "JST", "MM/dd");//終了日付
var date = new Date;
var kakouYear = Utilities.formatDate(date, "JST", "yyyy");//終了日付
//変数初期化
var sheatName = ''; //シートの名前 MM/dd型
var sheatName2 = ''; //シートの名前 yyyy/MM/dd型
//スプレッドシート中の全てのシートを取得
var sheets = Spreadsheet.getSheets();
owari:
for (var x in sheets) {
//シート名が終了日付と一致
if (sheets[x].getSheetName() == endDay2) {
for (var i = x; i < sheets.length; i++) {
sheatName = sheets[i].getSheetName();
sheatName2 = kakouYear + '/' + str2;
var ssDay = toDate(sheatName2, '/'); //文字列→Date型変換後
//開始日付 >= シート名の日付
if (ssDay >= strDay) {
var owari = outCsvSheet(i);
}
}
}
}
}
◎原価管理システム用開発要件
- CSVファイルを出力させる
これについては、こちらの記事を参考にというか、ほぼそのまま活用させて頂きました。
ですので、ソースの詳細については割愛します。
ダウンロードタブからCSVをダウンロードできるようになりました…!
CSVファイルを原価管理システムに取り込むのは手動になりますが、
これも自動化できたら良いですね。勉強せねば。
◎問合せ/案件実績管理表の実績更新用開発要件
- 加工用の第一次アウトプット作成
察しの良い方は、きっと☝の「保守実績」のボタンにもスクリプト仕込んでいるのでしょう?
と気づかれたのではないでしょうか。
上記の日付範囲指定のロジックはそのまま再利用し、日報のシートに保守管理番号があった場合は、
保守実績管理用スプレッドシートに書き込みにいくというロジックになっています。
以前の記事と内容がかぶってしまうので、アウトプットの処理も割愛しますが、
コーディングのポイントは、インプット、アウトプットのスプレッドシートの列が変更されることも想定して、
スプレッドシート位置を定数にセットしておいた方が後々管理が楽になります。
(と、GASの師匠がおっしゃっていました。受け売りでした!)
//「第一実績アウトプット」の位置セット
const NO_SET = 1;//No位置
const ZISSEKITIME_SET = 2;//実績入力日時位置
const KANRINO_SET = 3;//管理No位置
const TITLE_SET = 4;//タイトル(問合せ・案件)位置
const KUBUN_SET = 5;//作業区分(問合せ・案件)位置
const YMD_SET = 6; //作業日付位置
const OCCURRENCEYMD_SET = 7; //発生日付位置
const ZISSEKI_SET = 8; //実績位置
const NAME_SET = 9; //作業者名位置
const IRAINAME_SET = 10; //依頼者名位置
const SYSTEM_SET = 11; //システム名位置
~~略~~
var projectCodeLong = sheetData[j][KANRINO_SET- 1]; //管理CD
var ymdDate =sheetData[j][YMD_SET- 1]; //作業日付
~~略~~
outSheat.getRange(outLastRowTuika, KANRINO_SET).setValue(kanriNo); //管理CD
outSheat.getRange(outLastRowTuika, YMD_SET).setValue(ymd); //作業日付
問合せ/案件の実績管理の開発は途中となっていますが、第一アウトプットのシートを作ったことにより、
チーム内の複数の問合せ/案件実績の管理が今後開発するプログラムによって楽になる兆しが見えてきました。
ゆくゆくは、保守資料(月次保守実績報告シートや問合せ管理表)とも連携ができそうです!
4.感想・まとめ
~~1ヵ月後~~
K「問合せ/案件実績管理表の更新は開発途中ですが、日報と原価管理システムの連携が
無事終わりました!」
S「お疲れ様でした。この調子で最後まで頑張ろう!」
K「これで、もう実績管理で悩まなくてすみますね!」
S「そうだね。ただ、日報入力をサボると大変なことになるから…
きちんと入力しようね!」
K「…」
S「…入力しようね?」
~~ (完) ~~
ノンプログラマーでも比較的簡単に開発ができるGASは、
今回の課題のような業務改善に向いた開発環境です。
今回開発したツール以外にも菅谷・肥沼の所属チームでは、
問合せの過去の履歴から検索・該当する問合せをフィルタリングして、返してくれる問合せボットや、
実績自動計算ツール、自動メール配信ツール、チャット文言自動ハンドリング・メール通知機能などを開発し、業務で活用しています。
皆さんも日々の業務で改善したい点をGASで解決してみませんか?
ご相談もお待ちしております!