タスク表の作成

仕事が休みで一日暇だったので、プログラミングの勉強がてらタスクをまとめるスプレットシートを作ってみました。
誰でも無料で使えるGoogleSpreadSheetを利用し、簡単なタスク表を作成しました。配布の仕方を調べたら、共有していきます。
こういう機能あったら便利じゃない??というアイデアをお持ちの方いましたら実装していこうとおもうので、コメントお願いします!!

初心者なのでいろいろ間違っているところも多いかと思いますが、
コードを置いておきます。本職のPGの方がいらっしゃいましたらアドバイスいただけますとありがたいです。

タスク表を作った背景

私自身はSEなので自分でプログラムを記述することは少なく、なんとなくしかわからないんです(涙)
自分で記述する力をつけないとなと思って作成してみることにしました。今後何かに使えたらいいなとも思っています。

タスク表の概要

「種類」と「タスク名」を入力しボタンを押した際に下の表に自動で記載されるプログラムを作成しました。

入力した種類によってグルーピングされ、そのグループの一番下に新しいタスクが追加されるようにできています。(たぶん(笑))

タスク表

完全に自分用ですが「読書」と入力した際は、
「感想記入」「Note記載」がタスクとして増えるようにしています。
また、プログラムではないですがステータスを「済み」にした際にその行をグレーアウトしています。
今後は「更新」ボタンを押した際に済みのついている行を別の「完了タスクのシート」に移動させるようなプログラムを追加しようと思っています。

プログラム詳細(編集履歴・グローバル宣言)

編集履歴と使用するスプレットシートの宣言です。
変数をグローバル変数にしているのが嫌なので、クラス化??もしていかないとなと思っています。

//編集履歴==========================
//1.0.0 AddTasks 作成
//1.0.0 NullCheck 作成
//1.0.0 InsertNewTask 作成
//1.0.0 getStartNo 作成
//1.0.0 getEndNo 作成
//1.0.0 DeleteTasks 作成
//=================================

//1. 現在のスプレッドシートを取得
let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
//2. 現在のシートを取得
let sheet = spreadsheet.getActiveSheet();
var cgsSerchWord_Start = "START";
var cgsSerchWord_END = "END";
var cgsSerchWord_Title = "Title";

プログラム詳細(タスクを追加する親コード)

