ココナラ スキルマーケットココナラ スキルマーケットココナラ コンテンツマーケット
ココナラ スキルマーケットココナラ スキルマーケットココナラ コンテンツマーケット
UserIcon

ぷま業務効率化サポート

販売実績0
評価3

※ココナラスキルマーケットにおける実績です。

プロフィール詳細へコンテンツ一覧へ
コピペで動くスプレッドシート自動化コード集|突合・重複・集計・名寄せ4本(1本目は無料公開)

コピペで動くスプレッドシート自動化コード集|突合・重複・集計・名寄せ4本(1本目は無料公開)

お気に入り0
評価

0

販売実績

0

UserIcon

ぷま業務効率化サポート

2026年07月31日 03:36

コンテンツ一覧へ

1,000

「毎回おなじ手作業」を、Googleスプレッドシートの自動実行に置き換えるためのコード集です。

プログラミングの経験は要りません。コピーして貼り付けて、実行ボタンを押すだけで動くところまで整えてあります。

収録している4本

突合:2つの表を突き合わせ、不足・数量違い・過剰だけを抜き出す
重複チェック:名簿の重複を、全角半角やハイフンの違いごと見つける
集計:明細から担当別・店舗別の集計表を自動で作る
名寄せ:表記ゆれのある氏名・社名を同一人物としてまとめる

先に正直にお伝えします

この4本がやっていることの一部は、無料の関数でもできます。単純な重複を消すだけなら UNIQUE 関数で足りますし、片方向の照合だけなら COUNTIF でも書けます。それで足りる方は、わざわざこれを買う必要はありません。

このコード集が引き受けているのは、関数では書きづらくなる側です。全角と半角が混ざった氏名、9種類あるハイフン、複数条件の一致、元の行番号を残したままの一覧、数千行でも重くならない書き方。そこを毎回考え直さなくていい形にしてあります。

動かすのに必要なもの

・Googleアカウント(無料のもので構いません)
・Googleスプレッドシート
・所要時間の目安:1本あたり10分

追加のソフトも、外部サービスへの登録も要りません。処理はすべてご自身のGoogleアカウントの中で完結し、データが外部に送られることはありません

まず1本目を、無料で全部お渡しします

買う前に「本当に動くのか」を確かめられないと不安だと思います。なので①の突合ツールは、この無料部分でコード全文をお渡しします。貼り付けて動かしてみて、良ければ残りをどうぞ。

① 2つの表を突き合わせて、食い違いだけを抜き出す(全文・無料)

スプレッドシートを開き、上部メニューの「拡張機能」→「Apps Script」を選び、最初から入っているコードを全部消してから、下をそのまま貼り付けて保存します。

/************************************************************************
 * 2シート自動突合ツール  v1.0
 * --------------------------------------------------------------------
 * 2つのシート(例:発注シートと納品シート)を、指定したキー列で
 * 突き合わせ、「食い違い」だけを自動で抽出します。
 *
 * ■ 検出できる差分
 *   ・不足        … Aにあって、Bにない(例:未納品)
 *   ・過剰        … Bにあって、Aにない(例:発注なし納品)
 *   ・数量不一致  … 両方にあるが、数量など指定した数値列が違う
 *
 * ■ 使い方(詳しくは「導入手順書.pdf」をご覧ください)
 *   1. スプレッドシートに「発注」「納品」「差分結果」の3シートを用意
 *   2. 下の【設定】をご自身のシートに合わせて変更
 *   3. メニュー「▶ 突合ツール」→「差分を抽出する」を実行
 *
 * ※ このコードは自由に改変してお使いいただけます。
 ************************************************************************/


/* ============================================================
 * 【設定】ここだけ、ご自身のシートに合わせて変更してください
 * ============================================================ */
