2014年11月28日金曜日

スネーク記法をキャメル記法に変換するExcelの関数

DBの仕様書をもとにクラスのメンバを定義するのはよくあること。 DBのカラム名はスネーク記法で定義されていて、クラスのメンバはキャメル記法な場合にExcelで一気にスネーク記法からキャメル記法に変換するのに使ってました。
Attribute VB_Name = "snake2Camel"
Option Explicit

Const DELIMITER_SNAKE = "_"
Const DELIMITER_CHAIN = "-"
Const DELIMITER_CAMEL = ""

'------------------------------------------------------------
' 文字列strをUpperCamel形式に変換して返す
'------------------------------------------------------------
Function UpperCamel(ByVal str As String)
    Dim delimiter As String
    Dim i As Integer    'loop index
    Dim tmp As String
       
    '変換前の記法を判定
    If InStr(str, DELIMITER_SNAKE) > 0 Then
        delimiter = DELIMITER_SNAKE
    ElseIf InStr(str, DELIMITER_CHAIN) > 0 Then
        delimiter = DELIMITER_CHAIN
    Else
        delimiter = DELIMITER_CAMEL
    End If
    
    If delimiter <> DELIMITER_CAMEL Then
        Dim tokens() As String
        tokens = Split(str, delimiter)
        For i = 0 To UBound(tokens)
            tokens(i) = UCase(Left(tokens(i), 1)) & LCase(Mid(tokens(i), 2))
        Next
        str = Join(tokens, "")
    Else
        str = UCase(Left(str, 1)) & LCase(Mid(str, 2))
    End If
    
    '最初の1文字と数字の次は大文字
    tmp = UCase(Left(str, 1))
    For i = 2 To Len(str)
        If InStr("0123456789", Mid(str, i - 1, 1)) > 1 Then
            tmp = tmp & UCase(Mid(str, i, 1))
        Else
            tmp = tmp & Mid(str, i, 1)
        End If
    Next
    UpperCamel = tmp

End Function

'------------------------------------------------------------
' 文字列strをlowerCamel形式に変換して返す
'------------------------------------------------------------
Function LowerCamel(ByVal str As String)
    Dim delimiter As String
    Dim i As Integer    'loop index
    Dim tmp As String
       
    '変換前の記法を判定
    If InStr(str, DELIMITER_SNAKE) > 0 Then
        delimiter = DELIMITER_SNAKE
    ElseIf InStr(str, DELIMITER_CHAIN) > 0 Then
        delimiter = DELIMITER_CHAIN
    Else
        delimiter = DELIMITER_CAMEL
    End If
    
    If delimiter <> DELIMITER_CAMEL Then
        Dim tokens() As String
        tokens = Split(str, delimiter)
        For i = 0 To UBound(tokens)
            tokens(i) = UCase(Left(tokens(i), 1)) & LCase(Mid(tokens(i), 2))
        Next
        str = Join(tokens, "")
    Else
        '小文字が一つも出現しない場合は1単語とみなして全て小文字化
        If Not isContainSmallCase(str) Then
            str = LCase(str)
        End If
    End If
    
    '最初の1文字は小文字、数字の次は大文字
    tmp = LCase(Left(str, 1))
    For i = 2 To Len(str)
        If InStr("0123456789", Mid(str, i - 1, 1)) > 1 Then
            tmp = tmp & UCase(Mid(str, i, 1))
        Else
            tmp = tmp & Mid(str, i, 1)
        End If
    Next
    LowerCamel = tmp

End Function

'------------------------------------------------------------
' 文字列strに小文字を含む場合はTRUEを返す
'------------------------------------------------------------
Function isContainSmallCase(ByVal str As String) As Boolean
    Dim i As Integer ' loop index
    Dim a As Integer ' ascii code
    isContainSmallCase = False
    For i = 1 To Len(str)
        a = Asc(Mid(str, i, 1))
        If a >= 97 And a <= 122 Then
            isContainSmallCase = True
        End If
    Next
End Function