episode4 GASの「ヒソカチェックで、IFとループを一気に学ぶ」(Hunter×Hunterで覚えるGoogle Apps Script)

GAS(Google Apps Script)をアニメ、ハンターハンターを通して入門の入門から学べる記事を掲載しております。

この記事を通して、GASによるIF分岐とループ、SpreadSheetApp→アクティブシート→アクティブセルと階層を辿ることによって処理時間がかかってしまうことを空の配列を用意することで解決する方法を掲載しています。
GASでは配列の扱いがとても重要になります。

サイトマップはこちらから

GASサンプル集に戻る
メインメニューに戻る
これからプログラミングを始める方へ
基本情報技術者へ
自己紹介

←GAS自作サンプルへ戻る

前回(episode3)の復習をします。

・セルA1からB4にキャラクター名を入力する関数と消去する関数を作り、それぞれをボタンに登録しました。

//アクティブなスプレッドシートを選択するグローバル(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();

//キャラクターの名前と念の系統を入力する関数
function mySet(){

  //二次元配列hhにキャラクターの名前と念系統を格納
  let hh=[
    ['ゴン','強化系'],
    ['キルア','変化系'],
    ['クラピカ','具現化系'],
    ['レオリオ','放出系'],
    ];

  //二次元配列hhにデータが格納されたことをログ出力で確認
  console.log(hh);

  //hhを格納するために、スプレッドシートの4行2列を確保して出力する
  ss.getRange(1,1,hh.length,hh[0].length).setValues(hh);

}

//入力範囲を消去する関数
function myClear(){

  hh=ss.getDataRange();
  hh.clear();

}

今回はIF文を使って、ゴンからレオリオまでのキャラの念が、ヒソカと同じ変化系かどうか調べます。

ゴンは「強化系」なので「変化系」とは異なる為、条件が当てはまらないelseへと分岐します。

念が入力されているセルA2は(1,2)と洗わせます。
elseでは、「XXX」と表記されます。

//アクティブなスプレッドシートを選択するグローバル(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();


//【ゴン】がヒソカと同じ念系統か判定
function Hisoka(){
  let nen=ss.getRange(1,2).getValue();  //ゴンの念を取得
  
  //【ゴン】の念はヒソカと同じ「変化系」か?
  if(nen=='変化系'){                      
    ss.getRange(1,3).setValue('ヒソカと一緒');
  }else{
    ss.getRange(1,3).setValue('XXX'); //違うからこっちに分岐
  }
}

次に、「キルア」を調べます。

キルアは「変化系」なので、「ヒソカ」と同じという条件が当てはまり「ヒソカと一緒」と表示されます。

//アクティブなスプレッドシートを選択するグローバル(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();


//【キルア】がヒソカと同じ念系統か判定
function Hisoka(){
  let nen=ss.getRange(2,2).getValue();  //キルアの念を取得
  
  //【キルア】の念はヒソカと同じ「変化系」か?
  if(nen=='変化系'){                      
    ss.getRange(2,3).setValue('ヒソカと一緒');//同じだからこっちに分岐
    }else{
    ss.getRange(2,3).setValue('XXX'); 
  }
}

次に、「クラピカ」を調べます。

クラピカは「具現化系」なので、「変化系」とは異なる為、条件が当てはまらないelseへと分岐します。

//アクティブなスプレッドシートを選択するグローバル(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();


//【クラピカ】がヒソカと同じ念系統か判定
function Hisoka(){
  let nen=ss.getRange(3,2).getValue();  //クラピカの念を取得
  
  //【クラピカ】の念はヒソカと同じ「変化系」か?
  if(nen=='変化系'){                      
    ss.getRange(3,3).setValue('ヒソカと一緒');
    }else{
    ss.getRange(3,3).setValue('XXX'); //違うからこっちに分岐
  }
}

最後に、「レオリオ」を調べます。
レオリオは「放出系」なので、「変化系」とは異なる為、条件が当てはまらないelseへと分岐します。

//アクティブなスプレッドシートを選択するグローバル(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();


//【レオリオ】がヒソカと同じ念系統か判定
function Hisoka(){
  let nen=ss.getRange(4,2).getValue();  //レオリオの念を取得
  
  //【レオリオ】の念はヒソカと同じ「変化系」か?
  if(nen=='変化系'){                      
    ss.getRange(4,3).setValue('ヒソカと一緒');
    }else{
    ss.getRange(4,3).setValue('XXX'); //違うからこっちに分岐
  }
}

もうお気づきですよね。

getRange(i,2)getValue(); //キャラの念を取得 
getRange(i,3)setValue(‘ヒソカと同じか違うか’)      

この、「i」の部分のみを変えています。
ただ、コードをいちいち変えるの面倒なので、Forによるループを使います。

実は、これまでで、ループのトレースができちゃっていました。

追加としては、

ゴン・・・i=1
キルア・・・i=2
クラピカ・・・i=3
レオリオ・・・i=4

と、変数が出てくるぐらいです。

なぜ「i」なのか、それは、ループで慣習的に使う変数として、「i、j、k」がよく使われるからです。このことについては、「なぜ、新人つぶしのトンパさんは、トンパさんという名前なのか」と突き詰めてしまうことのようなものなので、ループではiとかを使うんだな、程度におさえておいて大丈夫です。

また、メンバーは4人なので、その人数を調べるために、変数Nに「LastRow」(最後の行)を調べます。

以上を踏まえてコードを書くと、こうなります。

//アクティブなスプレッドシートを選択するグローバル(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();


