0
0

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 LAMBDA関数で解消

0
Posted at

システム開発の現場では、Excelで定義書を作って、定義書からソースコードを生成することがよくあります。
この中で、user_profile_id(スネークケース)とuserProfileId(キャメルケース)を行き来する変換がよくあり、この地味な変換作業は、VBAマクロでやってました。
(以前、関数でやろうとしたこともありましたが、SUBSTITUTE のネストが深くなって可読性が大変悪かったのでやめました)

Excelの LET関数、LAMBDA関数 が登場したことで、VBAマクロを書かなくても、 Excel関数 だけで書けるようになったので、試してみました。

1. スネークケース → キャメルケース (TOCAMEL)

user_profile_iduserProfileId に変換します。

数式(名前の定義に貼り付けて使用)

=LAMBDA(_セル範囲,
    MAP(_セル範囲, LAMBDA(_セル,
        IF(OR(ISERROR(_セル), _セル=""), _セル,
            LET(
                _文字, IF(ISNUMBER(_セル), TEXT(_セル, "@"), _セル),
                _先頭文字, LEFT(_文字, 1),
                IFS(
                    ISERROR(VALUE(_先頭文字))=FALSE, _文字 & "_ERROR_NUM_START",
                    ISNUMBER(FIND(" ", _文字)), _文字 & "_ERROR_CONTAIN_SPACE",
                    TRUE, LET(
                        _分割, TEXTSPLIT(_文字, "_"),
                        _先頭単語, LOWER(INDEX(_分割, 1)),
                        _以降の単語, PROPER(DROP(_分割, , 1)),
                        CONCAT(_先頭単語, _以降の単語)
                    )
                )
            )
        )
    ))
)

ポイント:あえて「汚い変数名」を生成する

1user_2user のような「数字始まり」のスネークケースは、多くのプログラミング言語で変数名として不正です。
それっぽく 1user2User に変換してしまうこともできるのですが、後でコンパイルエラーになってメンドクサイです。
この関数では間にスペースが入ったり、数字始まりの場合、接尾辞を付与してます。
#N/Aとかのエラー値はそのままの値を返してます。こうすることで、おかしな変換に気づきやすくしてます。

  • 1user2User // エラー箇所が埋もれる
  • 1user_2user_ERROR_NUM_START // 「ここがおかしい!」と気づきやすくする
  • user profile_id_ERROR_CONTAIN_SPACE // 「ここがおかしい!」と気づきやすくする

「Fail Loudly:エラーが発生したら、即座に、かつ目立つ形で警告を出し、プログラムを止めるか、異常であることを知らせる」考え方で、設計書や定義書のバグを見つけやすくしています。


2. キャメルケース → スネークケース (TOSNAKE)

userProfileIduser_profile_id(または大文字の USER_PROFILE_ID)に変換します。

数式(名前の定義に貼り付けて使用)

=LAMBDA(_セル範囲, [_出力形式upper],
    MAP(_セル範囲, LAMBDA(_セル,
        IF(OR(ISERROR(_セル), _セル=""), _セル,
            LET(
                _文字, IF(ISNUMBER(_セル), TEXT(_セル, "@"), _セル),
                _先頭文字, LEFT(_文字, 1),
                IFS(
                    ISERROR(VALUE(_先頭文字))=FALSE, _文字 & "_ERROR_NUM_START",
                    ISNUMBER(FIND(" ", _文字)), _文字 & "_ERROR_CONTAIN_SPACE",
                    TRUE, LET(
                        _文字配列, MID(_文字, SEQUENCE(LEN(_文字)), 1),
                        _変換処理, MAP(_文字配列, LAMBDA(_char,
                            IF(AND(EXACT(_char, UPPER(_char)), ISERROR(VALUE(_char))),
                                "_" & LOWER(_char),
                                _char
                            )
                        )),
                        _結合結果, TEXTJOIN("", TRUE, _変換処理),
                        _頭抜き, IF(LEFT(_結合結果, 1)="_", RIGHT(_結合結果, LEN(_結合結果)-1), _結合結果),
                        IF(UPPER(_出力形式upper)="UPPER", UPPER(_頭抜き), LOWER(_頭抜き))
                    )
                )
            )
        )
    ))
)

ポイント

  1. 数字とアルファベットの区別: user1User2 を変換する際、1 も大文字判定されて USER_1_USER_2 になるのを防いでいます。VALUE 関数で数値判定を行うことで、数字を単語の一部として扱い、期待値通りの user1_user2 を出力します。
  2. PascalCase対応: クラス名など先頭が大文字(UserProfile)の場合、単純変換すると _user_profile と頭にアンダースコアがついてしまいます。これを _頭抜き 処理で除去しています。
  3. 間にスペースや数字はじまりはエラー: 変換元の文字列の末尾に_ERROR_NUM_START_ERROR_CONTAIN_SPACE を付与して即座に知らせます。

使い方イメージ

A列 (元データ) B列 (変換後) 使用した関数 備考
user_profile_id userProfileId =TOCAMEL(A2) 通常変換
user profile_id user profile_id_ERROR_CONTAIN_SPACE =TOCAMEL(A2) スペース混入警告
user1_user2 user1User2 =TOCAMEL(A2) 数字混じりもOK
1user_2user 1user_2user_ERROR_NUM_START =TOCAMEL(A2) 数字始まり警告
userProfileId user_profile_id =TOSNAKE(A2) 通常変換
UserProfileId user_profile_id =TOSNAKE(A2) PascalCase対応
userProfileId USER_PROFILE_ID =TOSNAKE(A2, "UPPER") 定数用大文字
1stUser 1stUser_ERROR_NUM_START =TOSNAKE(A2) 数字始まり警告
User Name User Name_ERROR_CONTAIN_SPACE =TOSNAKE(A2) スペース混入警告

導入方法

  1. Excelの [数式] タブ > [名前の定義] をクリック。
  2. 名前TOCAMEL(または TOSNAKE)と入力。
  3. 参照範囲 に上記のコードをコピペして保存。

一度名前定義すれば、そのブック内では標準関数と同じように呼び出せます。

思ったこと

Excelの LAMBDA関数 は、「手続き型プログラミング脳」を「関数型プログラミング脳」に鍛える訓練になるなぁと。
(LAMBDA と6文字使うのが残念なところだが...)

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?