共有シートのB列に金額がある前提で書いた処理は、途中に列を追加されると別の値を読む可能性があります。見出しの「金額」を探して列番号を決めれば、列の並び順から独立した参照にできます。ただし、同名の列が2つある場合は、自動で片方を選ばないようにします。
ここでは1行目を見出しとして読み、「顧客ID」と「金額」の位置を調べます。読み取りまでの例なので、列の並べ替えや元データの書き換えは行いません。必要な見出しが1つずつあることを確認してから、後続の処理へ渡します。
使う見出しの文字を決める
練習用シートの1行目に「顧客ID」「担当」「金額」を入れます。この例は完全一致で探すため、「金額」と「金額(税込)」は別の列です。似ている語から意味を推測せず、処理が必要とする名前を明示します。
前後の空白も不備として扱います。すべての空白を消してから比較すると、人には違う見出しに見えているのに同じ列として処理する可能性があるためです。表記を自動で補正したい場合は、補正前の見出しとルールを別に記録してください。
見出し行の取得には、公式のRangeのgetDisplayValuesを使います。見出しは表示文字として受け取り、2次元配列の先頭行を取り出します。数値データまで表示文字へ置き換えるという意味ではありません。
欠落と重複を見つける関数
以下は必要な列の位置だけを返します。シートの列番号は1から始まるため、配列の添字に1を足しています。
function requiredColumns(headers, required) {
const positions = new Map();
headers.forEach(function (name, index) {
if (typeof name !== 'string') throw new Error('見出しは文字列で指定');
if (name === '') return;
if (name.trim() !== name) throw new Error('見出しに前後の空白: ' + name);
if (positions.has(name)) throw new Error('見出しが重複: ' + name);
positions.set(name, index + 1);
});
const result = {};
required.forEach(function (name) {
if (!positions.has(name)) throw new Error('必要な見出しがありません: ' + name);
Object.defineProperty(result, name, {
value: positions.get(name), enumerable: true
});
});
return result;
}
function previewColumnMap() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('列名練習');
if (!sheet) throw new Error('列名練習シートがありません');
const width = sheet.getLastColumn();
if (width === 0) throw new Error('見出し行がありません');
const headers = sheet.getRange(1, 1, 1, width).getDisplayValues()[0];
console.log(JSON.stringify(requiredColumns(headers, ['顧客ID', '金額'])));
}
元の並びなら、結果は{"顧客ID":1,"金額":3}です。金額列を2列目へ移すと、結果の「金額」は2になります。配列の2番目を取り出すときには、この列番号から1を引く必要があります。使い分けはシートの番号と配列の番号で確認できます。
列を動かした後の試し方
練習用コピーで列を並べ替え、返る番号が見出しの位置と合うかを確かめます。続けて「金額」を削除した場合と、別の列にも「金額」と書いた場合に、どちらもエラーで止まることを確認します。
空の見出しは対応表に入れません。一方、不要に見える列でも名前が重複していればエラーにしています。今は使わない列が後で必要になったとき、同じ名前が複数ある状態をそのまま引き継がないためです。結合した見出しや2段見出しの表は、この関数の前提から外れます。
この方法は列の位置を見つけるもので、列の内容が正しいことまでは保証しません。「金額」という見出しの下に文字列が入っていたり、税込・税抜が混じっていたりする場合は、データを読む段階で別に検査します。
対応表を使うタイミング
1回の処理の開始時に見出しを読み、その処理で使う対応表として渡すと、コード内の固定の列番号を減らせます。長い処理の途中に列が移動する運用では、処理中の編集を止める取り決めや、書き込み前の再確認も必要です。
確認したのはローカルの配列と代用シートでの列順変更、空白、重複、欠落です。Google上の同時編集は実行していません。列対応と金額の集計などを別の関数に分ける考え方はGASコードの分割にもつながります。
