【ExcelVBA】列番号を変換する関数を自作してみた（R1C1形式<->A1形式）

# はじめに

ExcelVBA上では、1～Nの整数で表される列番号（R1C1形式）を用いることが多いですが、ユーザーが見ているExcelの画面上ではA, B, C, ..., AA, AB, ...というアルファベットで表される列番号（A1形式）が表示されていることが多いです。
（※[表示をA1形式からR1C1形式に変える](https://data-by-vba.com/2019/07/05/excel%E3%82%B7%E3%83%BC%E3%83%88%E3%81%AEa1%E5%BD%A2%E5%BC%8F%E3%81%A8r1c1%E5%BD%A2%E5%BC%8F%E3%81%AE%E8%A1%A8%E7%A4%BA%E5%88%87%E6%9B%BF%E6%96%B9%E6%B3%95/)ことも可能です）

そこで今回は学習目的で、R1C1形式とA1形式の列番号を（力任せで）相互に変換出来る関数を自作してみました。

また、INDIRECT関数やADDRESS関数などを使うともっとスッキリ変換出来るので、実用上は[こちらの記事の方法](https://qiita.com/nomico/items/60bce25569a5276b5817)を参考にされた方が良いと思います。

|列番号（R1C1形式）|列番号（A1形式）|
|---|---|
|1|A|
|2|B|
|3|C|
|...|...|
|26|Z|
|27|AA|
|...|...|
|52|AZ|
|53|BA|
|...|...|

# 作成した関数

* [ASCIIコード表](https://www.k-cube.co.jp/wakaba/server/ascii_code.html)では、A～Zの大文字のアルファベットが10進数だと65～90で表されています。
* そこで`Chr`関数を使って、列番号の数字をアルファベットに変換する処理を作ってみました。
  * 列番号が27以上の時は再帰処理を使ってA1形式の列番号を組み立てていますが、再帰を使わない方がより効率的な処理になると思います。

## R1C1形式->A1形式に変換する関数

```vb:R1C1形式->A1形式
'--------------------------------------------------------------------------------
' Excelの列番号をR1C1形式からA1形式に変換する。
'
' r1c1ColIdx：R1C1形式の列番号。
' return：Excelのバージョン。
'--------------------------------------------------------------------------------
Public Function ToA1(r1c1ColIdx As Long) As String
    Dim remainder As Integer, quotinent As Long
    remainder = (r1c1ColIdx - 1) Mod 26
    quotinent = Int((r1c1ColIdx - 1) / 26)  ' 除算の結果が小数になるケースがあるため、Int関数で切り捨てる
    
    If (quotinent > 0) Then
        ToA1 = ToA1(quotinent) + ToColAlphabet(remainder)
    Else
        ToA1 = ToColAlphabet(remainder)
    End If
End Function

'--------------------------------------------------------------------------------
' 1～26の整数を、A～Zのアルファベットに変換する。
'
' idx：1～26の整数。
' return：A～Zのアルファベット。
'--------------------------------------------------------------------------------
Private Function ToColAlphabet(idx As Integer) As String
    ToColAlphabet = Chr(idx + 65) ' Chr(65)は'A'となる。
End Function
```

```vb:テストコード
Public Sub TestToA1()
    Debug.Print "列番号1：", ToA1(1) ' A
    Debug.Print "列番号26：", ToA1(26) ' Z
    Debug.Print "列番号27：", ToA1(27) ' AA
    Debug.Print "列番号52：", ToA1(52) ' AZ
    Debug.Print "列番号53：", ToA1(53) ' BA
    Debug.Print "列番号78：", ToA1(78) ' BZ
    Debug.Print "列番号79：", ToA1(79) ' CA
End Sub
```

```text:テストコードの実行結果
列番号1：     A
列番号26：    Z
列番号27：    AA
列番号52：    AZ
列番号53：    BA
列番号78：    BZ
列番号79：    CA
```

## A1形式->R1C1形式に変換する関数

* R1C1形式->A1形式の変換の逆の処理を行うため、`Asc`関数を使ってアルファベットをASCIIコードに変換し、ASCIIコードから列番号を作り出しています。

```vb:A1形式->R1C1形式
'--------------------------------------------------------------------------------
' Excelの列番号をA1形式からR1C1形式に変換する。
'
' a1ColIdx：A1形式の列番号。
' return：Excelのバージョン。
'--------------------------------------------------------------------------------
Public Function ToR1C1(a1ColIdx As String) As Long
    Dim substr As String
    substr = a1ColIdx
    
    Dim i As Integer
    
    For i = 1 To Len(a1ColIdx)
        If (i = 1) Then
            ToR1C1 = ToR1C1 + ToColNumber(Right(substr, 1))
        Else
            ToR1C1 = ToR1C1 + (ToColNumber(Right(substr, 1)) * (i - 1) * 26)
        End If
        substr = Left(substr, Len(substr) - 1)
    Next i
End Function

'--------------------------------------------------------------------------------
' A～Zのアルファベットを、1～26の整数に変換する。
'
' idx：A～Zのアルファベット。
' return：1～26の整数。
'--------------------------------------------------------------------------------
Private Function ToColNumber(idx As String) As Integer
    ToColNumber = Asc(idx) - 65 + 1 ' Asc("A")は65となる。
End Function
```

```vb:テストコード
Public Sub TestToR1C1()
    Debug.Print "列番号A：", ToR1C1("A") ' 1
    Debug.Print "列番号Z：", ToR1C1("Z") ' 26
    Debug.Print "列番号AA：", ToR1C1("AA") ' 27
    Debug.Print "列番号AZ：", ToR1C1("AZ") ' 52
    Debug.Print "列番号BA：", ToR1C1("BA") ' 53
    Debug.Print "列番号BZ：", ToR1C1("BZ") ' 78
    Debug.Print "列番号CA：", ToR1C1("CA") ' 79
End Sub
```

```text:テストコードの実行結果
列番号A：      1 
列番号Z：      26 
列番号AA：     27 
列番号AZ：     52 
列番号BA：     53 
列番号BZ：     78 
列番号CA：     79 
```

# 参考URL

* [ExcelシートのA1形式とR1C1形式の表示切替方法](https://data-by-vba.com/2019/07/05/excel%E3%82%B7%E3%83%BC%E3%83%88%E3%81%AEa1%E5%BD%A2%E5%BC%8F%E3%81%A8r1c1%E5%BD%A2%E5%BC%8F%E3%81%AE%E8%A1%A8%E7%A4%BA%E5%88%87%E6%9B%BF%E6%96%B9%E6%B3%95/)
* [ASCIIコード表](https://www.k-cube.co.jp/wakaba/server/ascii_code.html)
* [[Excel] 列文字・列番号の変換をかろやかに行いたい](https://qiita.com/nomico/items/60bce25569a5276b5817)