見出し画像

【GAS】大文字TRUE/FALSEなのか小文字true/falseなのか、型がstringなのかbooleanなのか問題。データ取得の方法によってデータ型が違う。

ノンプロ研Slackで盛り上がっていたネタを拝借して、自分の勉強のためにnoteにしてみます。真偽値も奥が深い。急いで書いたので抜け漏れあったらご指摘ください!

概要

シートのチェックボックスの値を取得するときに、
const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues(); したときと、トリガーで e.value した時だと値の型が違う。
そのために厳密等価演算子 (===)で事故りそうという話。

予約語

https://wa3.i-3-i.info/word190.html


検証

図1 スプレッドシードを用意して、チェックボックスを作ります。
図2 チェックが入っていなければFALSEになっています。
図3 チェックが入っていればTRUEになっています。
図4 コンテナバインドのスクリプトを作成します。初回にAppsScriptをクリックすると、ページが開かないことがよくあります。再読み込みすればオッケー。
function myFunction() {

  const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  // console.log({values})

  values.forEach(record => {
    console.log('record[0]: ', record[0]);
    console.log('record[0] === true: ', record[0] === true);
    console.log('record[0] === "true": ', record[0] === 'true');
    console.log('record[0] === "TRUE": ', record[0] === 'TRUE');
    console.log('typeof record[0]: ', typeof record[0]);
  });

}
図5 コードを書く。


図3 の この状態でコードを走らせると…
図6 実行ログはこうなる。


ここで、更に、トリガーで e.value した時の値も検証してみます。

図7 こんな感じのコードを書く。
図8 編集時に移動するようインストラーブルトリガを仕込む。
図9 シートで二つ目のチェックボックスをポチっとする。
図10 実行数のところでログを確認する。

今度は TRUEで取れている。型はstringだ。なんで?

コードの解説

コード

function myFunction() {

  const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  // console.log({values})

  values.forEach(record => {
    console.log('record[0]: ', record[0]);
    console.log('record[0] === true: ', record[0] === true);
    console.log('record[0] === "true": ', record[0] === 'true');
    console.log('record[0] === "TRUE": ', record[0] === 'TRUE');
    console.log('typeof record[0]: ', typeof record[0]);
  });

}

値の取得

まず1行目。

const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();

これで、データをごそっと取得しています。
下図のようにconsole.log({values}) で確かめるとわかりやすい。

図11 console.log({values}) の表示
図12 元のシートの状態

A1、A2、A3セルの情報を二次元配列で取得しています。
ここで注意したいのは、シート上では大文字のTRUE/FALSEですが、ログ結果では小文字のtrue/falseになっています。なんで?

各classやMethodはリファレンスを読むとたのしい。

SpreadsheetApp

getActiveSheet

getDataRange

getValues

https://developers.google.com/apps-script/reference/spreadsheet/range?hl=en#getvalues

forEachメソッドでログ出力

2行目以降。

function myFunction() {

  const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  // console.log({values})

  values.forEach(record => {
    console.log('record[0]: ', record[0]);
    console.log('record[0] === true: ', record[0] === true);
    console.log('record[0] === "true": ', record[0] === 'true');
    console.log('record[0] === "TRUE": ', record[0] === 'TRUE');
    console.log('typeof record[0]: ', typeof record[0]);
  });

}

forEachメソッドを使っています。反復メソッドってやつですね。

今回はA1、A2、A3セルの情報を二次元配列で取得しています。
それぞれに対して、4つのconsole.logを表示してくれるというわけです。

record は横一行分のデータの塊を意味します。今回は一行につき1列分しかデータないけど。

図13 record



等価演算子

== 左辺と右辺が等しければtrue
===  左辺と右辺がデータ型も含めて正しければtrue


10 == 10 //true
10 == 11 //false

10 === 10 //true
10 === '10' //false

ログの解説

図14 const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues(); のログ



まず、ここで注目したいのは、図14 const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues(); のログの2~5番目です。
A1セルの値について、シート上の値を確認すると大文字のTRUEとなっています。

しかし、A1セルの値について、
record[0] === "TRUE" とするとfalseになる。混乱するなこれ。
typeofで判定した型はbooleanです。

次に、イベントオブジェクトから取得してきた場合のログを見てみます。

図15 イベントオブジェクトから取得してきた場合のログ

今度は 大文字のTRUEが取れています。型はstringです。


というわけで、この辺のところを意識せずにうっかり、
hoge === ture
hoge === "true";
hoge === "TRUE";
なんて書いてると思わぬエラーになるかもしれません。
というか、booleanで判定するなら、文字列で判定させちゃダメだよねという話もある。

true/false は予約語(既に役割が決まっている単語)だから、好きに使わないでね、ということか。

https://wa3.i-3-i.info/word190.html


↓なんかまた新たなのも出てきた…


はー、今日はこんなとこで。

#ノンプロ研
#GAS
#データ型
#真偽値
#true
#false
#string
#boolean

いただいたサポートで、書籍代や勉強費用にしたり、美味しいもの食べたりします!