ここまでの記事 プログラムの続きを書いてとりあえずの完成を目指します!
今回のソースファイル全文
今回の追加分です。それぞれ、前回作成したコードファイルに追加していきます。
「~以下に追加」となっていますが、基本どこでもOKです。
define.gsに追加
main.gsに追加
- // -------------------------------------------------------------------------------------------------------
- // tmpシート.
- // -------------------------------------------------------------------------------------------------------
- var TmpDataStartX = 3; // 開始 X.
- var TmpDataStartY = 3; // 開始 Y.
- var TmpYearX = 2; // 年度 X.
- // -------------------------------------------------------------------------------------------------------
- // エントリーポイント以下に追加.
- // -------------------------------------------------------------------------------------------------------
- // -------------------------------------------------------------------------------------------------------
- // 「作物決定」ボタンを押した.
- // -------------------------------------------------------------------------------------------------------
- function PushEntry() {
- // シートの取得.
- var mngSheet = SpreadsheetApp.openById( SheetID ).getSheetByName( SheetNameMng );
- var dataSheet = SpreadsheetApp.openById( SheetID ).getSheetByName( SheetNameData );
- var defineSheet = SpreadsheetApp.openById( SheetID ).getSheetByName( SheetNameDefine );
- if ( mngSheet === null ) { return; }
- if ( dataSheet === null ) { return; }
- if ( defineSheet === null ) { return; }
- // 作物名が存在するかどうかチェック.
- var dataID = SearchDataSheet( dataSheet );
- if ( dataID === -1 ) { return; }
- var dataIdx = GetLastRow( mngSheet, MngListIDX ) + 1;
- var num, tmp;
- // ID.
- mngSheet.getRange( dataIdx, MngListIDX ).setValue( dataID );
- // 作物名.
- mngSheet.getRange( dataIdx, MngListNameX ).setValue(
- dataSheet.getRange( dataID, DataNameX ).getValue() );
- // 科目.
- mngSheet.getRange( dataIdx, MngListSubjectX ).setValue(
- GetDataToSubject( dataSheet, defineSheet, dataID, DefineVarietySubjectX ) );
- // 作業開始.
- num = dataSheet.getRange( dataID, DataSowingSeedStartX ).getValue();
- tmp = dataSheet.getRange( dataID, DataSowingSeedResultX ).getValue();
- if ( num === 0 ) {
- // 種まき作業がないので定植で考える.
- num = dataSheet.getRange( dataID, DataPlantingStartX ).getValue();
- tmp = dataSheet.getRange( dataID, DataPlantingResultX ).getValue();
- mngSheet.getRange( dataIdx, MngListIsSowingSeedX ).setValue( false );
- } else {
- mngSheet.getRange( dataIdx, MngListIsSowingSeedX ).setValue( true );
- }
- mngSheet.getRange( dataIdx, MngListWorkStartX ).setValue( num + '月' );
- // 収穫.
- mngSheet.getRange( dataIdx, MngListWorkEndX ).setValue(
- dataSheet.getRange( dataID, DataHarvestStartX ).getValue() + '月' );
- // 作業終了週.
- mngSheet.getRange( dataIdx, MngListWorkEndWeekX ).setValue(
- dataSheet.getRange( dataID, DataCultivationPeriodEndX ).getValue() );
- // 輪作年限BASE.
- mngSheet.getRange( dataIdx, MngListCropRotX ).setValue(
- GetDataToSubject( dataSheet, defineSheet, dataID, DefineCropRotResultX ) );
- // 輪作年限残り.
- mngSheet.getRange( dataIdx, MngListCropRotRestX ).setValue(
- GetDataToSubject( dataSheet, defineSheet, dataID, DefineCropRotResultX ) );
- // カラ期間.
- if ( dataIdx !== MngListStartY ) {
- // 1個前の作業終了週をget.
- num = mngSheet.getRange( (dataIdx - 1), MngListWorkEndWeekX ).getValue();
- // 選択した作物の作業開始週と比較.
- if ( num < tmp ) {
- // カラ期間計算.
- num = tmp - num;
- } else {
- num = OneYearToWeeks + (tmp - num);
- }
- // カラ期間.
- mngSheet.getRange( dataIdx, MngListIntervalX ).setValue( num );
- // 前の輪作年限を全部更新.
- num = num + dataSheet.getRange( dataID, DataCultivationPeriodResultX ).getValue(); // カラ期間+栽培期間(ざっくり).
- for ( var y = MngListStartY; y < dataIdx; ++y ) {
- tmp = mngSheet.getRange( y, MngListCropRotRestX ).getValue();
- if ( tmp === 0 ) { continue; }
- tmp = tmp - num;
- if ( tmp < 0 ) { tmp = 0; }
- mngSheet.getRange( y, MngListCropRotRestX ).setValue( tmp );
- }
- }
- return;
- }
- // -------------------------------------------------------------------------------------------------------
- // 「スケジュール作成」ボタンを押した.
- // -------------------------------------------------------------------------------------------------------
- function PushCreateSchedule() {
- // シートの取得.
- var mngSheet = SpreadsheetApp.openById( SheetID ).getSheetByName( SheetNameMng );
- var dataSheet = SpreadsheetApp.openById( SheetID ).getSheetByName( SheetNameData );
- var defineSheet = SpreadsheetApp.openById( SheetID ).getSheetByName( SheetNameDefine );
- if ( mngSheet === null ) { return; }
- if ( dataSheet === null ) { return; }
- if ( defineSheet === null ) { return; }
- // 指定シート名が存在するか.
- var newSheetName = mngSheet.getRange( MngConfigSheetName ).getValue();
- var newSheet = GetSheet( newSheetName );
- if ( newSheet !== null ) {
- // シートを削除する.
- DeleteSheet( newSheet );
- }
- // 新たに作成.
- newSheet = CopySheet( SheetNameTmp, newSheetName );
- // 作物リストを頭から解釈してく.
- var dataEnd = GetLastRow( mngSheet, MngListIDX ) + 1;
- var year = 0, ID, isSeed, start, end, index = 1, col, name;
- // ~年目入力.
- DrawYear( newSheet, (year + 1) );
- for ( var y = MngListStartY; y < dataEnd; ++y ) {
- // ID.
- ID = mngSheet.getRange( y, MngListIDX ).getValue();
- // 種まきか否か.
- isSeed = mngSheet.getRange( y, MngListIsSowingSeedX ).getValue();
- // 作業終了週.
- end = dataSheet.getRange( ID, DataCultivationPeriodEndX ).getValue();
- // 色.
- col = GetBGColorToSubject( defineSheet, mngSheet.getRange( y, MngListSubjectX ).getValue() );
- // 名前.
- name = mngSheet.getRange( y, MngListNameX ).getValue();
- if ( isSeed === true ) {
- // 種まき開始週.
- start = dataSheet.getRange( ID, DataSowingSeedResultX ).getValue();
- } else {
- // 定植開始週.
- start = dataSheet.getRange( ID, DataPlantingResultX ).getValue();
- }
- // 色塗り開始.
- if ( y !== MngListStartY ) {
- if ( index >= start ) {
- // 1年ずらす.
- ++year;
- // ~年目入力.
- DrawYear( newSheet, (year + 1) );
- }
- }
- index = start;
- // 名前入力.
- newSheet.getRange( (TmpDataStartY + year), (index + TmpDataStartX - 1) ).setValue( name );
- while ( true ) {
- // 終了チェック.
- if ( index === end ) { break; }
- // 色塗り.
- newSheet.getRange( (TmpDataStartY + year), (index + TmpDataStartX - 1) ).setBackground( col );
- ++index;
- if ( index > OneYearToWeeks ) {
- // 年数を増やす.
- ++year;
- // ~年目入力.
- DrawYear( newSheet, (year + 1) );
- index = 1;
- }
- }
- }
- return;
- }
- // -------------------------------------------------------------------------------------------------------
- // 「1つ消す」ボタンを押した.
- // -------------------------------------------------------------------------------------------------------
- function PushOnePrev() {
- // シートの取得.
- var mngSheet = SpreadsheetApp.openById( SheetID ).getSheetByName( SheetNameMng );
- var dataSheet = SpreadsheetApp.openById( SheetID ).getSheetByName( SheetNameData );
- if ( mngSheet === null ) { return; }
- if ( dataSheet === null ) { return; }
- var endY = GetLastRow( mngSheet, MngListIDX );
- if ( endY < MngListStartY ) { return; }
- // 消してしまうカラ期間 + 栽培期間.
- var baseNum, tmp;
- var num =
- mngSheet.getRange( endY, MngListIntervalX ).getValue() +
- dataSheet.getRange( mngSheet.getRange( endY, MngListIDX ).getValue(), DataCultivationPeriodResultX ).getValue();
- RangeClear( mngSheet, MngListIDX, endY, 10, 1 );
- // 輪作年限を再設定.
- for ( var y = MngListStartY; y < endY; ++y ) {
- baseNum = mngSheet.getRange( y, MngListCropRotX ).getValue();
- if ( baseNum === 0 ) { continue; }// 輪作年限がもともとない作物はスキップ.
- tmp = mngSheet.getRange( y, MngListCropRotRestX ).getValue();
- tmp = tmp + num;
- // base以上にならないようにする.
- if ( tmp > baseNum ) {
- tmp = baseNum;
- }
- mngSheet.getRange( y, MngListCropRotRestX ).setValue( tmp );
- }
- return;
- }
- // -------------------------------------------------------------------------------------------------------
- // 「全部消す」ボタンを押した.
- // -------------------------------------------------------------------------------------------------------
- function PushAllDelete() {
- // シートの取得.
- var mngSheet = SpreadsheetApp.openById( SheetID ).getSheetByName( SheetNameMng );
- if ( mngSheet === null ) { return; }
- RangeClear( mngSheet, MngListIDX, MngListStartY, 10, 0 );
- return;
- }
- // -------------------------------------------------------------------------------------------------------
- // private以下に追加.
- // -------------------------------------------------------------------------------------------------------
- // -------------------------------------------------------------------------------------------------------
- // 現在のスプレッドシートの中の指定の名前のシートを取得.
- // -------------------------------------------------------------------------------------------------------
- function GetSheet( sheetName ) {
- return SpreadsheetApp.getActive().getSheetByName( sheetName );
- }
- // -------------------------------------------------------------------------------------------------------
- // スプレッドシートを削除.
- // -------------------------------------------------------------------------------------------------------
- function DeleteSheet( sheet ) {
- SpreadsheetApp.getActive().deleteSheet( sheet );
- return;
- }
- // -------------------------------------------------------------------------------------------------------
- // スプレッドシートをコピー作成&リネーム.
- // -------------------------------------------------------------------------------------------------------
- function CopySheet( copySheetName, newSheetName ) {
- var copy = GetSheet( copySheetName );
- if ( copy === null ) { return null; }// 失敗.
- var newSheet = copy.copyTo( SpreadsheetApp.getActive() );
- if ( newSheet === null ) { return null; }//失敗.
- // リネーム.
- newSheet.setName( newSheetName );
- return newSheet;
- }
- // -------------------------------------------------------------------------------------------------------
- // ~年目入力.
- // -------------------------------------------------------------------------------------------------------
- function DrawYear( tmpSheet, year ) {
- tmpSheet.getRange( ((TmpDataStartY - 1) + year), TmpYearX ).setValue( year + '年目' );
- return;
- }
- // -------------------------------------------------------------------------------------------------------
- // 科目名の背景カラーを取得.
- // -------------------------------------------------------------------------------------------------------
- function GetBGColorToSubject( defineSheet, subjectName ) {
- var endIdx = GetLastRow( defineSheet, DefineSubjectX ) + 1;
- var ranges = defineSheet.getRange( DefineDataStartY, DefineSubjectX, endIdx, 1 ).createTextFinder( subjectName ).findAll();
- if ( ranges.length === 0 ) { return '#ffffff'; }
- return ranges[0].getBackground();
- }
【解説】「作物決定」ボタンの処理実装
18~62行目
選択中のセルの作物名から「data」シートを検索し、縦列をIDとして利用しています。
- // 作物名が存在するかどうかチェック.
- var dataID = SearchDataSheet( dataSheet );
- if ( dataID === -1 ) { return; }
- var dataIdx = GetLastRow( mngSheet, MngListIDX ) + 1;
- var num, tmp;
- // ID.
- mngSheet.getRange( dataIdx, MngListIDX ).setValue( dataID );
- // 作物名.
- mngSheet.getRange( dataIdx, MngListNameX ).setValue(
- dataSheet.getRange( dataID, DataNameX ).getValue() );
- // 科目.
- mngSheet.getRange( dataIdx, MngListSubjectX ).setValue(
- GetDataToSubject( dataSheet, defineSheet, dataID, DefineVarietySubjectX ) );
- // 作業開始.
- num = dataSheet.getRange( dataID, DataSowingSeedStartX ).getValue();
- tmp = dataSheet.getRange( dataID, DataSowingSeedResultX ).getValue();
- if ( num === 0 ) {
- // 種まき作業がないので定植で考える.
- num = dataSheet.getRange( dataID, DataPlantingStartX ).getValue();
- tmp = dataSheet.getRange( dataID, DataPlantingResultX ).getValue();
- mngSheet.getRange( dataIdx, MngListIsSowingSeedX ).setValue( false );
- } else {
- mngSheet.getRange( dataIdx, MngListIsSowingSeedX ).setValue( true );
- }
- mngSheet.getRange( dataIdx, MngListWorkStartX ).setValue( num + '月' );
- // 収穫.
- mngSheet.getRange( dataIdx, MngListWorkEndX ).setValue(
- dataSheet.getRange( dataID, DataHarvestStartX ).getValue() + '月' );
- // 作業終了週.
- mngSheet.getRange( dataIdx, MngListWorkEndWeekX ).setValue(
- dataSheet.getRange( dataID, DataCultivationPeriodEndX ).getValue() );
- // 輪作年限BASE.
- mngSheet.getRange( dataIdx, MngListCropRotX ).setValue(
- GetDataToSubject( dataSheet, defineSheet, dataID, DefineCropRotResultX ) );
- // 輪作年限残り.
- mngSheet.getRange( dataIdx, MngListCropRotRestX ).setValue(
- GetDataToSubject( dataSheet, defineSheet, dataID, DefineCropRotResultX ) );
(別途IDをつけたい場合はdataシートを改造)
その後IDを使用し必要なデータを取り出しています。
64~77行目
このツールでは「カラ期間」を計算しています。
- // カラ期間.
- if ( dataIdx !== MngListStartY ) {
- // 1個前の作業終了週をget.
- num = mngSheet.getRange( (dataIdx - 1), MngListWorkEndWeekX ).getValue();
- // 選択した作物の作業開始週と比較.
- if ( num < tmp ) {
- // カラ期間計算.
- num = tmp - num;
- } else {
- num = OneYearToWeeks + (tmp - num);
- }
- // カラ期間.
- mngSheet.getRange( dataIdx, MngListIntervalX ).setValue( num );
…勝手に命名してますので好きに呼んでやってください。
ここで言うカラ期間は選択した作物間の空きの期間(週数)です。
スケジュールの作成がしやすいように保持しています。
79~87行目
カラ期間の計算ののち、現在選択中の作物の輪作年限数の消化をしています。
- // 前の輪作年限を全部更新.
- num = num + dataSheet.getRange( dataID, DataCultivationPeriodResultX ).getValue(); // カラ期間+栽培期間(ざっくり).
- for ( var y = MngListStartY; y < dataIdx; ++y ) {
- tmp = mngSheet.getRange( y, MngListCropRotRestX ).getValue();
- if ( tmp === 0 ) { continue; }
- tmp = tmp - num;
- if ( tmp < 0 ) { tmp = 0; }
- mngSheet.getRange( y, MngListCropRotRestX ).setValue( tmp );
- }
コメントにも書かれていますが、(ざっくり)してます。
【解説】「スケジュール作成」ボタンの処理実装
126~179行目
このツールのキモと言っても過言ではない部分です。
- for ( var y = MngListStartY; y < dataEnd; ++y ) {
- // ID.
- ID = mngSheet.getRange( y, MngListIDX ).getValue();
- // 種まきか否か.
- isSeed = mngSheet.getRange( y, MngListIsSowingSeedX ).getValue();
- // 作業終了週.
- end = dataSheet.getRange( ID, DataCultivationPeriodEndX ).getValue();
- // 色.
- col = GetBGColorToSubject( defineSheet, mngSheet.getRange( y, MngListSubjectX ).getValue() );
- // 名前.
- name = mngSheet.getRange( y, MngListNameX ).getValue();
- if ( isSeed === true ) {
- // 種まき開始週.
- start = dataSheet.getRange( ID, DataSowingSeedResultX ).getValue();
- } else {
- // 定植開始週.
- start = dataSheet.getRange( ID, DataPlantingResultX ).getValue();
- }
- // 色塗り開始.
- if ( y !== MngListStartY ) {
- if ( index >= start ) {
- // 1年ずらす.
- ++year;
- // ~年目入力.
- DrawYear( newSheet, (year + 1) );
- }
- }
- index = start;
- // 名前入力.
- newSheet.getRange( (TmpDataStartY + year), (index + TmpDataStartX - 1) ).setValue( name );
- while ( true ) {
- // 終了チェック.
- if ( index === end ) { break; }
- // 色塗り.
- newSheet.getRange( (TmpDataStartY + year), (index + TmpDataStartX - 1) ).setBackground( col );
- ++index;
- if ( index > OneYearToWeeks ) {
- // 年数を増やす.
- ++year;
- // ~年目入力.
- DrawYear( newSheet, (year + 1) );
- index = 1;
- }
- }
- }
作業期間部分のみを色塗りしていきます。色は「define」シートのセルの背景色から取得しています。
【解説】「1つ消す」「全部消す」ボタンの処理実装
200~223行目
作物リストから1つ消す場合は残り輪作年限をもとに戻さないといけません。
- // 消してしまうカラ期間 + 栽培期間.
- var baseNum, tmp;
- var num =
- mngSheet.getRange( endY, MngListIntervalX ).getValue() +
- dataSheet.getRange( mngSheet.getRange( endY, MngListIDX ).getValue(), DataCultivationPeriodResultX ).getValue();
- RangeClear( mngSheet, MngListIDX, endY, 10, 1 );
- // 輪作年限を再設定.
- for ( var y = MngListStartY; y < endY; ++y ) {
- baseNum = mngSheet.getRange( y, MngListCropRotX ).getValue();
- if ( baseNum === 0 ) { continue; }// 輪作年限がもともとない作物はスキップ.
- tmp = mngSheet.getRange( y, MngListCropRotRestX ).getValue();
- tmp = tmp + num;
- // base以上にならないようにする.
- if ( tmp > baseNum ) {
- tmp = baseNum;
- }
- mngSheet.getRange( y, MngListCropRotRestX ).setValue( tmp );
- }
改善点など
ソースを見直して、軽くできそうな箇所は軽くしたいですね(;'∀')ざっくりスケジュールなので、リアルベースでツールを考えてみる?
スケジュールを作成する時の文字色も「define」シートから引っ張っても良いと思います。
…などなど、色々手を加えられそうな部分は山ほどありそうです。
これで一旦完成という事になります!長丁場お疲れ様です。
こんな感じでプログラムと農業、色々とできそうな気がして、考えるだけでワクワクしませんか?(`・ω・´)ノ
私だけか…?