はじめに
Accessで既存の固定長ファイルを取り込む処理を修正していたところ、新しく追加した項目だけデータの位置がズレる問題が発生しました。
取込処理では、既存のインポート定義を指定して DoCmd.TransferText を実行していました。
DoCmd.TransferText _
acImportFixed, _
"インポート定義名", _
"取込先TMP", _
strPath, _
False
既存項目はこれまで正常に取り込めていました。
ところが、インポート定義の末尾に全角文字を含む項目を追加したところ、そこから項目位置が合わなくなりました。
最終的には、インポート定義の Start / Widthを文字数ではなくバイト数として計算し直すことで正常に取り込めました。
今回は、そのときに確認した内容を備忘録としてまとめます。
使用している処理
今回のシステムでは、保存済みのインポート定義を使用して固定長ファイルをAccessへ取り込んでいます。
VBAでは次のような処理です。
DoCmd.TransferText _
acImportFixed, _
"インポート定義名", _
"取込先TMP", _
strPath, _
False
acImportFixed を指定して、固定長形式としてインポートしています。
既存項目では問題が発生していなかった
今回少し分かりにくかったのが、既存部分はすべて正常に取り込めていたことです。
既存項目は半角文字だけで構成されていました。
今回扱っていたデータでは、
半角1文字 = 1バイト
となるため、
文字数 = バイト数
になります。
そのため、文字数の感覚でStart / Widthを設定していても問題が表面化していませんでした。
全角文字を含む項目を追加したらズレた
今回、既存のインポート定義の末尾に新しい項目を追加しました。
例えば、次のような項目です。
登録情報1
登録情報2
登録情報3
ここから全角文字を含むデータになりました。
すると、新規追加した項目からデータ位置がズレるようになりました。
既存部分には影響ありません。
イメージとしては、
既存項目
半角のみ
↓
正常に取り込める
新規追加項目
全角文字を含む
↓
ここからズレる
という状態でした。
そこで、全角文字の扱いに原因があるのではないかと考えました。
原因は「文字数」と「バイト数」の違い
最初は固定長ファイルなので、
何文字目から何文字分を取得するか
という考え方でStart / Widthを設定していました。
しかし、全角文字を含むデータでは文字数とバイト数が一致しません。
今回扱っていたデータでは、
半角文字 = 1バイト
全角文字 = 2バイト
として計算する必要がありました。
例えば、
ABCあいう
というデータなら、
A = 1バイト
B = 1バイト
C = 1バイト
あ = 2バイト
い = 2バイト
う = 2バイト
となり、合計は
9バイト
になります。
文字数としては6文字ですが、固定長データ上では9バイトです。
この違いによってStart / Widthの位置が合わなくなっていました。
Start / Widthをバイト数で設定して解決
そこで、全角文字を2バイトとしてStart / Widthを再計算しました。
例えば修正後のインポート定義を簡略化すると、次のようになります。
| 項目名 | Start | Width |
|---|---|---|
| 登録情報1 | 513 | 30 |
| 登録情報2 | 543 | 30 |
| 登録情報3 | 573 | 30 |
次の項目のStartは、
前の項目のStart + Width
になるように設定しています。
例えば、
513 + 30 = 543
543 + 30 = 573
です。
固定長データの実際のバイト位置に合わせてStart / Widthを設定し直したところ、正常に取り込めるようになりました。
なぜ今まで問題が発生しなかったのか?
今回の問題で特にハマったポイントです。
既存項目は半角文字だけだったため、
半角のみ
↓
1文字 = 1バイト
↓
文字数とバイト数が一致
↓
問題なし
でした。
ところが、新しく追加した項目には全角文字が含まれていました。
全角文字あり
↓
1文字 = 2バイトになる部分がある
↓
文字数とバイト数が一致しない
↓
Start / Widthが合わなくなる
つまり、
「今まで同じ設定方法で正常に動いていた」ことが、逆に原因を分かりにくくしていました。
半角文字だけを扱っている間は、文字数とバイト数の違いを意識しなくても問題が発生しなかったためです。
全角・半角が混在する固定長ファイルは注意
固定長ファイルを扱う場合は、単純な文字数だけではなく、実際のデータが何バイトで構成されているのかも確認した方が安全です。
特に、
- 漢字
- ひらがな
- 全角カタカナ
- 全角スペース
- 半角英数字
などが混在するデータでは注意が必要です。
半角だけのデータでは問題が発生せず、全角文字を含む項目を追加したタイミングで初めてズレることもあります。
また、1文字あたりのバイト数は文字コードによって異なるため、すべての環境で「全角=2バイト」となるわけではありません。
今回のケースでは、対象となる固定長ファイルを確認し、半角1バイト・全角2バイトとして計算することで正常に取り込めました。
まとめ
今回の問題をまとめると、次のような流れでした。
既存の固定長インポート
↓
インポート定義の末尾に項目を追加
↓
新規項目から全角文字を使用
↓
新規項目からインポート位置がズレる
↓
文字数ではなくバイト数でStart / Widthを再計算
↓
正常に取り込めた
特に重要だったのは、既存項目がすべて半角だったため、それまで文字数とバイト数の違いが表面化していなかったことです。
Accessの固定長インポートで、
- 全角文字を追加してからズレる
- Start / Widthが合わない
- 半角項目までは正常
- 全角項目以降からおかしくなる
といった現象が発生した場合は、Start / Widthをバイト数として見直してみると解決につながるかもしれません。
同じ問題で困っている方の参考になれば幸いです。


コメント