【EXCEL VBA】濁点の並び替えが他のシステムと異なる場合の対応

Excelにおける濁点の並び替えの挙動が他のシステムと異なる場合、対応策を考える必要があります。Excelでは、濁点が付いた文字を直接的に後ろに並べる組み込みオプションが提供されていないため、他のシステムと比べて並び順が異なる可能性があります。

問題のケース

個人宛の通知文書をメールに添付して一斉に配信したい場合があります。そのためには、個人ごとの通知文書を個人番号でファイル名に付けて、メールソフトやアプリでファイルを差し込みながら送信する仕組みを採用しています。

通知文書は業務システムからPDFとして出力できますが、個人ごとに出力すると数が多くなるため、Excelの対象者の一覧から複数の通知文書を一斉にPDFとして出力し、その後で分割しています。 PDFを分割するためには、フリーソフトの「cpdf」を使用してExcelの対象者の一覧からPDFの各ページに「しおり」を追加してからPDFを分割しています。

※ PDFに「しおり」を追加するための設定ファイル

 PDFをしおりで分割して固有のファイル名を付ける方法 「cpdf」を使用してしおりを追加したPDFを分割して固有のファイル名を付ける方法については、以下の記事もご覧ください。

関連記事

個人宛の文書を業務システムやWordの差し込み文書機能を利用して作成し、メールに添付して送信したいときなどがあります。人数が少なければ一人ずつPDF化すればいいのですが、多くの人数を扱う時には現実的ではありません。 そこで複数の個人[…]

業務システムにはSQL Serverが採用されており、照合順序は「Japanese_BIN」に設定されています。「Japanese_BIN」は、バイナリ順序で文字列を比較するため、大文字と小文字、濁点の有無が区別されて並び替えが行われます。

照合順序は、データベース管理システムにおいて文字列のソートや比較を行うためのルールセットです。SQL Serverには様々な照合順序が存在しますが、日本語に特化したものや一般的に使われるものなどがあります。以下に代表的な照合順序の種類を示します。

Japanese_CI_AS(日本語_ケースインセンシティブ_あいうえお順)
この照合順序は、大文字と小文字を区別せずに「あいうえお順」で並び替えを行います。濁点のある文字も正確に扱われます。

Japanese_BIN(日本語_バイナリ順序)
この照合順序は、バイナリ順序で文字列を比較します。つまり、文字のバイト値を基準に並び替えを行います。大文字と小文字、濁点の有無が区別されます。

 本来であれば、業務システムから個人番号順の通知文書がPDF出力できると問題ないのですが、個人のフリガナ順に出力される仕様となっているためにPDFのページの並び順はカナの濁点の有無に基づいて区別されています。例えば、「後藤(ゴトウ)」は「小林(コバヤシ)」よりも後ろに並びます。

 一方、「しおり」を追加するテキストファイルを作成する過程でExcelの対象者の一覧をソートすると、フリガナの濁点は無視されて並び替えられます。例えば、「後藤(ゴトウ)」は「小林(コバヤシ)」よりも先に並びます。

  しかも、Excelでは濁点の付いた文字を直接的に後ろに並べるための組み込みのオプションは提供されていないので、業務システムから出力されたPDFとExcelの対象者の一覧を比較すると、対象者数が同じであるにも関わらず、その並び順は異なっている可能性があります。このことに気づかずに並び順を修正しないまま処理を進めると、他人の個人文書を送信してしまうリスクが生じます。

対応策

他人の個人文書を送信してしまったら最悪です。そこでいくつか考えられる対策を挙げます。

他のアプリを使う方法

Excelの一覧を別の形式(テキストファイルやCSVファイルなど)にエクスポートし、別のソフトウェアでソートを行います。ソート後に再度Excelに取り込むことで、正しい並び順の一覧を得ることができます。以下はCSVファイルを「サクラエディタ」で開き、カナの部分を指定しソートを行ったところです。「サクラエディタ」のソートでは、濁点が区別されて並び替わることを確認しています(設定があるのかもしれませんが残念ながらそこまで調べていません)。ただ、手順が増えるので面倒ですね。 

 ExcelVBAを使用する方法

次にVBAを使用して、Excelの一覧をソートする際にダミーの文字列を生成してダミー列でソートする方法です。正規表現オブジェクトを利用してカナ文字列から濁点文字を抽出し、その濁点文字の後ろに漢字の「点」を付加してソート用のダミー文字列としています。これにより、濁点を後ろに並べることができます。

Sub Dakuten()
    Dim lastRow As Integer
    Dim myStr As String
    Dim Match As Object, Matches As Object
    
    '最終行を取得
    lastRow = Cells(Rows.Count, "A").End(xlUp).Row
    
    '正規表現オブジェクトを作成
    With CreateObject("VBScript.RegExp")
        ' 正規表現パターンを設定(濁点を含む全角カタカナ)
        .Pattern = "ガ|ギ|グ|ゲ|ゴ|ザ|ジ|ズ|ゼ|ゾ|ダ|ヂ|ヅ|デ|ド|バ|ビ|ブ|ベ|ボ"
        .Global = True  '文字列全体を検索
        
        'ヘッダー行を除外して2行目から最終行まで処理
        For i = 2 To lastRow
            'カナ列の文字を取得
            myStr = Cells(i, "C").Value
            
            '文字列がある場合に処理開始
            If Len(myStr) > 0 Then
                'マッチングの結果をMatchesコレクションで返す
                Set Matches = .Execute(myStr)
                
                'マッチしたすべての文字数を処理
                For Each Match In Matches
                    'マッチした文字を置換("点"を付加)
                    myStr = Replace(myStr, Match.Value, Match.Value & "点")
                Next Match
                
                '置換した文字列をダミー列に入力
                Cells(i, "D").Value = myStr
            End If
        Next i
    End With

    'ダミー列で昇順にソート
    Range("A1:D" & lastRow).Sort key1:=Range("D1"), Order1:=xlAscending, Header:=xlYes

End Sub

 チェック体制を整える

PDFファイルに「しおり」を付加する前に、Excelの対象者の一覧の順序と業務システムから出力されたPDFの順序が一致しているかをチェックする体制を整えることも重要です。複数の人に確認してもらうことで、他人の個人文書を誤って送信するリスクを最小限に抑えることができます。手間がかかるかもしれませんが、万一他人の文書が送信されてしまった場合の事後処理の手間を考えると、事前に少し手間をかけておくことが賢明かもしれません。

 

おわりに

そもそも個人番号での並び替えができないなど、業務システムの設計に若干の配慮のなさも否めませんが、いまさら業務システムの照合順序を仕様変更を依頼することもできず…。
結局は複数の人の目で確認するというのが確実な方法なのかもしれません。効果的な方法があれば是非ご教示いただけると幸いです。

Excelの基本から便利な関数やグラフ


ピボットテーブルの基本から応用


マクロ/VBAの基本&業務効率化