開発の現場では、Excelに定義したクラスやテーブル等の設計内容に基づいて、VBAで自動的にソースコードやSQL文等の成果物を生成したい場合があります。この処理を実装する場合、Excel上の項目名を、成果物の項目で使用されている命名規則に合わせて変換する機能が必要となります。
ここでは、命名規則に合わせて項目名を変換するためのサンプルを説明します。
概要
- ケバブケースから、スネークケース、パスカルケース、キャメルケース間で識別名を変換するサンプルです。
- 例えば、スネークケースからケバブケースに変換する場合は、Snake2Kebab関数を使用します。
- 各変換関数は「命名規則に基づいて文字列を複数の単語に分割する関数」(XXX2Words関数)、「分割された単語を命名規則に基づいて変換する関数」(Words2XXX関数)という2つの関数を組み合わせて変換しています。
- どちらの関数も、単語分割の区切り文字として半角空白を使用しています。例えば、”snakeToKebab”をケバブに変換する場合、Snake2Kebab関数では、Snake2Words関数とWords2Kebab関数を実行しています。
Snake2Words関数で単語の区切りに空白を挿入して”snake To Kebab”を生成します。Words2Kebabでは、半角空白を”-“に置換(かつ小文字化)して”snake-to-kebab”を生成します。 - 拡張性を持たせるために、このような作りになっています。もっと特定用途のために単純に実現することもできると思います。例えば、ケバブケースからスネークケースに変換するような場合、
Replace(kebab, "-", "_")
等で変換できます。 - 元々は、”getHTTPClient”を”GetHttpClient”のように、大文字が連続する略語を含むキャメルケースをパスカルケースに変換するのが単純にできなくて作ったサンプルです。
サンプルコード
Option Explicit Sub Main() Debug.Print "========" Debug.Print "---2Kebab" Debug.Print Snake2Kebab("here_we_are") 'here-we-are Debug.Print Pascal2Kebab("HereWeAre") 'here-we-are Debug.Print Camel2Kebab("hereWeAre") 'here-we-are Debug.Print "---2Snake" Debug.Print Kebab2Snake("here-we-are") 'here_we_are Debug.Print Pascal2Snake("HereWeAre") 'here_we_are Debug.Print Camel2Snake("hereWeAre") 'here_we_are Debug.Print "---2Pascal" Debug.Print Kebab2Pascal("here-we-are") 'HereWeAre Debug.Print Snake2Pascal("here_we_are") 'HereWeAre Debug.Print Camel2Pascal("hereWeAre") 'HereWeAre Debug.Print "---2Camel" Debug.Print Kebab2Camel("here-we-are") 'hereWeAre Debug.Print Snake2Camel("here_we_are") 'hereWeAre Debug.Print Pascal2Camel("HereWeAre") 'hereWeAre Debug.Print "---CamelVariation" Debug.Print Camel2Kebab("update") 'update Debug.Print Camel2Kebab("getHttp") 'get-http Debug.Print Camel2Kebab("getHTTPClient") 'get-http-client Debug.Print Camel2Kebab("setOpt1TextBox") 'set-opt1-text-box Debug.Print Camel2Kebab("setURI") 'set-uri Debug.Print Camel2Kebab("readEMail") 'read-e-mail Debug.Print Camel2Kebab("readEmail") 'read-email End Sub '変換関数 ================================================== 'ケバブケースから変換する関数群 Public Function Kebab2Snake(kebab As String) Kebab2Snake = Words2Snake(Kebab2Words(kebab)) End Function Public Function Kebab2Pascal(kebab As String) Kebab2Pascal = Words2Pascal(Kebab2Words(kebab)) End Function Public Function Kebab2Camel(kebab As String) Kebab2Camel = Words2Camel(Kebab2Words(kebab)) End Function 'スネークケースから変換する関数群 Public Function Snake2Kebab(snake As String) Snake2Kebab = Words2Kebab(Snake2Words(snake)) End Function Public Function Snake2Pascal(snake As String) Snake2Pascal = Words2Pascal(Snake2Words(snake)) End Function Public Function Snake2Camel(snake As String) Snake2Camel = Words2Camel(Snake2Words(snake)) End Function 'パスカルケースから変換する関数群 Public Function Pascal2Kebab(pascal As String) Pascal2Kebab = Words2Kebab(Pascal2Words(pascal)) End Function Public Function Pascal2Snake(pascal As String) Pascal2Snake = Words2Snake(Pascal2Words(pascal)) End Function Public Function Pascal2Camel(pascal As String) Pascal2Camel = Words2Camel(Pascal2Words(pascal)) End Function 'キャメルケースから変換する関数群 Public Function Camel2Kebab(camel As String) Camel2Kebab = Words2Kebab(Camel2Words(camel)) End Function Public Function Camel2Snake(camel As String) Camel2Snake = Words2Snake(Camel2Words(camel)) End Function Public Function Camel2Pascal(camel As String) Camel2Pascal = Words2Pascal(Camel2Words(camel)) End Function '内部関数 ================================================== '各ケースから単語群に変換する関数群------------------------- Private Function Kebab2Words(kebab As String) Kebab2Words = Replace(kebab, "-", " ") End Function Private Function Snake2Words(snake As String) Snake2Words = Replace(snake, "_", " ") End Function Private Function Pascal2Words(pascal As String) Pascal2Words = Camel2Words(pascal) End Function Private Function Camel2Words(camel As String) Dim ucs As Boolean 'スキャンモード(Upper Case Scan) Dim i As Integer Dim ch As String Dim nch As String Dim s As String For i = 1 To Len(camel) 'HTTP等の略語で大文字が連続する場合は、大文字+小文字の直前で区切る 'それ以外は、小文字orその他文字が大文字に切り替わる直前で区切る ch = Mid(camel, i, 1) nch = Mid(camel, i + 1, 1) If Not ucs And IsUCase(ch) And IsUCase(nch) Then '大文字が連続する場合はスキャンモード有効 s = ch: ucs = True ElseIf ucs And IsUCase(ch) And IsLCase(nch) Then 'スキャンモードの場合、大文字+小文字の前で区切る s = " " & ch: ucs = False ElseIf (IsLCase(ch) Or IsOther(ch)) And IsUCase(nch) Then '通常、小文字(+その他文字)が大文字に変わった場合に区切る s = ch & " " Else s = ch End If Camel2Words = Camel2Words & s Next End Function '単語群から各ケースに変換する関数群------------------------- Private Function Words2Kebab(words As String) Words2Kebab = Join(Split(LCase(words)), "-") End Function Private Function Words2Snake(words As String) Words2Snake = Join(Split(LCase(words)), "_") End Function Private Function Words2Pascal(words As String) Dim w As Variant For Each w In Split(words) '各単語の先頭を大文字、それ以降を小文字に変更 Words2Pascal = Words2Pascal & UCase(Mid(w, 1, 1)) & LCase(Mid(w, 2)) Next End Function Private Function Words2Camel(words As String) 'パスカルケースの先頭を小文字に変更 Dim pascal As String: pascal = Words2Pascal(words) Words2Camel = LCase(Mid(pascal, 1, 1)) & Mid(pascal, 2) End Function 'その他の関数群--------------------------------------------- Private Function IsUCase(ch As String) IsUCase = False If ch = "" Then Exit Function Dim c As Integer: c = Asc(ch) IsUCase = (&H41 <= c And c <= &H5A) End Function Private Function IsLCase(ch As String) IsLCase = False If ch = "" Then Exit Function Dim c As Integer: c = Asc(ch) IsLCase = (&H61 <= c And c <= &H7A) End Function Function IsOther(ch As String) IsOther = (InStr("0123456789", ch) > 0) End Function