アプリ開発ときどきアウトドア

主にJavaを使ったアプリ開発やトラブルシューティング等のノウハウ、キャンプや登山の紹介や体験談など。

1. システムエンジニアリング vba 実装技術

VBAでケバブ・スネーク・パスカル・キャメル変換

投稿日:

開発の現場では、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


(adsbygoogle = window.adsbygoogle || []).push({});


(adsbygoogle = window.adsbygoogle || []).push({});

-1. システムエンジニアリング, vba, 実装技術

執筆者:

関連記事

jQueryによるデフォルトボタンの実装

デフォルトボタンについて Webページ上でエンターキーを押した場合、そのページ上であらかじめ決められたボタンをクリックしたかのように処理を実行する仕組みがある。何らかのデータの検索を行うようなページは …

ftp, ftps, sftpの違い

開発対象システムの連携先システムとして、ftpsやらftpsサーバが指定される場合がある。 私の場合、開発標準の役割を担う場合が多く、これらの仕様を把握し、動作確認や単体テスト用のダミーのサーバを用意 …

Windows Updateが終わらない問題

ふと会社で使っているPCのWindows Updateがほとんど当たっていないことに気づいた。 手動でWindows Updateを実行すると、30分、1時間たっても終わらない… これは何 …

システムエンジニアによる嫌われる勇気の実践

愚直に成果を出すことしか知らなかったシステムエンジニアが、デスマーチなプロジェクトで心を病みそうになったが、「嫌われる勇気」を読んで逆に強くなったお話です。 モノ作りが好きだが「コミュニケーションが苦 …

mavenマルチモジュールプロジェクトの構成例

システム開発でよく使用するmavenマルチモジュールプロジェクトの構成サンプルを説明します。 構成方針 複数のサブシステムをもつシステム開発を想定しています。システム名はzzz、サブシステムはf10, …