3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Excel VBA] 列番号と列文字を相互変換する

Last updated at Posted at 2024-08-20

ざっくり説明

列番号を渡すと列文字にしてくれて、
列文字を渡すと列番号してくれます。

ex.
ConvertColValueMutually ("AB") → 28
ConvertColValueMutually (3776) → "EOF"

コード

列番号と列文字を相互変換する
Function ConvertColValueMutually(ByVal colValue As String) As Variant
'================================
'用途  :列番号と列文字の相互変換
'--------------------------------
'第一引数:列番号もしくは列文字 (String型)
'戻り値 :引数が列番号の場合→列文字 (Variant型)
'     引数が列文字の場合→列番号 (Variant型)
'================================
    Const MAXIMUM_COL_NUMBER As Long = 16384
    Const MAXIMUM_COL_LETTER As String = "XFD"

    If colValue = "" Then GoTo ErrorLabel

    Dim colNumber As Long
    Dim colLetter As String

    If IsNumeric(colValue) Then
        If Len(colValue) > Len(CStr(MAXIMUM_COL_NUMBER)) Then GoTo ErrorLabel
        If colValue <> Int(colValue) Then GoTo ErrorLabel
        colNumber = colValue

        If colNumber <= 0 Then GoTo ErrorLabel
        If colNumber > MAXIMUM_COL_NUMBER Then GoTo ErrorLabel

        Do While colNumber > 0
            colNumber = colNumber - 1
            colLetter = Chr((colNumber Mod 26) + 65) & colLetter
            colNumber = Int(colNumber / 26)
        Loop

        ConvertColValueMutually = colLetter
    Else
        colLetter = UCase(colValue)
        If colLetter = vbNullString Then GoTo ErrorLabel
        If Len(colLetter) > Len(MAXIMUM_COL_LETTER) Then GoTo ErrorLabel
        If Len(colLetter) = Len(MAXIMUM_COL_LETTER) And _
            colLetter > MAXIMUM_COL_LETTER Then GoTo ErrorLabel
    
        Dim i As Long
        For i = 1 To Len(colLetter)
            Dim targetCharacter As String
            Dim asciiCode As Long
            targetCharacter = Left(Right(colLetter, i), 1)
            asciiCode = Asc(targetCharacter)
            If asciiCode < 65 Or asciiCode > 90 Then GoTo ErrorLabel
            colNumber = colNumber + (asciiCode - 64) * 26 ^ (i - 1)
        Next
    
        ConvertColValueMutually = colNumber
    End If

    Exit Function
ErrorLabel:

    ConvertColValueMutually = "ERROR"
End Function

使用方法

第一引数に列番号か列文字を渡す

仕様等

  • 引数で文字を入力するときは小文字でも大丈夫です
  • エラーで弾かれたものはErrorLabelに飛ばされるので適宜処理を記入して下さい
    (とりあえず文字列"ERROR"を返します)

注意点

以下はエラーになります。(以下、第一引数を引数と言う)

  • 引数で空白("")を渡す
  • 引数(数字)が小数
  • 引数(数字)が0以下
  • 引数(数字)が最大列の数字(現状16384)より大きい
  • 引数(文字)がアルファベットではない
  • 引数(文字)が最大列の文字列(現状"XFD")より大きい

引数で#REF!とか#DIV/0!とか渡すと止まることに気付いてるけど対処はしてないです

その他

セルに入力させた列文字を取得・変換して
列番号としてマクロ内で使うという流れがメインかなって勝手に思ってます


ConvertColValueMutuallyの中にConvertColNumberToColLetterとConvertColLetterToColNumberという2つの関数を含ませて分割しようかとも思ったけれど、色々考えて止めました。分割版も一応別記事で書こうかね。

入力された列文字が最大列の文字列("XFD")を超えていないかを判定するときに
変換後の列番号が最大列の数字を超えていないかで判断してるのにモヤっとしている。
分割版のときはなんかアルゴリズム変えたい。

2024/8/21追記
分割版のマクロ書きました!以下へどうぞ


分割版を書いた時に一部コード変更しました。
一応、修正前は以下の通り。

(前略)
    Else
        If Len(colValue) > Len(MAXIMUM_COL_LETTER) Then GoTo ErrorLabel
        colLetter = colValue

        Dim i As Long
        For i = 1 To Len(colLetter)
            Dim targetCharacter As String
            Dim asciiCode As Long

            targetCharacter = Left(Right(colLetter, i), 1)
            asciiCode = Asc(UCase(targetCharacter))
            If asciiCode <= 65 And asciiCode >= 90 Then GoTo ErrorLabel
            colNumber = colNumber + (asciiCode - 64) * 26 ^ (i - 1)
        Next

        If colNumber > MAXIMUM_COL_NUMBER Then GoTo ErrorLabel

        ConvertColValueMutually = colNumber
    End If
(後略)
3
5
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?