子コードを順次??実行していきます。
正直、エラー処理やワーニング処理が分からず、本職が見たら発狂するようなコードになってると思います。(誰か教えてください(´;ω;`))
※特殊処理は後で解説します。


//  タスクの追加=============================================================
function AddTasks() {
 try {
   
   let vgsAddTaskTitle = sheet.getRange("C2").getValue();
   let vgsAddTaskName = sheet.getRange("D2").getValue();
   
   //Null確認
   if (!NullCheck(vgsAddTaskTitle,vgsAddTaskName)){return false};
  
   // Start,End検索
   let vgiRowNo_Start = getRowNo(cgsSerchWord_Start);
   if(!vgiRowNo_Start){return false};
   let vgiRowNo_End = getRowNo(cgsSerchWord_END, vgiRowNo_Start);
   if(!vgiRowNo_End){return false};
   
   //  行の挿入
   let vgiNewRowNo = InsertNewTask(vgiRowNo_Start, vgiRowNo_End,vgsAddTaskTitle,vgsAddTaskName);
   if(!vgiNewRowNo){return false};
   
   //  読書の場合の特殊処理
   if(vgsAddTaskTitle === "読書"){
     let vgsBookName = vgsAddTaskName;
     vgsAddTaskName = vgsBookName + " 感想記入";
     InsertNewTask(vgiRowNo_Start, vgiRowNo_End,vgsAddTaskTitle,vgsAddTaskName);
     vgsAddTaskTitle = "Note投稿";
     InsertNewTask(vgiRowNo_Start, vgiRowNo_End,vgsAddTaskTitle,vgsBookName);
   };
 } catch(error) {
   Browser.msgBox(error);
 }
}

プログラム詳細(Nullチェック)

「種類」「タスク名」を記載しているかどうか確認するNull値チェックです。

//  Null確認=============================================================
function NullCheck(vlsAddTaskTitle,vlsAddTaskName){
 if (!vlsAddTaskTitle ){
   Browser.msgBox("種類を入力してください");
   return false;
 } else if(!vlsAddTaskName){
   Browser.msgBox("タスク名を入力してください");
   return false;
 }
 return true;
}

プログラム詳細(該当列検索)

どこから表が始まっているのかを探すためのプログラムです。
非表示のA列に"START", "END"が隠れているので、その行数を探し出し表がどこからどこまでなのかを認識させます。

キャプチャ

// 該当行検索=============================================================
function getRowNo(vlsSearchWord, vliStartRowNo = 1){
 
 let cliMaxSearchRowsCount_Start = 11;
 let cliMaxSearchRowsCount_END = 50;
 let cliMaxSearchRowsCount_Title = 11;
 
 //初期化
 let vliRowNo = 0;
 let vlsRowWord = "";
 let vliMaxSearchRowsCount = 0;
 
 //探す単語により、探す行数を変更する。
 switch (vlsSearchWord){
 case cgsSerchWord_Start:
     vliMaxSearchRowsCount = cliMaxSearchRowsCount_Start;
     break;
 case cgsSerchWord_END:
     vliMaxSearchRowsCount = cliMaxSearchRowsCount_END;
     break;
 case cgsSerchWord_Title:
     vliMaxSearchRowsCount = cliMaxSearchRowsCount_Title;
     break;
 }
 
 //行数を取得する。
 for (let i = vliStartRowNo; i < vliStartRowNo + vliMaxSearchRowsCount; i++) {
   vlsRowWord = sheet.getRange(i,1).getValue();
   if(vlsRowWord === vlsSearchWord){
     vliRowNo = i;
     return vliRowNo;
   }
 }
 if (vliRowNo === 0){
   Browser.msgBox(vlsSearchWord + "の検索に失敗しました。");
   return false;
 }
}

プログラム詳細(該当列検索)

行の追加をします。(本丸のコードですね。)
下記のような構成です。
1)入力した「種類」を取得する
2)C列にすでに該当の「種類」が記載されているか判定する。
3)なければ、最終行にテンプレート行を追加する。
4)もしあれば、その「種類」の最終行にテンプレート行を追加する。

//  行の挿入=============================================================
function InsertNewTask(vliRowNo_Start,vliRowNo_End,vlsAddTaskTitle,vlsAddTaskName){
 //  挿入行の特定
 let vliNewRowNo = 0;
 let vliSearchNo = 0;
 let vlsSearchWord = "";
 let vliSearchNextRow = 0;
 let vlsSearchNexTitle = "";
 let vlbTitleExist = Boolean("");
 
 for (let i = vliRowNo_Start + 1; i < vliRowNo_End; i++) {
   vliSearchNo = sheet.getRange(i,2).getValue();
   vlsSearchWord = sheet.getRange(i,3).getValue();
   if(vlsSearchWord === vlsAddTaskTitle){
     for(let j = i;j < vliRowNo_End; j++) {
       vliSearchNextRow = sheet.getRange(j+1,2).getValue();
       vlsSearchNexTitle = sheet.getRange(j+1,3).getValue();
       if ((vliSearchNextRow && vlsSearchNexTitle) || !vliSearchNextRow){
         vliNewRowNo = j+1;
         vlbTitleExist = Boolean("True");
         break
       }
     }
   } else if (!vliSearchNo && !vlbTitleExist){
     vliNewRowNo = i;
     break
   }
 }
 if (vliNewRowNo === 0){
   Browser.msgBox("作成行の取得に失敗しました。");
   return false
 }
 //  行の挿入
 sheet.insertRowBefore(vliNewRowNo);
 //  テンプレ行のコピー
 sheet.getRange(vliRowNo_Start,2,1,7).copyTo(sheet.getRange(vliNewRowNo,2,1,7));
 //  値の代入
 if (!vlbTitleExist){
   sheet.getRange(vliNewRowNo,3).setValue(vlsAddTaskTitle);
 }
 sheet.getRange(vliNewRowNo,4).setValue(vlsAddTaskName);
 return vliNewRowNo;
}

プログラム詳細(特殊処理)

上記で説明を後回しにした特殊処理です。と言っても単純です。
「読書」がきたときに、「感想記入」と「Note投稿」の列を追加するようにコード作成の部分を起動しているだけです。

   //  読書の場合の特殊処理
   if(vgsAddTaskTitle === "読書"){
     let vgsBookName = vgsAddTaskName;
     vgsAddTaskName = vgsBookName + " 感想記入";
     InsertNewTask(vgiRowNo_Start, vgiRowNo_End,vgsAddTaskTitle,vgsAddTaskName);
     vgsAddTaskTitle = "Note投稿";
     InsertNewTask(vgiRowNo_Start, vgiRowNo_End,vgsAddTaskTitle,vgsBookName);
   };
 } catch(error) {
   Browser.msgBox(error);
 }

感想

プログラムの説明は以上です。
普段はプログラムはみるだけなので自分で作ってみると予想以上に時間がかかってしまいました(´;ω;`)
「たぶん、間違ってるんだろうな(ダサいんだろうな)」と思いながら作っているのが現実ですね。。。
変数宣言とか。クラス化とか。勉強しますね・・・

これからも少しずつ機能を付け足していったり、そもそも全く別の用途で使うシートを作ったり、別の言語でプログラミング開発していきたいなと思います。

最後に興味ある人がいるのかはわかりませんが全ソースコードを載せておきます。
本職の方、アドバイスください(切実)

~~~~~~~~~~~~
ごん\( •̀ω•́ )/

//編集履歴==========================
//1.0.0 AddTasks 作成
//1.0.0 NullCheck 作成
//1.0.0 InsertNewTask 作成
//1.0.0 getStartNo 作成
//1.0.0 getEndNo 作成
//1.0.0 DeleteTasks 作成
//=================================

//1. 現在のスプレッドシートを取得
let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
//2. 現在のシートを取得
let sheet = spreadsheet.getActiveSheet();
var cgsSerchWord_Start = "START";
var cgsSerchWord_END = "END";
var cgsSerchWord_Title = "Title";

//  タスクの追加=============================================================
function AddTasks() {
 try {
   
   let vgsAddTaskTitle = sheet.getRange("C2").getValue();
   let vgsAddTaskName = sheet.getRange("D2").getValue();
   
   //Null確認
   if (!NullCheck(vgsAddTaskTitle,vgsAddTaskName)){return false};
  
   // Start,End検索
   let vgiRowNo_Start = getRowNo(cgsSerchWord_Start);
   if(!vgiRowNo_Start){return false};
   let vgiRowNo_End = getRowNo(cgsSerchWord_END, vgiRowNo_Start);
   if(!vgiRowNo_End){return false};
   
   //  行の挿入
   let vgiNewRowNo = InsertNewTask(vgiRowNo_Start, vgiRowNo_End,vgsAddTaskTitle,vgsAddTaskName);
   if(!vgiNewRowNo){return false};
   
   //  読書の場合の特殊処理
   if(vgsAddTaskTitle === "読書"){
     let vgsBookName = vgsAddTaskName;
     vgsAddTaskName = vgsBookName + " 感想記入";
     InsertNewTask(vgiRowNo_Start, vgiRowNo_End,vgsAddTaskTitle,vgsAddTaskName);
     vgsAddTaskTitle = "Note投稿";
     InsertNewTask(vgiRowNo_Start, vgiRowNo_End,vgsAddTaskTitle,vgsBookName);
   };
 } catch(error) {
   Browser.msgBox(error);
 }
}

//======================================================================
//  Null確認=============================================================
function NullCheck(vlsAddTaskTitle,vlsAddTaskName){
 if (!vlsAddTaskTitle ){
   Browser.msgBox("種類を入力してください");
   return false;
 } else if(!vlsAddTaskName){
   Browser.msgBox("タスク名を入力してください");
   return false;
 }
 return true;
}

//  行の挿入=============================================================
function InsertNewTask(vliRowNo_Start,vliRowNo_End,vlsAddTaskTitle,vlsAddTaskName){
 //  挿入行の特定
 let vliNewRowNo = 0;
 let vliSearchNo = 0;
 let vlsSearchWord = "";
 let vliSearchNextRow = 0;
 let vlsSearchNexTitle = "";
 let vlbTitleExist = Boolean("");
 
 for (let i = vliRowNo_Start + 1; i < vliRowNo_End; i++) {
   vliSearchNo = sheet.getRange(i,2).getValue();
   vlsSearchWord = sheet.getRange(i,3).getValue();
   if(vlsSearchWord === vlsAddTaskTitle){
     for(let j = i;j < vliRowNo_End; j++) {
       vliSearchNextRow = sheet.getRange(j+1,2).getValue();
       vlsSearchNexTitle = sheet.getRange(j+1,3).getValue();
       if ((vliSearchNextRow && vlsSearchNexTitle) || !vliSearchNextRow){
         vliNewRowNo = j+1;
         vlbTitleExist = Boolean("True");
         break
       }
     }
   } else if (!vliSearchNo && !vlbTitleExist){
     vliNewRowNo = i;
     break
   }
 }
 if (vliNewRowNo === 0){
   Browser.msgBox("作成行の取得に失敗しました。");
   return false
 }
 //  行の挿入
 sheet.insertRowBefore(vliNewRowNo);
 //  テンプレ行のコピー
 sheet.getRange(vliRowNo_Start,2,1,7).copyTo(sheet.getRange(vliNewRowNo,2,1,7));
 //  値の代入
 if (!vlbTitleExist){
   sheet.getRange(vliNewRowNo,3).setValue(vlsAddTaskTitle);
 }
 sheet.getRange(vliNewRowNo,4).setValue(vlsAddTaskName);
 return vliNewRowNo;
}

// 該当行検索=============================================================
function getRowNo(vlsSearchWord, vliStartRowNo = 1){
 
 let cliMaxSearchRowsCount_Start = 11;
 let cliMaxSearchRowsCount_END = 50;
 let cliMaxSearchRowsCount_Title = 11;
 
 //初期化
 let vliRowNo = 0;
 let vlsRowWord = "";
 let vliMaxSearchRowsCount = 0;
 
 //探す単語により、探す行数を変更する。
 switch (vlsSearchWord){
 case cgsSerchWord_Start:
     vliMaxSearchRowsCount = cliMaxSearchRowsCount_Start;
     break;
 case cgsSerchWord_END:
     vliMaxSearchRowsCount = cliMaxSearchRowsCount_END;
     break;
 case cgsSerchWord_Title:
     vliMaxSearchRowsCount = cliMaxSearchRowsCount_Title;
     break;
 }
 
 //行数を取得する。
 for (let i = vliStartRowNo; i < vliStartRowNo + vliMaxSearchRowsCount; i++) {
   vlsRowWord = sheet.getRange(i,1).getValue();
   if(vlsRowWord === vlsSearchWord){
     vliRowNo = i;
     return vliRowNo;
   }
 }
 if (vliRowNo === 0){
   Browser.msgBox(vlsSearchWord + "の検索に失敗しました。");
   return false;
 }
}

この記事が気に入ったらサポートをしてみませんか?