AccessVBAのレポートで文字に「□」が重なる原因はTAB文字だった

Accessのレポートで文字に重なった□をTAB文字の除去で解消するイメージ AccessVBA

Accessのレポートで、文字に「□」が重なって表示される。

Accessで作った見積書を使っていただいていたところ、次のような連絡をいただきました。

見積書の備考欄に「□」(チェックボックス?)が被って表示されてしまっています

PDFを確認すると、確かに文字の上に四角い枠が重なっています。

備考欄の先頭の文字や途中の文字に□が重なって表示されているレポート

1行目は「空」、3行目は「交」、4行目は「ク」に□が重なっています。2行目は正常です。

シチュエーション

Excelからコピーして入力している
品名や備考を、Excelの見積表や商品リストから貼り付けている

他のシステムから取り込んだデータ
CSVなどで取り込んだ文字列をそのままレポートに出している

入力画面では気付かない
入力した本人も、PDFにして初めて気付く

原因はTAB文字

□の正体はTAB文字(Chr(9))です。PDFの文字をコピーしてテキストエディタに貼り付けると、□の位置にTABが入っていることが確認できます。

レポートはTAB文字を「字下げ」として扱わず、1文字として描こうとします。ところがフォントにはTAB文字の形がないため、「表示できない文字」の四角が描かれ、しかも幅がほとんどないので、次の文字に重なって表示されます。

見え方はフォントによって変わります。同じデータを游ゴシックで出力すると、×印の入った四角になりました。

游ゴシックでは×印の入った四角が文字に重なる

TAB文字が入る経路
Excelで複数のセルをまとめてコピーすると、セルの区切りはTAB文字になります。空のセルを含めてコピーし、1つのテキストボックスに貼り付けると、先頭や途中にTAB文字が残ります。テキストボックスの中ではTAB文字がほとんど目立たないので、入力した時点では気付けません。

TAB文字が入っているデータを探す

まず、登録済みのデータにTAB文字がどれだけあるか確認します。クエリのデザインビューで、SQLビューに次のように入力します。

SELECT * FROM T_受注明細 WHERE InStr([備考], Chr(9)) > 0;

InStr でTAB文字(Chr(9))の位置を調べ、0より大きい(=含まれている)行だけを抽出しています。品名など他の項目も気になる場合は、同じ条件を OR でつなげます。

TAB文字を取り除くプロシージャサンプル

標準モジュールに以下のコードを貼り付けます。

'=========================================================
'  プロシージャ名:gf_DEL_TAB
'  機能  :文字列からTAB文字を取り除きます。
'            ・先頭と末尾のTABは削除
'            ・途中のTABは半角スペースに置き換え
'
'  【引数】
'    varText :対象の文字列(Nullも可)
'
'  【使用例】
'    gf_DEL_TAB(vbTab & "空錠タイプ")        → "空錠タイプ"
'    gf_DEL_TAB("ハンドル" & vbTab & "交換") → "ハンドル 交換"
'=========================================================
Public Function gf_DEL_TAB(varText As Variant) As Variant
    Dim l_str As String           ' 作業用の文字列
    '=== Nullはそのまま返す ===
    If IsNull(varText) Then
        gf_DEL_TAB = Null
        Exit Function
    End If
    l_str = varText
    '=== 先頭のTABを削除 ===
    Do While Left(l_str, 1) = vbTab
        l_str = Mid(l_str, 2)
    Loop
    '=== 末尾のTABを削除 ===
    Do While Right(l_str, 1) = vbTab
        l_str = Left(l_str, Len(l_str) - 1)
    Loop
    '=== 途中のTABは半角スペースに ===
    gf_DEL_TAB = Replace(l_str, vbTab, " ")
End Function

途中のTABを削除せずスペースにする理由
「ハンドル」「交換」のように別々のセルからコピーされた文字の間にTABが入っている場合、TABを消すだけだと「ハンドル交換」と語がくっついてしまいます。元の区切りが分かるように、半角スペースに置き換えています。

引数をVariantにしている理由
レポートのコントロールソースやクエリから呼び出すと、空欄の項目はNullで渡されます。String 型の引数にすると、Nullの行でエラー(#エラー表示)になるため、Variant で受けてNullはそのまま返しています。

実行方法

レポートの表示だけ直す
レポートをデザインビューで開き、備考のテキストボックスのプロパティシート「データ」タブで、コントロールソースを次のように変更します。

プロパティ変更前変更後
コントロールソース備考=gf_DEL_TAB([備考])

コントロールソースを式にした場合、テキストボックスの名前が 備考 のままだと「循環参照」のエラーになります。名前は Txt_Biko など、フィールド名と違うものにしておいてください。

変更後のレポートでは、□が消えて正しく表示されます。

gf_DEL_TABを通したレポート。□が消え、途中のTABは半角スペースになっている

3行目は途中のTABが半角スペースになり、「ハンドル 交換作業」と表示されています。

登録済みのデータを一括で直す
データそのものからTAB文字を消す場合は、更新クエリを実行します。

UPDATE T_受注明細 SET 備考 = gf_DEL_TAB([備考])
WHERE InStr([備考], Chr(9)) > 0;

実行前に、必ずテーブル(またはデータベースファイル)のバックアップを取ってください。

どこで取り除くのがよいか

TAB文字を取り除く場所は、大きく分けて3つあります。

取り除く場所良い点注意点
出力時(レポートのコントロールソース等)登録済みのデータもそのまま直る出力する場所(レポート・Excel出力など)ごとに対応が必要
データを一括修正(更新クエリ)データがきれいになるこれから入力されるデータには効かない
入力時(テキストボックスの更新後処理)以降のデータにTABが入らない登録済みのデータは直らない

実際の見積書の不具合では、出力時に取り除く方法を採用しました。登録済みの見積も出力し直すだけで直るので、利用者にデータを入力し直してもらう必要がありません。見積書とあわせて、外部サービス用のExcel出力にも同じ関数を通しています。

最後に

以上がAccessのレポートで、文字に「□」が重なる原因と対策です。

TAB文字は入力画面ではほとんど目立たず、PDFにして初めて気付くことが多い文字です。Excelからの貼り付けが多い画面では、レポートに出す項目に gf_DEL_TAB を通しておくと安心です。

コメント

タイトルとURLをコピーしました