前回の記事(スプレッドシートの関数だけでリンク切れ・ページ存在チェックを行う方法)では、標準関数の IMPORTXML と MAP 関数を組み合わせて数式だけでURLの存在確認を行う方法を解説しました。
しかし、数式を使った判定には「404エラーページでもタイトルがあると『あり』と誤判定される」「EUC-JPなど古い文字コードのサイトで文字化け・パースエラーになり実在するのに『なし』になる」「数式だとシート編集のたびに通信が走って動作が激重になる」という実務上の重大な弱点があります。
そこで今回は、これらの課題を根本から解決し、「スプレッドシートのメニューから1クリックでB列のURLを検査し、C列に『あり/なし』を色分けして一括書き込みする」 Google Apps Script(GAS)の実装手順を解説します。
開くたびに自動通信を走らせるのではなく、「普段はシートを最速で軽く開ける状態を保ち、チェックしたい時だけメニューから手動実行する」という、実務で最も扱いやすく安全な運用スタイルです。
標準関数の限界とGASを採用すべき理由
スプレッドシートでURLのリンク切れを調べる際、なぜ数式ではなくGASを使うべきなのか、両者の仕組みの違いを比較してみましょう。

標準関数(IMPORTXML方式)の主な弱点
数式で運用した際に起きる4大トラブル
- 404ページのタイトル誤判定: Webサーバーによっては、ページが存在しない(404 Not Found)場合でも「404 Not Found」や「お探しのページは見つかりませんでした」といったタイトルのHTMLを返します。IMPORTXMLはタイトルタグが取得できると正常と判断するため、リンク切れなのに「あり」と誤判定されてしまいます。
- 日本語文字コード(EUC-JP等)によるパースエラー: 古いWebサイトなど文字コードがEUC-JPやShift_JISで書かれている場合、XML解析エンジンが文字化けや構文エラーを起こし、正常に存在するページであっても「なし」と誤判定されます。
- シート編集のたびに再計算が走り激重になる: セル数式の場合、シートを開き直したり別のセルを編集するたびにすべてのURLへのアクセスが再実行されます。リストが増えるほどシートがフリーズし、開くたびに結果が変わるなど動作が極めて不安定になります。
- PDFや画像URLの判定不可: HTMLではないファイルURLにはタイトルタグが存在しないため、ファイルが正常に存在していても必ずエラーになります。
GAS(UrlFetchApp方式)の決定的な強み
一方、GASの UrlFetchApp.fetch メソッドを使用すると、これらの問題がすべて解決されます。
- 生(Raw)のHTTPステータスコードを直接取得: タイトルタグの有無ではなく、Webサーバーが返したレスポンスコード(200番台、404など)を直接判定できるため、404エラーページも確実に検出できます。
- 判定結果を「値(テキスト)」としてセルに書き込む: 数式ではなく「あり」「なし」という文字列をセルに固定するため、他のセルを編集しても不必要な外部通信が一切発生せず、シートが常に軽量・高速に動作します。
- PDFや画像などのファイルURLも正確に判定可能: ファイルであってもサーバーから200番台が返れば正常と判定できます。
メニューから1クリックで一括判定するスマートな運用設計
実務において最も使いやすいのは、「普段はシートを軽く開ける状態を保ち、確認したいタイミングで上部メニューからポチッと実行する」という運用です。
シートを開いた時に自動通信が走る設定にすると、少し内容を確認したいだけの時でも待たされてしまいます。
そのため、本スクリプトでは onOpen() でスプレッドシート上部に「リンクチェック」という独自メニューを追加するだけに留め、通信負荷ゼロで瞬時にシートが開くように設計しています。

