起案システム/GAS/教務の先生へ/管理職へ届け
さてさて、
何でもかんでもデジタル化することでは正義ではない!!
何でもかんでもICTにすればいいんじゃない!!
って、言われますけど。
では、紙で起案した書類の一覧の管理や記録、数年前の記録はサッと出せますか?😎
学校の情報をデータ化していくことは、業務効率を上げるのにとても役立ちます。
いつ、どんな理由で、何が稟議されていたのか。
その記録を検索できるようになれば、楽だと思いません?🤔
学校では、
去年ってどうだったけ?😅
みたいな話、結構あるんですよね。
また、内容を精選することにも繋がってくるとも思うんです。
これって、自動化できるんじゃね!?
ということを、ふと思い。
サクッと作りました!!🤣笑
使い方はこんな感じ!!
これで大事なのは、前述した通り、起案の一覧が記録されていくこと!
そして、リンクをつけてあるからすぐにその文書に飛べるし、起案依頼はメールに行って、承認は各自設定されたものでできる!
いいすね👍✨
日付を入れたりしてもいいですね!!
また、一覧が残るスプシは、管理者のみ編集権限を付与して、あとは閲覧権限にしておくと良いと思います!
編集権限を持っていると意味ないので🤣笑
もちろん、自分達の学校用でカスタムしたい!!!
というお話があれば、ご相談に乗りますのでご連絡ください😆
プログラムはこんな感じ!
/----- 初期設定 (ここから) -----
// 対象とするGoogleDriveフォルダのID
const TARGET_FOLDER_ID = '';
//----- 初期設定 (ここまで) -----
// メインの関数
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sht = ss.getSheetByName('起案一覧');
// 前回の更新日時を取得
let lastDateText = PropertiesService.getScriptProperties().getProperty('lastDateText');
// 最終の日時がなければ初期値を代入
if( !lastDateText )
lastDateText = "2019/01/01 00:00:00";
// 最終の日時のDateオブジェクトをつくる
let lastDate = new Date(lastDateText);
// 対象のフォルダを取得
const targetFolder = DriveApp.getFolderById( TARGET_FOLDER_ID );
// アップロードされたファイルを取得
const files = getNewFiles( targetFolder, lastDate );
// 通知メッセージを作成
let message = "";
for(const file of files){
message += file.owner + 'が' +file.folder + 'に' +file.name + 'を追加しました\n' + file.url + '\n'
+ ' 稟議をお願いします。\n';
// 作成日時を取得
sht.insertRowBefore(2);
let number = Number(sht.getRange(3,1).getValue());
sht.getRange(2,1).setValue(number+1);
sht.getRange(2,2).setValue(file.owner);
sht.getRange(2,3).setValue(file.folder);
sht.getRange(2,4).setValue(file.name);
sht.getRange(2,5).setValue(file.url);
if( file.date > lastDate ) lastDate = file.date;
} console.log(lastDateText);
if( !message ) return false;
// メッセージを送信
sendMail(message);
// 最新の更新日時を記録
lastDateText = Utilities.formatDate( lastDate,"Asia/Tokyo", "yyyy-MM-dd HH:mm:ss.S"); //'JST', "yyyy-MM-dd'T'HH:mm:ssZ");//
PropertiesService.getScriptProperties().setProperty( "lastDateText", lastDateText );
console.log(message);
console.log(lastDateText);
}
// 追加されたファイルを取得する関数
function getNewFiles( targetFolder, lastDate ){
// フォルダ名を取得
const folderName = targetFolder.getName();
// 対象のフォルダ内のファイルを取得
const files = targetFolder.getFiles();
// 追加されたファイル情報を格納する配列を定義
let updatedFiles = [];
// filesの数だけ繰り返し
while( files.hasNext() ){
// 1つ取り出してfileに代入
const file = files.next();
const date = file.getLastUpdated();//DateCreated();
if( date > lastDate ){
const updatedFile = {
folder: folderName,
name: file.getName(),
url: file.getUrl(),
date: date,
owner: file.getOwner().getName()
};
updatedFiles.push( updatedFile );
}
}
//対象のフォルダ内のサブフォルダを取得
const folders = targetFolder.getFolders();
// 配列foldersの数だけ繰り返し
while( folders.hasNext() ){
// 1つ取り出してfolderに代入
const folder = folders.next();
// フォルダ内のサブフォルダを取得
const filesInFolder = getNewFiles( folder, lastDate );
// サブフォルダのファイルを追加
updatedFiles.push.apply( updatedFiles, filesInFolder );
}
return updatedFiles;
}
function sendMail(message){
let To = 'keisuke.edu@gmail.com';//ここにアドレスを入れてください
let Subject = '起案文書';//こちらはメールの件名になります
let Body = message + '\n\n'+ '承認先は\n' + 'https://docs.google.com/spreadsheets/d/1_tP1ZQuu34l70LzV0CjkRxHePv-wvjrEMN5kgz2qsAU/edit#gid=0';
GmailApp.sendEmail(To, Subject, Body);
}
function deputyHeadTeacher(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sht = ss.getSheetByName('起案一覧');
const ui = SpreadsheetApp.getUi();
const res = ui.prompt('承認パスワードは?');
const msg = res.getResponseText();
const lastRow = sht.getLastRow();
if(msg == 'pass'){
const res2 = ui.prompt('承認番号は?');
const msg2 = res2.getResponseText();
for(let row = 2; row <= lastRow; row++) {
if(sht.getRange(row, 1).getValue() == msg2){
sht.getRange(row,8).setValue('承認');
}
}
ui.alert('承認しました');
}
}
function headTeacher(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sht = ss.getSheetByName('起案一覧');
const ui = SpreadsheetApp.getUi();
const res = ui.prompt('承認パスワードは?');
const msg = res.getResponseText();
const lastRow = sht.getLastRow();
if(msg == 'pass2'){
const res2 = ui.prompt('承認番号は?');
const msg2 = res2.getResponseText();
for(let row = 2; row <= lastRow; row++) {
if(sht.getRange(row, 1).getValue() == msg2){
sht.getRange(row,6).setValue('承認');
}
}
ui.alert('承認しました');
}
}
function deputyHeadTeacher2(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sht = ss.getSheetByName('起案一覧');
const ui = SpreadsheetApp.getUi();
const res = ui.prompt('承認パスワードは?');
const msg = res.getResponseText();
const lastRow = sht.getLastRow();
if(msg == 'pass3'){
const res2 = ui.prompt('承認番号は?');
const msg2 = res2.getResponseText();
for(let row = 2; row <= lastRow; row++) {
if(sht.getRange(row, 1).getValue() == msg2){
sht.getRange(row,7).setValue('承認');
}
}
ui.alert('承認しました');
}
}
function manager(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sht = ss.getSheetByName('起案一覧');
const ui = SpreadsheetApp.getUi();
const res = ui.prompt('承認パスワードは?');
const msg = res.getResponseText();
const lastRow = sht.getLastRow();
if(msg == 'pass4'){
const res2 = ui.prompt('承認番号は?');
const msg2 = res2.getResponseText();
for(let row = 2; row <= lastRow; row++) {
if(sht.getRange(row,1).getValue() == msg2){
sht.getRange(row,9).setValue('承認');
}
}
ui.alert('承認しました');
}
}
レクチャーしやすいように作ってあるので、
いや、これこっちも配列にした方が効率いいじゃん😅
とかは、そっと置いといてください笑
コピーも貼っておきますねー。
もちろん、各学校用にカスタムもしますので!
何なりと!😎
こちらも併せて、動画にします!
YouTube チャンネル
動画一覧
ポートフォリオ
何かと0から1を作るのは大変だと思います。学校はどこも似たような問題課題に対応していると思います。それなのに、先生って自分だけで頑張ろうとするんですよね。ボクの資料やnoteが1になって、学校ごとの現状に合わせてカスタムしていただければと思います‼️