「カタカナをローマ字表記に変換する」ネタは VBAでよく見かける。数式でも WebAPIの力を借りれば超絶簡単にできる。これをクエリでやってみよう。
単純には置換リストを作って置き換えればいいので、例外処理を除けばそんなに難しい話ではない。ただし、何をおいてもまずは変換リストを作る必要がある。
自分で作ってもいいけど、面倒なら下のコードを新規クエリの詳細エディタにコピー&ペーストでどうぞ。
変換リスト(ヘボン式基本)
Json.Document(Binary.Decompress(Binary.FromText("bZTNbuJAEITfhXMOZB0n7HG9gB0s2xFgUEhyGP+9Qd4/1Kw187m1F6Qu4Ot2d7k+Plaf38l66lcPq9XXw79qeNLn+HLX3t4bK6debq2cePlPlJMAyQhJAiQjJAmQDJD+V4AcGquKcWitKsQhErrN/wizagizaglrr453Nb9a2T0a2Y2hX47HnuXUy62VEy9HyORX6n7f5UtjVaEvO6sKcXm1qqa7YLgpPEqJmYc0tNs3VlW7/c6qard/tara7SN3dGEXR+xillMvt1ZOvIzhogUK+ih6oKCPogkK+qgLkBqQWU693Fo58TIgjwHyt2isnHq5tXLiZdjmJUBOgMxy6uXWyomXccchQEqabAiQkiYbAqTE47jncPVrY1WhrzurCnGNV3fRkO9wyKAkwKWcanzvc4X5oRpekoveYABlUwaeJs7Ae1bNKFEN3lo1zqj/b3E/zbONvF77uzFXlAeR14u3xUX1Ot1wSs17i7zOLXndZsnrNP8NPO0jB0/9c/DUP2eGqMZV1D9nmCgE4u8n7+tYCo+Q0faRLmoW2eMkB+AN162PeLXV+xj/Pnaq+Y6rBk+3OIKn3TAqtBtmhJ4FHh41fIXfa/oK/TV+BW9o/gre0O4qeE3z4rUcNE/B9FPCMW70PbwhPl7UXvwaXtO+anhN+6qZPKrB075q8DTPGTzt5wye9nM+MYV8/sBtmvAMt2miE9ymCU5wmy50YiL5LALQZxaAPmcA1AQlokQDlEwn1bCvBigRU27hT7dZ+NNpAYA9LezqdJ476usH"), Compression.Deflate))
文字数が多い順に置換するので、50音降順で並べている。
後は新規クエリを作成して入力表を読み込み、一文字ずつ置き換えしてから促音の処理を付け加えればいい。
ローマ字変換(基本)
let
ソース = 入力表,
変換列の追加 = Table.AddColumn(
ソース,
"ローマ字変換",
each List.Accumulate(
変換リスト,
[文字],
(x, y)=> Text.Replace(x, y{0}, y{1})
),
type text
),
変換列の編集 = Table.TransformColumns(
変換列の追加, {"ローマ字変換", each [
位置 = Text.PositionOf(_, "ッ"),
置換 = Text.ReplaceRange(_, 位置, 1, Text.Range(_, 位置+1, 1)),
条件選択 = if 位置=-1 then _ else 置換
][条件選択]
})
in
変換列の編集
単純にはこれでおしまい。後は「『OO』は『O』に変換」のような例外処理を追加していけばいい。ヘボン式なら例外処理は後回しにして、リストを作って置換するだけでいい。
ローマ字変換(ヘボン式)
let
設定 = [
ヘボンA = {{"NB", "MB"}, {"NP", "MP"}, {"NM", "MM"}},
ヘボンB = {{"OO", "O"}},
ヘボンC = {{"OU", "OH"}},
ヘボンD = {{"UU", "U"}},
ヘボンE = {{"CCH", "TCH"}}
],
置換 = (A as list, B as text)=>
List.Accumulate(A, B, (x, y)=> Text.Replace(x, y{0}, y{1})),
ソース = 入力表,
ローマ字変換列の追加 = Table.AddColumn(
ソース,
"ローマ字変換",
each List.Accumulate(
変換リスト,
[文字],
(x, y)=> Text.Replace(x, y{0}, y{1})
),
type text
),
ローマ字変換列の編集 = Table.TransformColumns(
ローマ字変換列の追加, {"ローマ字変換", each [
促音変換 = [
位置 = Text.PositionOf(_, "ッ"),
文字 = Text.Range(_, 位置+1, 1),
置換 = Text.ReplaceRange(_, 位置, 1, 文字),
条件選択 = if 位置=-1 then _ else 置換
][条件選択],
ヘボン設定A = 置換(設定[ヘボンA], 促音変換),
ヘボン設定B = 置換(設定[ヘボンB], ヘボン設定A),
ヘボン設定C = 置換(設定[ヘボンC], ヘボン設定B),
ヘボン設定D = 置換(設定[ヘボンD], ヘボン設定C),
ヘボン設定E = 置換(設定[ヘボンE], ヘボン設定D)
][ヘボン設定E]}
),
列の選択 = Table.SelectColumns(ローマ字変換列の編集, {"ローマ字変換"})
in
列の選択集
訓令式の場合は、「ん」の後に母音(もしくは「Y」)がきた時は「'(アポストロフィ)」を入れる必要があるので「ん」の処理だけ後に回す必要がある。なので訓令式用の変換リストでは「ん」をわざと除いて、置換を後回しにする。
変換リスト(訓令式基本)
Json.Document(Binary.Decompress(Binary.FromText("bZTRbqpQEEX/xefeREup9vESFRoCNoKa2tuHg8Af3P+v+5TMWZz2xWS2umaY2eyPj8W//8lyvC0eFn8Wnw/fZf+kz2F9F9/eD7GcevkUy4mX/wY5MUhGSGKQjJDEIBkgt0eDXAGZ5NTLp1hOvBwg3eZXyCTHkEn+AVl6ebjL+SWW3SqS3WAtc7Sc5NTLp1hOvBwgo1+se7nL50OsCn3exaoQ59dY1XRnDDfao5SYuU+t3f4Qq2q338Wq2u1fY1Xt9oE7ONvFEbuY5NTLp1hOvIzhghEKuikYoaCbghEKuqkzSE03dQap6abOIDUhK4O0hKwM0hKyMkhLN60N0tCSa4M0tOTaIA0grjdISZP1Bilpst4gJSHPdvXLIVaFvuxiVYhLuLoLhnyHQ3rlAS7lVON7ny5MEdXwklz0BgMoojLwNHEG3rNqBopq8JaqcUb9f4v7aZ5t4N18LjBbVAfeTbwtLqrX6YpTat5r4HVuzus2c16n+a/gaR85eOqfg6f+OTNENa6i/jnDRCEQfj+Kh1TRuhEnogfYMOrkeKV13CPeZTU7hr8PnWq+1KrB0/KP4GkZzAYtg6Gg4WHaQcNX+L2mr9Bf41cwg+avYAYtq4K5NG8Bc2megnGnmvmiGmYQv4C5xK9hLu2rhrm0r5pRoxo87asGT/O04Gk/LXjaT8vUUQ1zab4W5tI8Dcyl/g3Mpfs0DCDV4PmEAs+nCnjqXyI41L9kFqmGWdW/RCi5mTndZmZOp6cH7GnmVafb3FGfXw=="), Compression.Deflate))
他はやることは同じで変換する内容が違ってくるだけ。長音がある時は「̂(サーカムフレックス)」を入れるルールがあるけど、これもリストの置換で問題なし。
ローマ字変換(訓令式)
let
設定 = [
訓令A = {
{"ん", "ン"}, {"ンA", "N'A"}, {"ンI", "N'I"}, {"ンU", "N'U"},
{"ンE", "N'E"}, {"ンO", "N'O"}, {"ンY", "N'Y"}, {"ン", "N"}
},
訓令B = {
{"A-", "Â"}, {"I-", "Î"}, {"U-", "Û"},
{"E-", "Ê"}, {"O-", "Ô"}
},
訓令C = {{"Î", "II"}}
],
置換 = (A as list, B as text)=>
List.Accumulate(A, B, (x, y)=> Text.Replace(x, y{0}, y{1})),
ソース = 入力表,
ローマ字変換列の追加 = Table.AddColumn(
ソース,
"ローマ字変換",
each List.Accumulate(
変換リスト,
[文字],
(x, y)=> Text.Replace(x, y{0}, y{1})
),
type text
),
ローマ字変換列の編集 = Table.TransformColumns(
"ローマ字変換", each [
促音変換 = [
位置 = Text.PositionOf(_, "ッ"),
文字 = Text.Range(_, 位置+1, 1),
置換 = Text.ReplaceRange(_, 位置, 1, 文字),
条件選択 = if 位置=-1 then _ else 置換
][置換],
訓令設定A = 置換(設定[訓令A], 促音変換),
訓令設定B = 置換(設定[訓令B], 訓令設定A),
訓令設定C = 置換(設定[訓令C], 訓令設定B)
][訓令設定C]}
),
列の選択 = Table.SelectColumns(ローマ字変換列の編集, {"ローマ字変換"})
in
列の選択集
以上。必要か分からない設定は分けてあるので、いらなければレコードの処理から設定を抜けばいい。設定用のテーブルを別に作って、切り替えできるように作ってもいいと思う。