//【メンバー】がヒソカと同じ念系統か判定
function Hisoka(){

  //行数を取得して、変数Nにメンバーの人数を格納
  let N=ss.getLastRow();

  //ループを使って各キャラクターの念が「変化系」と等しいか判定して結果入力
  for(let i=1;i<=N;i++){
    let nen=ss.getRange(i,2).getValue();  //【メンバー】の念を取得
  
    //【メンバー】の念はヒソカと同じ「変化系」か?
    if(nen=='変化系'){                      
      ss.getRange(i,3).setValue('ヒソカと一緒');
    }else{
      ss.getRange(i,3).setValue('XXX'); //違うからこっちに分岐
    }

  }  
}

この「Hisoka」をボタンの「スクリプトを割り当て」でボタンに登録します。
また、下記のコードで、判定結果の範囲を削除します。

//ヒソカチェッククリア
function HisoClear(){

  //行数を取得して、変数Nに人数を格納
  let N=ss.getLastRow();
  ss.getRange(1,3,N).clear();
}

一旦ここまでのコードをまとめます。

//アクティブなスプレッドシートを選択するグローバル(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();


//【メンバー】がヒソカと同じ念系統か判定
function Hisoka(){

  //行数を取得して、変数Nにメンバーの人数を格納
  let N=ss.getLastRow();

  //ループを使って各キャラクターの念が「変化系」と等しいか判定して結果入力
  for(let i=1;i<=N;i++){
    let nen=ss.getRange(i,2).getValue();  //【メンバー】の念を取得
  
    //【メンバー】の念はヒソカと同じ「変化系」か?
    if(nen=='変化系'){                      
      ss.getRange(i,3).setValue('ヒソカと一緒');
    }else{
      ss.getRange(i,3).setValue('XXX'); //違うからこっちに分岐
    }

  }  
}


//ヒソカチェッククリア
function HisoClear(){

  //行数を取得して、変数Nに人数を格納
  let N=ss.getLastRow();
  ss.getRange(1,3,N).clear();
}

これで、ボタンを使って、判定したり消したりが出来る様になりました。
このままでも良いのですが、GASでループを使う場合、1回1回SpreadsheetAppからアクティブシートを辿ってしまうので処理に時間がかかってしまいます。

そこで、一旦配列arrayにメンバーの念系統を格納します。
また、メンバーの念系統がヒソカの変化系と等しいかどうかの判定結果を格納する配列judgeを用意します。

  //【メンバー】の念を格納する配列を宣言
  let array=[];

  //変化系と等しいか判定結果を入れる配列
  let judge=[];

  //念を配列に格納
  array=ss.getRange(1,2,N).getValues();

配列arrayを使って、念系統がヒソカと同じ変化系かどうか調べて、その判定結果を配列judgeに格納するループです。
これ(配列)を使うことによって、スプレッドシートからアクティブシートに階層を辿って行く処理時間を短縮できます。

配列arrayをログ出力しました。


この配列arrayは、4行1列の二次元配列です。
なので、array[0][0]=ゴンの「強化系」,array[1][0]=キルアの「変化系」,array[2][0]=クラピカの「具現化系」,array[3][0]=レオリオの「放出系」にアクセスして、それがヒソカの「変化系」と等しいかどうか調べてその結果を配列judgeに格納しています。

//ループを使って配列の中身が「変化系」と等しいか調べて判定結果を二次元配列として追加
  for(let i=0;i<N;i++){
    if(array[i][0]=='変化系'){
      judge.push('ヒソカと一緒');
    }else{
      judge.push('XXX');
    }
  }

配列judgeのログはこちらです。

この判定結果の配列judgeをループでスプレッドシートに格納します。

//配列judgeをスプレッドシートに出力
  for(let i=1;i<=N;i++){
    ss.getRange(i,3,1).setValue(judge[i-1]);
  }

同様にスプレッドシートに書き込めました。
ここまでのコードをまとめます。

//アクティブなスプレッドシートを選択するグローバル(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();


//【メンバー】がヒソカと同じ念系統か判定
function Hisoka(){

  //行数を取得して、変数Nにメンバーの人数を格納
  let N=ss.getLastRow();

  //【メンバー】の念を格納する配列を宣言
  let array=[];

  //変化系と等しいか判定結果を入れる配列
  let judge=[];

  //念を配列に格納
  array=ss.getRange(1,2,N).getValues();

  //arrayに念が格納されたことをログに出力して確認
  console.log(array);

  //ループを使って配列の中身が「変化系」と等しいか調べて判定結果を二次元配列として追加
  for(let i=0;i<N;i++){
    if(array[i][0]=='変化系'){
      judge.push('ヒソカと一緒');
    }else{
      judge.push('XXX');
    }
  }

  //判定結果が二次元配列として格納されたことをログで確認
  console.log(judge);

  
  //配列judgeをスプレッドシートに出力
  for(let i=1;i<=N;i++){
    ss.getRange(i,3,1).setValue(judge[i-1]);
  }
}


//ヒソカチェッククリア
function HisoClear(){

  //行数を取得して、変数Nに人数を格納
  let N=ss.getLastRow();
  ss.getRange(1,3,N).clear();
}

ご精読ありがとうございました。

サイトマップはこちらから

GASサンプル集に戻る
メインメニューに戻る
これからプログラミングを始める方へ
基本情報技術者へ
自己紹介

■参考文献の紹介■
初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本を通してじっくり学べます。

←episode3               episode5→

←GAS自作サンプルへ戻る