これはコドモン Advent Calendar 2022 13日目の記事です。
こんにちは!22年度新卒で保護者機能チームの船越です!最近の悩みごとは、膝の冷えです!
はじめに
悩みといえば、自分は単純作業が苦手です。
黙々と一人で同じ作業していると段々集中力が落ちてきて、結果的に単純な見落としなどのケアレスミスを起こしてしまうのです。
今回は、そんな自分の天敵である単純作業を自動化してみた話になります!
【何に困っていたか】40人分のアンケートを手作業で集計
コドモンでは毎月LT大会を行っていて、毎回参加者に満足度を聞くアンケートを実施しています。回答はすべて、1つのスプレッドシート(Google Sheets)に集約されています。
そのため当月のアンケートの回答結果を共有するには、スプレッドシートから手作業で当月分のデータを切り出して整形する必要がありました。
アンケート結果をスプレッドシートにLT大会の回数ごとに切り出します
この、別のスプレッドシートへの切り出し作業に地味に時間がかかっており、何よりも手間でした。さらに手作業による入力ミスなども発生することもあり、小さいながらも存在感のある問題となっていました。
そこで、この問題を何とかしようと、チームの別メンバーに作業の自動化を提案したところ、快く受け入れてもらえたため、着手を開始しました。
【どうやって解決したか】GAS導入で自動化!(ソースコードあり)
作業はすべてGoogle Sheetsに関わるもののため、Google Apps Script(以下GAS)を使った自動化を行いました。
GASはGoogleが提供している各種サービスの自動化や連携を行うためのローコード開発ツールです。使用言語がJavaScriptと似ているため、学習コストが低く気軽に使えます。
ソースコードは以下に記載していますが、簡単に処理の流れを説明すると、
- アンケート集計結果スプレッドシートから、任意の回のアンケート結果データを抽出
- 切り出し用のスプレッドシートを作成
- 切り出し用のスプレッドシートに1.で抽出したデータを注入
- 注入したデータの並びを整える
といった流れです。
function organize(){
const lt_number = {$LT大会の開催数}
const line_day = new Date({$LT大会の開催日付});;
const original_ss_ID = '{$切り出し元のスプレッドシートID}'
const original_sh_name = "{$切り出したいシート名}"
const extract_ss_ID = '{$切り出し先のスプシの雛形になるスプレッドシートのID}'
const questionnaire_data = [];
const original_ss = SpreadsheetApp.openById(original_ss_ID);
const original_sprt_sh = original_ss.getSheetByName(original_sh_name);
const extract_ss = DriveApp.getFileById(extract_ss_ID);
const sprt_values = original_sprt_sh.getRange('A:A').getValues();
const sprt_lastrow = sprt_values.length;
const sprt_sh_data = original_sprt_sh.getRange(1,1,sprt_lastrow,7).getValues();
for (let i=1; i< sprt_lastrow; i++){
if(sprt_sh_data[i][0] < line_day) continue
questionnaire_data.push(sprt_sh_data[i].slice(1));
}
const folder_ID = "{$切り出し先のスプレッドシートを保存したいフォルダID}";
const files_Folder = DriveApp.getFolderById(folder_ID);
const copied_extract_ss_ID = extract_ss.makeCopy(`第${lt_number}回LT大会!フィードバック`,files_Folder).getId()
const opened_extract_ss = SpreadsheetApp.openById(copied_extract_ss_ID);
const participant_names = [];
for (let i=1; i< questionnaire_data.length ; i++){
if (participant_names.includes(questionnaire_data[i][0])) continue
participant_names.push(questionnaire_data[i][0]);
};
for (let i=0; i < participant_names.length; i++){
const ss_sheet_temp = opened_extract_ss.getSheetByName("{$複製したい雛形スプシのシート名");
const ss_sheet_copy = ss_sheet_temp.copyTo(opened_extract_ss);
ss_sheet_copy.setName(participant_names[i]);
};
for (let i=0; i<questionnaire_data.length; i++){
const sheet = opened_extract_ss.getSheetByName(questionnaire_data[i][0]);
for (let j=0; j<questionnaire_data[i].length; j++){
sheet.getRange(i+2, j+1).setValue(questionnaire_data[i][j+1]);
};
};
for (let i=0; i<opened_extract_ss.getNumSheets(); i++ ){
let last_row = opened_extract_ss.getSheets()[i].getLastRow();
for (let j=1; j<last_row; j++){
let left_most_cell_value = opened_extract_ss.getSheets()[i].getRange(j,1).getValue();
try{
if(left_most_cell_value == ''){
opened_extract_ss.getSheets()[i].deleteRow(j);
j -= 1;
};
}catch(error){
break
}
};
};
}
【その結果どうなったか】
作業の省力化
当然ながら、今までの手作業がかなり省力化されました。以前は作業全体通して15分程かかっていた時間が2〜3分に短縮され、もう一つの問題点であったケアレスミスも全く無くなりました。
作業の着手スピードアップ
また、これは改善してから気づいたのですが、作業そのものに対するハードルが下がり、着手が迅速になりました。これまでは、作業に対する苦手意識から無意識的に実行を後回しにしてしまい、そのまま実行自体を忘れてしまうことがありましたが、自動化したことにより実行のハードルが下がり、早めに着手できるようになりました。
リファクタリングの勉強に活用
さらに、リファクタリングを練習する上でよい教材にもなりました。
以前から参加している社内の勉強会で、リファクタリングがトピックに上がったことがあり、実際に何か一つのコードを参加者それぞれでリファクタリングしてみようとなりました。
そこで、コードの長さや処理の複雑さを加味すると、このソースコードがちょうどよいということを提案すると、快く教材に選んでもらえました。
完成物が社内ツールであったことから、スピードを優先しとりあえずの完成を目指したため、元のコードはあまりいいクオリティとは言えませんでした。クラスなどには分割せずすべて平文で書いているし、処理にも所々無駄があります。
しかし、勉強会でみなさんにリファクタリングしてもらったものを見ると、そういった仕方なく雑にしてしまっていた部分が綺麗に修正され、実行スピードも改善され、ツールとしての完成度も上がりました。
また、勉強会では参加者それぞれが書いたコードにお互いがフィードバックを行ったことにより、何よりも自分では思いつかなかった改善方法やリファクタリングの手法などの知見を多く得られました。
おわりに
いかがでしたでしょうか。今回は、興味本位で始めた作業の自動化が、結果的に作業の効率化だけでなく、自分のスキルの向上につながりました。
このように、気軽に始めたことでも意外な結果に結びつくこともあるので、今後も積極的に色んなことに挑戦していきたいと思います。
コドモンの開発チームのTwitterを始めました!
アドベントカレンダーの新着記事も毎日ツイートしていくので、ぜひフォローしてください😊
twitter.com