部活の検温フォームを朝送り、指定の時間までに答えていない人に催促し、その答えを待って、回答から検温表を作り、それを学生支援に送るフローを取っていましたが、この流れを自動化できないかと考えました。このフローを自動化したいと思ったからこそ、プログラミングを勉強しようと思いました。(東進のバイトの経験上、プログラミングの凄さがわかっていたというのも大きいですが...)
せっかくなので、見学するかどうかなども合わせて聞き、それをキャプテン(あるいは練習担当)に伝えることができたら、練習メニューも事前に組みやすいかなと思いました。実際にどれだけの部活が丁寧に検温取っているか分かりませんが(笑)、練習人数の把握は多少役に立つかなと感じました。
function pullDownNumberList() {
/**
// スプレッドシートの情報を取得する
//
**/
//スプレッドシートのID →「https://docs.google.com/spreadsheets/d/△△△/edit#gid=0」の△△△を↓に記述
var sheets = SpreadsheetApp.openById('ーーーーーーーーーーーーーーーーーーーーーーー').getSheets();
// シート1の情報を取得
//(4つ目のシートを取得)
var sheet = sheets[3];
// スプレッドシートのA1のセルが「DJ」の場合
if("学籍番号" == sheet.getRange("A1").getValue()){
// A行の2行目からコンテンツをもつ最後の行までの値を配列で取得する
var colA = sheet.getRange(2, 1, sheet.getLastRow() - 1).getValues();
}
/**
// Googleフォームのプルダウン内の値を上書きする
//
**/
// GoogleフォームのIDを設定 →「https://docs.google.com/forms/d/〇〇〇/edit」の〇〇〇を↓に記述
var form = FormApp.openById('-------------------------------------------');
// 質問項目がプルダウンのもののみ取得
var items = form.getItems(FormApp.ItemType.LIST);
items.forEach(function(item){
// 質問項目が「学籍番号を選択して下さい」を含むものに対して、スプレッドシートの内容を反映する
if(item.getTitle().match(/学籍番号を選んでください.*$/)){
var listItemQuestion = item.asListItem();
var choices = [];
colA.forEach(function(name){
if(name != ""){
choices.push(listItemQuestion.createChoice(name));
}
});
// プルダウンの選択肢を上書きする
listItemQuestion.setChoices(choices);
}
});
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//参考:https://qiita.com/kobaboy/items/610263087d9c85d8458e
//フィルター参考:https://futureobs.xyz/2018/08/09/function-filter/
スプレッドシートに打ち込んだリストをフォーム の選択肢に反映させます。数十項目を手打ちで作成するのは難しいからです。
ちなみにプルダウンで選ばせることによって、誤入力の可能性を減らします。学籍番号を選んでもらったら、名前は自動的に紐付けられるようにして、入力項目を減らします。
function pullDownTempuratureList() {
/**
// スプレッドシートの情報を取得する
//
**/
//スプレッドシートのID →「https://docs.google.com/spreadsheets/d/△△△/edit#gid=0」の△△△を↓に記述
var sheets = SpreadsheetApp.openById('-----------------------------------------').getSheets();
// シート1の情報を取得
//(デフォルトのスプレッドシートの場合、シート1という名称になっています)
var sheet = sheets[3];
// スプレッドシートのA1のセルが「DJ」の場合
if("体温" == sheet.getRange("D1").getValue()){
// A行の2行目からコンテンツをもつ最後の行までの値を配列で取得する
var colD = sheet.getRange(2, 4, sheet.getLastRow() - 4).getValues();
}
/**
// Googleフォームのプルダウン内の値を上書きする
//
**/
// GoogleフォームのIDを設定 →「https://docs.google.com/forms/d/〇〇〇/edit」の〇〇〇を↓に記述
var form = FormApp.openById('-----------------------------------------');
// 質問項目がプルダウンのもののみ取得
var items = form.getItems(FormApp.ItemType.LIST);
items.forEach(function(item){
// 質問項目が「好きなDJを選択して下さい」を含むものに対して、スプレッドシートの内容を反映する
if(item.getTitle().match(/体温を入力してください.*$/)){
var listItemQuestion = item.asListItem();
var choices = [];
colD.forEach(function(name){
if(name != ""){
choices.push(listItemQuestion.createChoice(name));
}
});
// プルダウンの選択肢を上書きする
listItemQuestion.setChoices(choices);
}
});
}
同様にスプレッドシートに打ち込んだリストをフォーム の選択肢に反映させます。
function setDate() {
// 開いているスプレッドシートを取得
var SS = SpreadsheetApp.getActiveSpreadsheet();
// 表の「自動転記」を取得
var sheet1 = SS.getSheetByName("自動転記");
// 日付を表の2箇所(フィルター関数用、未送信者リスト)に挿入
// 日付取得
const todaydate = new Date()
// 日付挿入
const insertDate = todaydate.getMonth() + 1 + "/"+ todaydate.getDate() ;
sheet1.getRange( 2,3 ).setValue( insertDate );
sheet1.getRange( 45,1 ).setValue( insertDate);
// 表の「キャプテン送信用」を取得
var sheet2 = SS.getSheetByName("キャプテン送信用");
// 日付を表に挿入
sheet2.getRange( 2,4 ).setValue( insertDate );
sheet2.getRange( 2,5 ).setValue( insertDate );
}
指定の時間(朝早く)に日にちを取得し、その日にち(のみ)を表の中に入れます。これで練習のある日のみ、自動的に正しく関数が引き起こされ、検索(自動転記)が行われます。
function formSend() {
// LINEで自動通知する内容。
// var content = の後に任意の文章を入力してください。
var content = "\nお疲れ様です。検温管理担当からです。\n";
content += "15時までに以下の検温フォームから、検温の確認お願いします。\n";
content += "フォームのURL";
sendHttpPost_shiftCreated(content);
}
// LINE Notifyを利用するための関数
function sendHttpPost_shiftCreated(content){
//LINEで自動通知をする宛先のトークン。
//'トークンを入力してください'の箇所に
//取得したトークンを入力してください。
var token = ['トークン '];
var options =
{
"method" : "post",
"payload" : {"message": content,
},
"headers" : {"Authorization" : "Bearer "+ token}
};
UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}
指定の時間(朝早く)にフォーム のURLを送り、フォームに回答してもらいます。
LINE Notify による自動送信を行っています。
=iferror(INDEX('フォームの回答1'!$C:$E,MATCH($A3&C$1,'フォームの回答1'!$B:$B&'フォームの回答1'!$A:$A,0)),"未送信")
フォーム の回答を別のシートに移します。学籍番号を入力すれば、名前と紐づくようにリストを作成します。未回答である(回答のシートにデータがない)と #N/Aと出てしまうので、未回答と表示されるようにiferror関数を利用しています。
A3:リストにある氏名、C1:日付で探しています。
ここで日付について、各日付に5桁のナンバリングがされているので、これを自動転記させてます。
=FILTER($B$2:$B$41,C2:C41="未送信")
if 関数を用いて、別のシートに天気できなかったので、同じシート上に「未送信」で一致する名前を列挙します。
function unsentInform() {
var mainSheets = SpreadsheetApp.getActiveSpreadsheet();
var sheet = mainSheets.getSheetByName("シート名");
var unsentMenbers = sheet.getRange(46,1,sheet.getLastRow() - 45);
var unInformList = unsentMenbers.getValues();
console.log(unInformList);
// LINEで自動通知する内容。
// var content = の後に任意の文章を入力してください。
var content = "\nお疲れ様です。検温管理担当からです。\n";
content += "まだ入力されていない、以下の方はすぐにフォームの送信してください。\n";
content += "フォーム のURL";
content += "\n";
content += `以下の人がフォームを送っていません。\n`;
content += "\n-------------------------\n";
content += unInformList;
//このunInformListに未送信者の名前が配列として入ります
content += "\n-------------------------\n";
sendHttpPost_shiftCreated(content);
}
// LINE Notifyを利用するための関数
function sendHttpPost_shiftCreated_2(content){
//LINEで自動通知をする宛先のトークン。
//'トークンを入力してください'の箇所に
//取得したトークンを入力してください。
var token = ['トークンを入力'];
var options =
{
"method" : "post",
"payload" : {"message": content,
},
"headers" : {"Authorization" : "Bearer "+ token}
};
UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}
//列データの取得:https://tonari-it.com/gas-spreadsheet-column-data-array/
//列データの取得2:https://uxmilk.jp/25841
//フィルター関数:http://www.eurus.dti.ne.jp/~yoneyama/Excel/kansu/filter.htm
指定の時間にformSend関数をトリガーさせ、未送信者をLINEのグループ上で挙げます。
=iferror(INDEX('フォームの回答1'!$C:$C,MATCH($B8&D$6,'フォームの回答1'!$B:$B&'フォームの回答1'!$A:$A,0)),36.5)
送信用のリストをレイアウトを整え、準備します。(画像ではデータをあえて消しています)
(秘密ですが、未入力であってもデフォルトで温度が入るようになっています...)
function creatPdf_tempurature_sendToGakushi(){
// 日付取得
const todaydate = new Date()
// 日付挿入
const insertDate = todaydate.getMonth() + 1 + "/"+ todaydate.getDate() ;
//pdfの名前を定義
const pdfName = "pdfの名前" + '('+insertDate +')';
//スプシの取得
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var key = spreadsheet.getId();
//スプシのシートを選んで取得
var sheetName = spreadsheet.getSheetByName("シートの名前");
var gid = sheetName.getSheetId();
var token = ScriptApp.getOAuthToken();
var url = "https://docs.google.com/spreadsheets/d/" + key + "/export?gid=" + gid + "&format=pdf&portrait=false&size=A4&gridlines=false&fitw=true";
var pdf = UrlFetchApp.fetch(url, {headers: {'Authorization': 'Bearer ' + token}}).getBlob().setName( pdfName +".pdf");
//メールアドレスの宛先を記述する
let address = "メールを送りたい人のアドレス";
//ここの宛先を変えるの忘れずに
//メールの件名を記述する
let mailTitle = "タイトル" + '(' + insertDate +')' + "の検温表";
//メール本文を記述する
let mailText ="お世話になっています。\n所属" + '(' + insertDate +')' + "の検温表です。";
mailText += "\nお手数おかけしますが、ご確認ください。なお、部活の参加の有無に関わらず、検温しています。実際に参加する部員はpdfにお示ししています。";
mailText += "\n-------------------------\n自分の所属や連絡先\n";
//オプションで添付ファイルを設定する
let options = {
"attachments":pdf,
};
//MailAppで宛先、件名、本文、添付ファイルを引数にしてメールを送付
MailApp.sendEmail(address, mailTitle, mailText, options);
}
//自動送信:https://jetb.co.jp/8759
//上のを利用して作った
//スプレッドシートのIDについて:https://qiita.com/n0bisuke/items/67afb8ad50d20fba0ad3
//Gmail以外にメールする方法:https://auto-worker.com/blog/?p=1511#toc_id_2
送信したいシートを取得し、pdfにして、指定のメールアドレス(自分は学生支援と自分)に文面をつけて、検温表を送信する。
=iferror(INDEX('フォームの回答1'!$E:$E,MATCH($A3&D$1,'フォームの回答1'!$B:$B&'フォームの回答1'!$A:$A,0)),"未送信")
フォーム未送信者や部活にくる人数や見学する人数をカウントします。
function creatPdf_practiceMenber_toAoki(){
// 日付取得
const todaydate = new Date()
// 日付挿入
const insertDate = todaydate.getMonth() + 1 + "/"+ todaydate.getDate() ;
const pdfName = "所属" + '('+insertDate +')';
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var key = spreadsheet.getId();
var sheetName = spreadsheet.getSheetByName("シート名");
var gid = sheetName.getSheetId();
var token = ScriptApp.getOAuthToken();
var url = "https://docs.google.com/spreadsheets/d/" + key + "/export?gid=" + gid + "&format=pdf&portrait=false&size=A4&gridlines=false&fitw=true";
var pdf = UrlFetchApp.fetch(url, {headers: {'Authorization': 'Bearer ' + token}}).getBlob().setName( pdfName +".pdf");
//ここの宛先を変えるの忘れずに
var to = "キャプテンのアドレス";
to = "自分のアドレス";
var subject = '所属'+'('+insertDate +')';
var body ="お世話になっています。\n所属" + '(' + insertDate +')' + "練習メンバー表です。";
body+= "今日も練習頑張りましょう";
GmailApp.sendEmail(to,
subject,
body,
{attachments: pdf})
};
//自動送信:https://jetb.co.jp/8759
//上のを利用して作った
//スプレッドシートのIDについて:https://qiita.com/n0bisuke/items/67afb8ad50d20fba0ad3
上で把握した人数状況を部員が記載した詳細な情報も合わせて、キャプテンに表で送信する。
function practiceMember() {
var mainSheets = SpreadsheetApp.getActiveSpreadsheet();
var sheet = mainSheets.getSheetByName("取得したいシート名");
var date1 =sheet.getRange("C46").getValue();
var date2 =sheet.getRange("C47").getValue();
var date3 =sheet.getRange("C48").getValue();
var date4 =sheet.getRange("C49").getValue();
var date5 =sheet.getRange("C50").getValue();
// LINEで自動通知する内容。
// var content = の後に任意の文章を入力してください。
var content = "\n今日の練習に参加できるメンバーと人数です。\n";
content += "\n-------------------------\n";
content += "部活に来る人数:" + date1 +"人\n";
content += "参加プレイヤー:" + date2 +"人\n";
content += "参加マネージャー:" + date3 +"人\n";
content += "見学プレイヤー:" + date4 +"人\n";
content += "部活に来ない人数:"+ date5 +"人\n";
content += "-------------------------\n";
sendHttpPost_shiftCreated(content);
}
// LINE Notifyを利用するための関数
function sendHttpPost_shiftCreated_3(content){
//LINEで自動通知をする宛先のトークン。
//'トークンを入力してください'の箇所に
//取得したトークンを入力してください。
var token = ['トークン '];
var options =
{
"method" : "post",
"payload" : {"message": content,
},
"headers" : {"Authorization" : "Bearer "+ token}
};
UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}
練習参加状況を練習前に連絡する
ここまで作るのに、1週間かかりました。(1日大体2,3時間くらいです)
誰にも相談する人がいないっていうのも、GASやJavascriptの勉強が不十分っていうのもあり、いろいろ進路変更しました。
フィルターを使おうと思ったり、Gmail以外にはメール送れないんじゃないかと思ったり...
最終的にはちゃんと思い通りに動くものができて満足です。