この記事のシリーズを読むことで、アニメHUNTER×HUNTER(ハンターハンター)を通してGAS(Google Apps Script)の最初の一歩が学べます。
この記事では、
・GASによるIF分岐とループでヒソカと同じ念系統か調べる
・配列で処理時間を短縮
・最後の行をgetLastRow()で求める
SpreadSheetApp→アクティブシート→アクティブセルと階層を辿ることによって処理時間がかかってしまうことを空の配列を用意することで解決する方法を掲載しています。
GASでは配列の扱いがとても重要になります。
ますは、前回(episode3)の復習をします。
・セルA1からB4にキャラクター名を入力する関数と消去する関数を作り、それぞれをボタンに登録しました。
//アクティブなスプレッドシートを選択するグローバル領域
const ss=SpreadsheetApp.getActiveSheet();
//スプレッドシートにキャラクターの名前と念系統の入った配列を出力する
function nenArray(){
//二次元配列hhにキャラクターの名前と念系統を格納
const hh = [
['ゴン','強化系'],
['キルア','変化系'],
['クラピカ','具現化系'],
['レオリオ','放出系']
];
//配列hhをログに出力
console.log(hh);
//行の長さを調べる
console.log(hh.length);
//列の長さを調べる
console.log(hh[0].length);
//二次元配列hhを格納するために、スプレッドシートの4行2列を確保して出力する
ss.getRange(1,1,hh.length,hh[0].length).setValues(hh);
}
//出力した配列を消去する
function myClear() {
//出力した配列をgetDataRangeを使って取得して消去する
ss.getDataRange().clear();
}
実行するとこの様になっていると思います。
ヒソカの念は「変化系」でキルアと一緒です。
今回はIF文を使って、ゴンからレオリオまでのキャラの念が、ヒソカと同じ変化系かどうか調べます。
ゴンは「強化系」なので「変化系」とは異なる為、条件が当てはまらないelseへと分岐します。
ゴンの念が入力されているセル「B1」は「1行目の2列目」ですので、(行,列)で書くと(1,2)と書くことも出来ます。
処理はelseになる為、隣のセルである「C1 (1,3)」には「XXX」と入力されます。
//アクティブなスプレッドシートを選択するグローバル領域(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();
//【ゴン】がヒソカと同じ念系統か判定する関数
function Hisoka() {
let nen = ss.getRange(1,2).getValue(); //ゴンの念を取得
console.log(nen);
//【ゴン】の念はヒソカと同じ「変化系」か?
if(nen=='変化系'){
ss.getRange(1,3).setValue('ヒソカと一緒');
}else{
ss.getRange(1,3).setValue('XXX'); //違うからこっちに分岐
}
}
ログ出力です。
ゴンの念系統「強化系」が出力されました。
スプレッドシートです。
C1に「XXX」と入りました。
次に、「キルア」を調べます。
キルアは「変化系」なので、「ヒソカ」と同じという条件が当てはまり「ヒソカと一緒」と表示されます。
//アクティブなスプレッドシートを選択するグローバル領域(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();
//【キルア】がヒソカと同じ念系統か判定する関数
function Hisoka() {
let nen = ss.getRange(2,2).getValue(); //キルアの念を取得
console.log(nen);
//【キルア】の念はヒソカと同じ「変化系」か?
if(nen=='変化系'){
ss.getRange(2,3).setValue('ヒソカと一緒'); //同じだからこっちに分岐
}else{
ss.getRange(2,3).setValue('XXX');
}
}
ログ出力です。
スプレッドシートです。
キルアの念はヒソカと同じなので、セルC2に「ヒソカと一緒」と入力されました。
次に、「クラピカ」を調べます。
クラピカは「具現化系」なので、「変化系」とは異なる為、条件が当てはまらないelseへと分岐します。
//アクティブなスプレッドシートを選択するグローバル領域(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();
//【クラピカ】がヒソカと同じ念系統か判定する関数
function Hisoka() {
let nen = ss.getRange(3,2).getValue(); //クラピカの念を取得
console.log(nen);
//【クラピカ】の念はヒソカと同じ「変化系」か?
if(nen=='変化系'){
ss.getRange(3,3).setValue('ヒソカと一緒');
}else{
ss.getRange(3,3).setValue('XXX'); //違うからこっちに分岐
}
}
ログ出力です。
スプレッドシートです。
ヒソカとは念が異なるので、C3に「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'); //違うからこっちに分岐
}
}
ログ出力です。
レオリオの「放出系」が出力されました。
スプレッドシートではC4に「XXX」と出力してelseの処理を実行しました。
ここまでで、「なんだか同じような処理をしていて、それで一部だけを変更している」と言う感覚になられたと思います。
上記のコードで「i」の部分のみを変えています。
そこで、ゴンからレオリオまでを繰り返して調べられる、Forによるループを使います。
getRange(i,2)getValue(); //キャラの念を取得
getRange(i,3)setValue(‘ヒソカと同じか違うか’)
実はここまでの記事で、ループのトレースを行えておりました。
追加としては、
ゴン・・・i=1
キルア・・・i=2
クラピカ・・・i=3
レオリオ・・・i=4
と、変数が出てくるぐらいです。
なぜ「i」なのか、それは、ループで慣習的に使う変数として、「i、j、k」がよく使われるからです。
このことについては、「なぜ、新人つぶしのトンパさんは、トンパさんという名前なのか」と突き詰めてしまうことの様なものなので、ループではiとかを使うんだな、程度に捉えておりましたが、やはり気になって調べた所、分かりやすい記事を見つけました。
「i, j, k」ってなに?知っておきたいfor文の変数名の由来
ゴン〜レオリオまでメンバーは4人ですので、その人数を調べるために、変数Nに「getLastRow()」(最後の行)を調べて格納します。
最後の行…getLastRow();
以上を踏まえてループとIFを使ったコードを書くと、下記の様になります。
//アクティブなスプレッドシートを選択するグローバル領域(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();
//【メンバー】がヒソカと同じ念系統か判定する関数
function Hisoka() {
const N = ss.getLastRow(); //人数は変数Nに格納。この場合は4人
console.log(N);
for(i=1;i<=N;i++){
let nen = ss.getRange(i,2).getValue(); //メンバーの念を取得
console.log(nen);
//【メンバー】の念はヒソカと同じ「変化系」か?
if(nen=='変化系'){
ss.getRange(i,3).setValue('ヒソカと一緒'); //キルアの場合
}else{
ss.getRange(i,3).setValue('XXX'); //キルア以外
}
}
}
ログ出力です。
スプレッドシートには同様に出力されております。
この「Hisoka」をボタンの「スクリプトを割り当て」でボタンに登録します。
ボタンを右クリックして3点リーダーから登録します。
また、下記のコードで、ヒソカと念が同じかどうか調べた範囲の判定結果を削除します。
//ヒソカチェックのクリア
function HisokaClear(){
//行数を取得して変数Nに人数を格納
const N=ss.getLastRow();
ss.getRange(1,3,N).clear();
}
一旦ここまでのコードをまとめます。
人数の行数をは判定もクリアも同じ4人でNですので、グローバル領域に移動しました。
//アクティブなスプレッドシートを選択するグローバル領域(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();
//行数(人数)を取得する
const N=ss.getLastRow();
// console.log(N); 確認済みなのでコメントアウトしました。
//【メンバー】がヒソカと同じ念系統か判定する関数
function Hisoka() {
for(i=1;i<=N;i++){
let nen = ss.getRange(i,2).getValue(); //メンバーの念を取得
// console.log(nen); 確認済みなのでコメントアウトしました。
//【メンバー】の念はヒソカと同じ「変化系」か?
if(nen=='変化系'){
ss.getRange(i,3).setValue('ヒソカと一緒'); //キルアの場合
}else{
ss.getRange(i,3).setValue('XXX'); //キルア以外
}
}
}
//ヒソカチェックのクリア
function HisokaClear(){
ss.getRange(1,3,N).clear();
}
紫のボタン「ヒソカチェック」に関数「Hisoka」を、灰色のボタン「ヒソ消し」に関数「HisokaClear」それぞれスクリプトを割り当てます。
これで、ボタンを使って、判定したり消したりが出来る様になりました。
現在、ヒソ消しを押して、判定の列は削除してあります。
このままでも良いのですが、GASでループを使う場合、1回1回SpreadsheetAppからアクティブシートを辿ってしまうので処理に時間がかかってしまいます。
そこで、一旦B列4行分の各メンバーの念系統を配列arrayに格納します。
配列arrayには[[‘強化系’],[‘変化系’],[‘具現化系’],[‘放出系’]]が入ります。
また、そのメンバーの念系統がヒソカの変化系と等しいかどうかの判定結果を格納する配列judgeを用意します。
配列arrayには[[‘XXX’],[‘ヒソカと一緒’],[‘XXX’],[‘XXX’]]が入ります。
それぞれの空の配列を用意しております。
//【メンバー】の念を格納する配列を宣言
let array=[];
//変化系と等しいか判定結果を入れる配列
let judge=[];
配列arrayを使って、念系統がヒソカと同じ変化系かどうか調べて、その判定結果を配列judgeに格納する処理にループを用います。
また、judgeに格納するときにpushを使います。
この配列を使うことによって、スプレッドシートからアクティブシートに階層を辿って行く処理時間を短縮できます。
ここまでの処理について、ログ出力のところまでのコードを掲載致しました。
配列は0から始まるので、ループの条件部分を修正しました。
i=0、i<Nと変更してあります。
また、配列judgeに入れる際、スプレッドシートに出力するのに二次元配列の形にするので、と[ ]を付けて配列に追加しております。
judge.push([‘ヒソカと一緒’]) → ifでキルアの念系統の場合
judge.push([‘XXX’]) → elseでキルア以外のメンバーの念系統の場合
その部分のコードの抜粋です。
//【メンバー】の念はヒソカと同じ「変化系」か?
if(array[[i]]=='変化系'){
judge.push(['ヒソカと一緒']); //キルアの場合
}else{
judge.push(['XXX']); //キルア以外
}
ここまでのログ出力までのコードです。
//アクティブなスプレッドシートを選択するグローバル領域(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();
//行数(人数)を取得する
const N=ss.getLastRow();
//【メンバー】がヒソカと同じ念系統か判定する関数
function Hisoka() {
let array= [];
let judge = [];
//B列の各メンバーの念を配列arrayに格納
array=ss.getRange(1,2,N).getValues();
console.log(array);
for(i=0;i<N;i++){
//【メンバー】の念はヒソカと同じ「変化系」か?
if(array[[i]]=='変化系'){
judge.push(['ヒソカと一緒']); //キルアの場合
}else{
judge.push(['XXX']); //キルア以外
}
}
console.log(judge);
}
配列arrayとヒソカの念との比較のログを出力しました。
【配列array】
【配列judge】
この後、配列judgeをスプレッドシートのC列に4行分書き出します。
関数Hisokaにこの2行を加えたのみです。
//スプレッドシートC列4行分に判定結果の入った配列judgeごと入力する。
ss.getRange(1,3,N).setValues(judge);
ここまでのコードをまとめました。
//アクティブなスプレッドシートを選択するグローバル領域(共通の処理)
const ss=SpreadsheetApp.getActiveSheet();
//行数(人数)を取得する
const N=ss.getLastRow();
//【メンバー】がヒソカと同じ念系統か判定する関数
function Hisoka() {
let array= [];
let judge = [];
//B列の各メンバーの念を配列arrayに格納
array=ss.getRange(1,2,N).getValues();
console.log(array);
for(i=0;i<N;i++){
//【メンバー】の念はヒソカと同じ「変化系」か?
if(array[[i]]=='変化系'){
judge.push(['ヒソカと一緒']); //キルアの場合
}else{
judge.push(['XXX']); //キルア以外
}
}
console.log(judge);
//スプレッドシートC列4行分に判定結果の入った配列judgeごと入力する。
ss.getRange(1,3,N).setValues(judge);
}
//ヒソカチェックのクリア
function HisokaClear(){
ss.getRange(1,3,N).clear();
}
お疲れ様でした。ブレイクタイムPhotoは、
横浜の夜景です。
思わずこの歌を歌いたくなりました。
←episode3 episode5→
←GAS自作サンプル集へ戻る
■ 関連記事 ■
HUNTER×HUNTERのGAS自作サンプル集のページに戻る
初めてのGASに戻る
自己紹介