const CONFIG = {
  // 突き合わせる2つのシート名
  SHEET_A: '発注',          // 基準にするシート(例:発注した数)
  SHEET_B: '納品',          // 比較するシート(例:実際に納品された数)

  // 結果を書き出すシート名(自動で中身がクリアされます)
  SHEET_RESULT: '差分結果',

  // 見出し行が何行目か(1行目が見出しなら 1)
  HEADER_ROW: 1,

  // 突き合わせのキーになる列の見出し(両シート共通の名前)
  KEY_HEADER: '商品コード',

  // 数量など、値を比較したい列の見出し(両シート共通の名前)
  //   → 数量を比較しない(存在チェックだけ)場合は '' にしてください
  VALUE_HEADER: '数量',

  // 結果に一緒に表示したい列の見出し(任意・複数可)
  //   例:['商品名'] を入れると、結果に商品名も出ます
  SHOW_HEADERS: ['商品名'],

  // ラベル(お好みで日本語を変えられます)
  LABEL_MISSING:   '不足(Aにあり/Bになし)',
  LABEL_EXTRA:     '過剰(Bにあり/Aになし)',
  LABEL_MISMATCH:  '数量不一致',

  // 実行後にメールで結果を送る場合はここに宛先を入れる(送らないなら '')
  MAIL_TO: '',
  MAIL_SUBJECT: '[差分レポート] 突合結果',
};


/* ============================================================
 * ここから下は、原則さわらなくて大丈夫です
 * ============================================================ */

/** スプレッドシートを開いたときに、専用メニューを追加する */
function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('▶ 突合ツール')
    .addItem('差分を抽出する', 'runReconciliation')
    .addToUi();
}

/** メインの処理:2シートを突き合わせて差分結果シートに書き出す */
function runReconciliation() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();

  const rowsA = readSheet_(ss, CONFIG.SHEET_A);
  const rowsB = readSheet_(ss, CONFIG.SHEET_B);

  // キー → 行データ のマップを作る
  const mapA = toMap_(rowsA);
  const mapB = toMap_(rowsB);

  const results = [];  // 差分の行をためていく

  // --- Aを基準に、不足 と 数量不一致 を探す ---
  Object.keys(mapA).forEach(function(key) {
    const a = mapA[key];
    if (!(key in mapB)) {
      // Bに無い → 不足
      results.push(makeRow_(CONFIG.LABEL_MISSING, key, a, null));
    } else if (CONFIG.VALUE_HEADER) {
      // 両方にある → 数値を比較
      const b = mapB[key];
      const va = toNumber_(a[CONFIG.VALUE_HEADER]);
      const vb = toNumber_(b[CONFIG.VALUE_HEADER]);
      if (va !== vb) {
        results.push(makeRow_(CONFIG.LABEL_MISMATCH, key, a, b));
      }
    }
  });

  // --- Bを基準に、過剰(Aに無いもの)を探す ---
  Object.keys(mapB).forEach(function(key) {
    if (!(key in mapA)) {
      results.push(makeRow_(CONFIG.LABEL_EXTRA, key, null, mapB[key]));
    }
  });

  writeResult_(ss, results);

  const summary = summarize_(results);
  SpreadsheetApp.getActiveSpreadsheet().toast(summary, '突合が完了しました', 8);

  if (CONFIG.MAIL_TO) {
    sendMail_(summary, results);
  }
}

/** シートを読み込み、[{見出し:値, ...}, ...] の配列にして返す */
function readSheet_(ss, sheetName) {
  const sheet = ss.getSheetByName(sheetName);
  if (!sheet) {
    throw new Error('「' + sheetName + '」という名前のシートが見つかりません。設定のシート名をご確認ください。');
  }
  const values = sheet.getDataRange().getValues();
  const headerIdx = CONFIG.HEADER_ROW - 1;
  const headers = values[headerIdx].map(function(h) { return String(h).trim(); });

  const rows = [];
  for (let r = headerIdx + 1; r < values.length; r++) {
    const rowArr = values[r];
    // 空行はスキップ
    if (rowArr.every(function(c) { return c === '' || c === null; })) continue;
    const obj = {};
    headers.forEach(function(h, c) { obj[h] = rowArr[c]; });
    rows.push(obj);
  }
  return rows;
}

/** 行の配列を キー→行 のマップにする */
function toMap_(rows) {
  const map = {};
  rows.forEach(function(row) {
    const key = String(row[CONFIG.KEY_HEADER]).trim();
    if (key === '' || key === 'undefined') return;
    map[key] = row;   // キー重複時は後の行で上書き
  });
  return map;
}

