GAS学習note:Day3 if文を極める(条件分岐・比較演算子・空セル判定)
はじめに
Day2ではセルの読み書きと for文での複数処理を学びました。
Day3のゴールは「if文を自在に書ける」こと。これができると、条件で処理を分ける=実務の自動化の核が作れます。
if文の基本形と比較演算子
if (条件) {
// 条件が true のとき実行
} else {
// それ以外のとき実行
}
よく使う比較演算子
=== 等しい(型も値も一致)※推奨
!== 等しくない
> / < / >= / <= 大小比較
✅ 基本は === を使う(== は型変換が起きてバグの元)
実践1:点数で「合格/要改善」を判定
スプレッドシートの A列:点数、B列:判定 とします(1行目は見出し)。
function judgeScore() {
const sheet = SpreadsheetApp.getActive().getActiveSheet();
const last = sheet.getLastRow();
for (let r = 2; r <= last; r++) {
const score = sheet.getRange(r, 1).getValue(); // A列
if (typeof score !== 'number') continue; // 数値以外はスキップ
if (score >= 80) {
sheet.getRange(r, 2).setValue('合格'); // B列
} else {
sheet.getRange(r, 2).setValue('要改善');
}
}
}
💡ポイント
見出しを避けるため r = 2 から開始
typeof score !== 'number' で安全にガード(空や文字列を弾く)

実践2:三段階評価(else if)
スプレッドシートの A列:点数、B列:判定、C列:評価 とします(1行目は見出し)
80点以上:A、60〜79:B、59以下:C
function gradeScore() {
const sh = SpreadsheetApp.getActive().getActiveSheet();
const last = sh.getLastRow();
for (let r = 2; r <= last; r++) {
const v = sh.getRange(r, 1).getValue();
if (typeof v !== 'number') { sh.getRange(r, 3).setValue('—'); continue; }
if (v >= 80) {
sh.getRange(r, 3).setValue('A');
} else if (v >= 60) {
sh.getRange(r, 3).setValue('B');
} else {
sh.getRange(r, 3).setValue('C');
}
}
}

実践3:複合条件(AND/OR/NOT)
&&(かつ)
||(または)
!(ではない)
例:在庫が10以下 かつ 発注済みでない行を警告
E列:在庫数、F列:発注済み(TRUE/FALSE)、G列:メモ
function stockAlert() {
const sh = SpreadsheetApp.getActive().getActiveSheet();
const last = sh.getLastRow();
for (let r = 2; r <= last; r++) {
const qty = Number(sh.getRange(r, 5).getValue()); // 在庫数
const ordered = sh.getRange(r, 6).getValue(); // チェックボックス(TRUE/FALSE)
const isOrdered = (ordered === true); // 論理値として扱う
if (qty <= 10 && !isOrdered) {
sh.getRange(r, 7).setValue('⚠ 補充要');
sh.getRange(r, 5, 1, 3).setBackground('#fff2cc');
} else {
// ★条件に当てはまらなければ、メモと背景色をリセット
sh.getRange(r, 7).setValue('');
sh.getRange(r, 5, 1, 3).setBackground(null);
}
}
}
💡F列の発注のセルはチェックボックス形式に変更

F列の発注のセルのチェックボックスにチェックを入れ、実行するとG列のメモの色付け、⚠ 補充要が消える。

