Googleスプレッドシートのセルにプレースホルダを表示する方法

に公開

知恵袋で要望を見つけたので実装してみた。


// =================================================================
// 定数設定エリア
// =================================================================

/**
 * @const {string} SHEET_NAME - 対象のシート名
 */
const SHEET_NAME = 'シート1'; // ここに対象のシート名を入力してください

/**
 * @const {string} TARGET_RANGE - プレースホルダーを適用する範囲 (A1表記)
 */
const TARGET_RANGE = 'A2:C10'; // ここに対象の範囲を入力してください

/**
 * @const {object.<string, string>} PLACEHOLDERS - プレースホルダーのテキストを列ごとに定義
 * 列番号をキー、プレースホルダーテキストを値として設定します。
 * 例: {1: 'お名前を入力', 2: 'メールアドレスを入力', 3: '電話番号を入力'}
 * → 1列目(A列)には'お名前を入力', 2列目(B列)には... と表示されます。
 */
const PLACEHOLDERS = {
  1: '(例)山田 太郎', // A列のプレースホルダー
  2: '(例)example@google.com', // B列のプレースホルダー
  3: '(例)090-1234-5678' // C列のプレースホルダー
};

/**
 * @const {string} PLACEHOLDER_FONT_COLOR - プレースホルダーの文字色
 */
const PLACEHOLDER_FONT_COLOR = '#888888'; // 薄いグレー

/**
 * @const {string} DEFAULT_FONT_COLOR - 通常入力時の文字色
 */
const DEFAULT_FONT_COLOR = '#000000'; // 黒

// =================================================================
// メイン処理
// =================================================================

/**
 * スプレッドシートが開かれたときに、初期状態でプレースホルダーを設定する関数です。
 * onOpenトリガーで実行されることを想定しています。
 */
function onOpen() {
  setInitialPlaceholders_();
}

/**
 * ユーザーがセルを編集したときに実行される単純トリガーです。
 * @param {object} e - Googleスプレッドシートの編集イベントオブジェクト
 */
function onEdit(e) {
  // イベントオブジェクトから必要な情報を取得
  const range = e.range;
  const sheet = range.getSheet();
  const editedRow = range.getRow();
  const editedCol = range.getColumn();
  const editedValue = e.value;

  // 編集されたシートが対象外、または編集範囲が対象外の場合は処理を終了
  if (sheet.getName() !== SHEET_NAME || !isTargetRange_(editedRow, editedCol)) {
    return;
  }

  // プレースホルダーを持っている列かチェック
  if (!PLACEHOLDERS.hasOwnProperty(editedCol)) {
    return;
  }

  // 編集後のセルが空になった場合(値を削除した場合)
  if (editedValue === undefined || editedValue === '') {
    // 再度プレースホルダーを設定
    range.setValue(PLACEHOLDERS[editedCol]);
    range.setFontColor(PLACEHOLDER_FONT_COLOR);
  } else {
    // 何か値が入力された場合
    // プレースホルダーが表示されている状態で入力された可能性があるため、文字色を通常に戻す
    range.setFontColor(DEFAULT_FONT_COLOR);
  }
}

// =================================================================
// ヘルパー関数 (内部処理用)
// =================================================================

/**
 * 指定されたシートの対象範囲に初期プレースホルダーを設定します。
 * @private
 */
function setInitialPlaceholders_() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
  if (!sheet) return; // 対象シートがなければ終了

  const targetRange = sheet.getRange(TARGET_RANGE);
  const values = targetRange.getValues();
  const fontColors = targetRange.getFontColors();

  // 範囲内の各セルをループ処理
  for (let i = 0; i < values.length; i++) {
    for (let j = 0; j < values[i].length; j++) {
      // セルの列番号を取得 (getRangeのインデックスは0から始まるため+1)
      const currentCol = targetRange.getColumn() + j;

      // その列に対応するプレースホルダーが定義されているかチェック
      if (PLACEHOLDERS.hasOwnProperty(currentCol)) {
        // セルが空の場合のみプレースホルダーを設定
        if (values[i][j] === '') {
          values[i][j] = PLACEHOLDERS[currentCol];
          fontColors[i][j] = PLACEHOLDER_FONT_COLOR;
        } else {
          // 既に値が入っている場合は通常の文字色にする
          fontColors[i][j] = DEFAULT_FONT_COLOR;
        }
      }
    }
  }

  // 高速化のため、値と色の設定を一度に行う
  targetRange.setValues(values);
  targetRange.setFontColors(fontColors);
}

/**
 * 指定された行と列が、定数で定義されたターゲット範囲内にあるかどうかを判定します。
 * @param {number} row - 判定する行番号
 * @param {number} col - 判定する列番号
 * @return {boolean} 範囲内であればtrue, そうでなければfalse
 * @private
 */
function isTargetRange_(row, col) {
  // A1表記から行・列番号を取得
  const range = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME).getRange(TARGET_RANGE);
  const startRow = range.getRow();
  const endRow = range.getLastRow();
  const startCol = range.getColumn();
  const endCol = range.getLastColumn();

  return row >= startRow && row <= endRow && col >= startCol && col <= endCol;
}

上記のGASをスプレッドシートの拡張機能→apps scriptから保存、スプレッドシートを再読み込みすればプレースホルダが表示されます。

プレースホルダの内容や反映するシート名、範囲などはプログラムの初めにある設定エリアから変更できます。

Discussion