/** 結果1行分を組み立てる */
function makeRow_(label, key, a, b) {
  const extra = CONFIG.SHOW_HEADERS.map(function(h) {
    if (a && a[h] !== undefined && a[h] !== '') return a[h];
    if (b && b[h] !== undefined) return b[h];
    return '';
  });
  const va = (a && CONFIG.VALUE_HEADER) ? a[CONFIG.VALUE_HEADER] : '';
  const vb = (b && CONFIG.VALUE_HEADER) ? b[CONFIG.VALUE_HEADER] : '';
  const diff = (CONFIG.VALUE_HEADER && a && b)
    ? (toNumber_(vb) - toNumber_(va))
    : '';
  return [label, key].concat(extra).concat([va, vb, diff]);
}

/** 結果シートに書き出す */
function writeResult_(ss, results) {
  let sheet = ss.getSheetByName(CONFIG.SHEET_RESULT);
  if (!sheet) sheet = ss.insertSheet(CONFIG.SHEET_RESULT);
  sheet.clearContents();

  const header = ['分類', CONFIG.KEY_HEADER]
    .concat(CONFIG.SHOW_HEADERS)
    .concat([CONFIG.SHEET_A, CONFIG.SHEET_B, '差(' + CONFIG.SHEET_B + '−' + CONFIG.SHEET_A + ')']);

  const out = [header].concat(results.length ? results : [['差分はありませんでした'].concat(header.slice(1).map(function(){return '';}))]);
  sheet.getRange(1, 1, out.length, header.length).setValues(out);

  // 見出しを太字&背景色に
  sheet.getRange(1, 1, 1, header.length)
    .setFontWeight('bold')
    .setBackground('#f1f3f4');
  sheet.setFrozenRows(1);
  sheet.autoResizeColumns(1, header.length);
}

/** 件数の要約テキストを作る */
function summarize_(results) {
  let missing = 0, extra = 0, mismatch = 0;
  results.forEach(function(r) {
    if (r[0] === CONFIG.LABEL_MISSING)  missing++;
    if (r[0] === CONFIG.LABEL_EXTRA)    extra++;
    if (r[0] === CONFIG.LABEL_MISMATCH) mismatch++;
  });
  return CONFIG.LABEL_MISSING + ':' + missing + '件 / '
       + CONFIG.LABEL_MISMATCH + ':' + mismatch + '件 / '
       + CONFIG.LABEL_EXTRA + ':' + extra + '件';
}

/** 結果をメールで送る */
function sendMail_(summary, results) {
  const lines = results.map(function(r) { return r.join('\t'); }).join('\n');
  const body = '突合を実行しました。\n\n'
    + '実行日時:' + Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm') + '\n'
    + summary + '\n\n'
    + (results.length ? '--- 差分の明細 ---\n' + lines : '差分はありませんでした。') + '\n\n'
    + '※このメールは自動送信されています。';
  MailApp.sendEmail(CONFIG.MAIL_TO, CONFIG.MAIL_SUBJECT, body);
}

/** 文字列でも数値でも、数値に変換(カンマ・空白は無視) */
function toNumber_(v) {
  if (typeof v === 'number') return v;
  const n = parseFloat(String(v).replace(/[,\s]/g, ''));
  return isNaN(n) ? 0 : n;
}

/**
 * 毎日・毎週など自動実行したい場合は、この関数をトリガーに設定します。
 * (導入手順書の「自動実行の設定」をご覧ください)
 */
function scheduledRun() {
  runReconciliation();
}

保存したらスプレッドシートに戻り、再読み込みしてください。メニューに専用の項目が追加され、そこから実行できます。

動きましたか。もし動いたなら、残りの3本も同じ手順で動きます。

② 名簿の重複を、表記ゆれごと見つける

残り:16075文字 / 0画像

1,000

0
0

出品者

UserIcon

ぷま業務効率化サポート

販売実績0
評価3

※ココナラスキルマーケットにおける実績です。

プロフィール詳細へ

1,000