コピペで使える完成版スクリプトコード
以下のコードをコピーして、スプレッドシートのApps Scriptエディタに貼り付けて使用します。
B列のURLを検査し、C2セルから下方向に判定結果(あり/なし)を書き込み、見やすいように緑と赤でセルを色分けします。
/*
* スプレッドシート専用:リンク切れ一括判定スクリプト(手動実行版)
* B列のURLを検査し、C2セルから下方向に「あり/なし」を一括書き込みします
*/
// スプレッドシートを開いた時にメニューを追加(通信は走らないため最速で開きます)
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('リンクチェック')
.addItem('今すぐB列のリンクを一括判定する', 'checkCurrentSheet')
.addToUi();
}
// メニューから実行されるメイン処理
function checkCurrentSheet() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
// 現在開いているアクティブシートを取得
const sheet = ss.getActiveSheet();
const lastRow = sheet.getLastRow();
if (lastRow < 2) {
ss.toast('B列にデータが見つかりません', '通知');
return;
}
// B2から最終行までの値を取得
const range = sheet.getRange(2, 2, lastRow - 1, 1);
const values = range.getValues();
// B列の実データがある最終行を特定(余分な空行を除外)
let actualCount = 0;
for (let i = values.length - 1; i >= 0; i--) {
if (String(values[i][0] || '').trim() !== '') {
actualCount = i + 1;
break;
}
}
if (actualCount === 0) {
ss.toast('B列にURLが見つかりません', '通知');
return;
}
ss.toast(actualCount + ' 件のリンクをチェック中...', '処理中', 2);
const results = [];
const backgrounds = [];
for (let i = 0; i < actualCount; i++) {
// 前後の全角・半角スペースや改行を自動トリム
const rawUrl = String(values[i][0] || '').trim();
if (!rawUrl || !rawUrl.toLowerCase().startsWith('http')) {
results.push(['なし']);
backgrounds.push(['#fef2f2']); // 薄い赤
continue;
}
try {
const response = UrlFetchApp.fetch(rawUrl, {
muteHttpExceptions: true,
followRedirects: true,
validateHttpsCertificates: false // SSL証明書エラーを回避
});
const code = response.getResponseCode();
if (code >= 200 && code < 300) {
results.push(['あり']);
backgrounds.push(['#f0fdf4']); // 薄い緑
} else {
results.push(['なし']);
backgrounds.push(['#fef2f2']); // 薄い赤
}
} catch (e) {
results.push(['なし']);
backgrounds.push(['#fef2f2']); // 薄い赤
}
}
// C2セルから一括書き込み
const targetRange = sheet.getRange(2, 3, results.length, 1);
targetRange.setValues(results);
targetRange.setBackgrounds(backgrounds);
// 画面の再描画を即座に強制実行(未反映を防止)
SpreadsheetApp.flush();
ss.toast('C列の更新が完了しました!(' + actualCount + ' 件)', '完了', 5);
}
Apps Scriptへの導入と実行手順
導入手順はわずか1分ほどで完了します。画像の流れに沿って設定してください。

エディタの起動とコードの保存
- 対象のスプレッドシートを開き、上部メニューの「拡張機能」>「Apps Script」をクリックします。
- エディタ画面に表示されている初期コード(
function myFunction() ...)を消去します。 - 上記の完成版スクリプトコードを貼り付けます。
- 上部の保存アイコン(フロッピーディスクのマーク)をクリックして保存します。
初回実行とアクセス権限の承認
スプレッドシートに戻ってブラウザを再読み込み(F5)すると、上部メニューに「リンクチェック」というメニューが追加されます。
初回実行時の「承認が必要です」の対応
メニューの「今すぐB列のリンクを一括判定する」をクリックすると、初回のみGoogleのセキュリティ認証画面が表示されます。
「続行」をクリック → 自身のアカウントを選択 → 左下の「詳細」をクリック →「〇〇(安全ではないページ)に移動」をクリック →「許可」を選択してください。これは自作スクリプトがスプレッドシートの編集と外部URLへの通信を行うために必須の正規の権限承認です。
一度承認すれば、次からはメニューをクリックするだけで、何十件あろうと数秒でチェックが完了し、C列が緑(あり)と赤(なし)に色分けされて最新化されます。
カスタム関数(=CHECK_URL)を避けるべき技術的理由
数式のように =CHECK_URL(B2) とセルに入力して使うのは、実務運用では避けるべきです。
- 「Service invoked too many times」制限の壁: カスタム関数はセル1つごとに個別のGASプロセスが起動します。Googleの短時間呼び出し制限に即座に達してしまい、途中で計算が停止してしまいます。
- 数式と同じ再計算フリーズの再発: カスタム関数もセル数式であるため、他のセルを編集するたびに全行でGASが起動し、シート全体がフリーズしてしまいます。
今回のように「メニューから必要な時だけ一括チェックし、値と背景色としてセルに書き込む」設計にすることで、シートを常に最速・最軽量に保ちながら、ストレスのない運用を実現できます。
まとめ(必要な時だけ判定してシートを軽く保つ)
URLリストの管理における2つのアプローチの使い分けは以下の通りです。
- 標準関数(IMPORTXML + MAP方式): 数十件程度の小規模なリストで、GASを使わず手軽に大まかな確認をしたい場合(EUC-JP文字コードや404ページのタイトル誤判定に注意)。
- GASメニュー実行方式: 404誤判定や文字コード問題を解消し、シートを軽く保ちながら必要なタイミングで1クリックで正確に最新化したい実務・本番運用。
リンク切れを放置すると訪問ユーザーの離脱を招くだけでなく、検索エンジンのクローラー効率を落としてSEOにもマイナスの影響を与えます。日々のWebサイト運用やURL管理に、ぜひこのスマートな自動化スクリプトを活用してください。
