GAS | Convert spreadsheet column numbers and alphabetic column names.

When specifying a column in GAS, the column number is basically more convenient. Because you can also do addition and subtraction.

However, when you want to get the entire column in the sheet, you have to write the following using the column name, and there are times when you want to convert the column number and column name.

Column number → Column name

/**
 * シートの列番号をアルファベットの列名称に変換する。
 * 例: 5 => "E", 100 => "CV"
 * @param {number} clmNum 列番号
 * @return {string} アルファベットの列名称
 */
function getClmName(clmNum) {
  //数字ではなかった場合はエラー
  if (isNaN(clmNum)) throw new Error(`列番号が数字ではありません。 clmNum: ${clmNum}`)
  //アルファベット文字数26文字なので、列番号を26進数の扱いに直す。
  let syo = Math.floor(clmNum / 26); //26で割った商
  let amari = clmNum % 26; //26で割った余り
  //余りが0の場合は、微調整する。
  if (amari === 0) {
    syo--;
    amari = 26;
  }
  //列名称2桁目(以上)のアルファベットを特定する。
  let parent = syo > 26
    ? getClmName(syo) //商の値が26を超える場合は、ループ処理する。
    : syo > 0
      ? String.fromCharCode('A'.charCodeAt(0) + syo - 1) //商の値が0より大きく26以下の場合は、対応するアルファベット1文字に変換する。
      : ''; //商が0の場合は空欄とする。
  //列名称1桁目のアルファベットを特定する。
  let child = String.fromCharCode('A'.charCodeAt(0) + amari - 1); //余りの値に対応するアルファベット1文字に変換する。
  return parent + child;
}

Column name → Column number

/**
 * シートのアルファベットの列名称を列番号に変換する。
 * 例: "E" => 5, "CV" => 100
 * @param {string} clmName アルファベットの列名称
 * @return {number} 列番号
 */
function getClmNum(clmName) {
  let clmNum = 0;
  //列名称を文字ごとに分割した配列を作成し、順番を逆転させた上で、末尾の文字より該当する数字に変換する。
  String(clmName).split("").reverse().forEach((val, idx, arr) => {
    //半角アルファベットでない場合はエラー
    if (/[^A-Za-z]/.test(val)) throw new Error(`半角アルファベット以外の文字が含まれています。 clmName: ${clmName}`)
    //大文字化した上で、「A」の文字コードとの差を数字で取得する。
    let num = val.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0) + 1;
    //列名称末尾からの位置に応じて、26のべき乗を準備し、それに先ほどの数字をかける。その値を列番号に加算する。
    clmNum += (26 ** idx) * num;
  })
  return clmNum;
}

Not recommended method

I sometimes see code like the following, but it uses the method of the sheet class that is originally unnecessary, so it is not recommended.

function getClmName() {
  //アクティブなセルを取得
  const cell = SpreadsheetApp.getActiveRange().getCell(1, 1);
  //セル名をA1表記で取得
  const loc = cell.getA1Notation();
  //セル名から行を表す数字部分を削除し、列を表すアルファベットのみを残す。
  const clmName = loc.replace(/[0-9]/g, '');
  return clmName;
}

列名称は完全に規則的に付けられているものなので、わざわざ無関係なsheetのメソッドを呼び出さなくても変換できます。スタンドアローンのGASプロジェクトだと、そもそもアクティブレンジも取得できなかったりします。

Let's go as simple as possible!

Leave a Reply

Your email address will not be published. Required fields are marked *