空セル・文字列の“落とし穴”回避術
1) 空セル判定は === "" が安全
const v = sh.getRange(r, 1).getValue();
if (v === "") { /* 空セル */ }
if(!v){} は 0 も偽と判定してしまうので NG。
2) 数値に変換してから比べる
const raw = sh.getRange(r, 1).getValue(); // "100" のような文字列の可能性
const num = Number(raw);
if (Number.isNaN(num)) { /* 数値でない → スキップ */ }
if (num >= 80) { /* OK */ }
3) 文字列比較は 全角/半角・大文字小文字 に注意
const flag = String(sh.getRange(r, 2).getValue()).trim();
if (flag.toLowerCase() === 'ok') { /* … */ }
早期リターン(ガード節)で読みやすく
ネストを浅くしてバグを減らします。
function processRow(r) {
const sh = SpreadsheetApp.getActive().getActiveSheet();
const v = sh.getRange(r, 1).getValue();
// 前提を満たさないならすぐ返す
if (v === "" || typeof v !== 'number') return;
if (v >= 100) {
sh.getRange(r, 2).setValue('達成');
return;
}
sh.getRange(r, 2).setValue('未達');
}
よくあるエラー&対処(ミニ辞典)
== を使ってしまう → 予期せぬ型変換で判定ミス。=== を使う
空セルを !v で判定 → 0 も偽になる。v === "" で判定
文字列数値をそのまま比較 → "100" > 80 は true になるが混在は危険。Number() で揃える
見出し行まで処理 → for (let r = 2; …) のように2行目から
TRUE/FALSE の表記ゆれ → データをチェックボックス(TRUE/FALSE)にするか toLowerCase() で吸収
今日の仕上げ課題(コピペでOK)
課題1:売上ランク
I列:売上
J列:ランク(100,000以上=S / 50,000以上=A / それ以外=B)
function rankSales() {
const sh = SpreadsheetApp.getActive().getActiveSheet();
for (let r = 2; r <= sh.getLastRow(); r++) {
const num = Number(sh.getRange(r, 9).getValue());
if (Number.isNaN(num)) { sh.getRange(r, 10).setValue('—'); continue; }
if (num >= 100000) sh.getRange(r, 10).setValue('S');
else if (num >= 50000) sh.getRange(r, 10).setValue('A');
else sh.getRange(r, 10).setValue('B');
}
}

課題2:期限警告
L列:期限(日付)
M列:ステータス(空 or 済)
ルール:今日より前 & ステータス空ならN列に「期限切れ」+行を赤背景
function dueAlert() {
const sh = SpreadsheetApp.getActive().getActiveSheet();
const last = sh.getLastRow();
// 今日を0時にそろえる(今日スルー仕様)
const today = new Date();
today.setHours(0, 0, 0, 0);
const todayMs = today.getTime();
for (let r = 2; r <= last; r++) {
let due = sh.getRange(r, 12).getValue(); // L列:期限
const rawStatus = sh.getRange(r, 13).getValue(); // M列:ステータス(チェックボックス)
// ステータス判定:未チェック or 空文字 → 未処理
const isTodo = (rawStatus === false) || (String(rawStatus).trim() === "");
// 「済」にしている場合の互換(テキスト運用にも対応)
const isDone = (rawStatus === true) || (String(rawStatus).trim() === "済");
if (isDone) { // 完了は常にリセットしてスキップ
sh.getRange(r, 14).setValue("");
sh.getRange(r, 12, 1, 3).setBackground(null);
continue;
}
// 日付でなければスキップ(文字列でも new Date で変換を試す)
if (!(due instanceof Date)) {
due = new Date(due);
}
if (!(due instanceof Date) || isNaN(due)) {
// 変換不可ならクリアだけして次へ
sh.getRange(r, 14).setValue("");
sh.getRange(r, 12, 1, 3).setBackground(null);
continue;
}
// 期限も0時にそろえて数値比較
due.setHours(0, 0, 0, 0);
const dueMs = due.getTime();
if (isTodo && dueMs < todayMs) {
// 期限切れ:今日より前 & 未処理(未チェック/空)
sh.getRange(r, 14).setValue("期限切れ"); // N列
sh.getRange(r, 12, 1, 3).setBackground("#f4cccc"); // L〜N列 赤背景
} else {
// 条件外はリセット
sh.getRange(r, 14).setValue("");
sh.getRange(r, 12, 1, 3).setBackground(null);
}
}
}

まとめ
if / else if / else の基本と**比較演算子(=== 推奨)**を理解
空セル/数値/文字列の扱いを安全に
AND/OR/NOT で複合条件を表現
早期リターンで読みやすくバグを減らす
👉 Day4 は「for文 × if文で“実務ミニツール”を作る」。
実データを一括クリーニング&判定する実戦レシピを作ります。
