トップ回答者
AccessのデータをUTF-16でテキスト出力した時の不思議な現象

質問
-
AccessのTransferTextの事で伺います。
最初、マイクロソフト コミュニティ で質問しましたが、こちらで聞いた方が良いとアドバイスされたので、こちらにも書き込みます。
TransferTextでUTF-16のテキスト出力時に不思議な現象に遭遇しました。そこで、以下のようなレイアウトのテーブルtData1を作成し、再現するかどうか試してみました。
項目1(主キー) 長整数型
項目2 短いテキスト
項目1は1から5000までの連番
項目2は "あいうえおかきくけこ□"の末尾に連番と同じ物を付加したデータが格納されています。
このデータを、以下のコマンドでUTF-16のテキスト出力しました。
DoCmd.TransferText acExportDelim, , "tData1", _
cOFolder & "\text\tdata1_U16.txt", True, , 1200
cOFolderはフォルダーの名称を格納した定数です。
最初の方は、UTF-16で正常に出力されているのですが、途中、一点崩れたデータの行がありました。
(略)
100,"あいうえおかきくけこ□100"
101,"あいうえおかきくけこ□101"
102,"あいうえおかきくけこ□102"
103104,"あいうえおかきくけこ□104" ←ここ
105,"あいうえおかきくけこ□105"
(略)
キー103の行の後ろが欠損しています。
データの内容を変えても、崩れる位置が変わりますが、同様の欠損が起こります。
崩れているのはこの箇所だけで、この行以降、5000行目までは、欠損している行はありません。
出力エンコード設定を1200(UTF-16リトルエンディアン)ではなく、65001(UTF-8)やデフォルト(CP932)にした場合は崩れがありません。
またUTF-16はリトルエンディアンだけでなく、ビッグエンディアン(1201)でも崩れが生じました。
UTF-16だとこうなる物なのでしょうか。それとも何かやり方が悪いのでしょうか。
(試した環境)
Windows8.1 MS-Office2013
Windows7 MS-Office2010、2016
回答
-
> マイクロソフトの有償サポートに問い合わせた方が良さそうですね。
問い合わせてみました。
結論から言えば、本件は未報告の不具合であったとのことで、開発部門へ報告されました。
暫定的な対処として、HasFieldNames を False にすることで現象が発生しなくなるようです。
[Windows 7] + [Access 2007/2010/2013/2016] においては、
HasFieldNames が True かつ CodePage が 1200/1201 のときに再現。
[Windows 8.1 x64] + [Access 2013] あるいは
[Windows 10] + [Access 2016] においては、
HasFieldNames が True かつ CodePage が 1200 のときに再現。
※CodePage 1201 の場合、HasFieldNames でも再現せず。
組み合わせによって動作が異なることから、
OS の文字コードの扱いと、Access 側の処理の双方の影響で
発生している問題のようです。
> 実務的にはFileSystemobjectを使った出力で逃げられますので、
列名の出力が不要な場合は、HasFieldNames 引数を False 指定にすることが、もっとも簡単な回避策になります。
それと FileSystemObject で出力する場合、CodePage 1200 (もしくは 0) 相当でしか書き出せないという制限があります。今回は不要だと思いますが、もしも他の CodePaage で出力が必要な場合は、ADODB.Stream を利用することを検討してみてください。
- 編集済み 魔界の仮面弁士MVP 2016年3月4日 3:28 「それ」という表記が曖昧だったため、回避策の表現を修正
- 回答としてマーク Note-taking distance 2016年3月5日 6:17
すべての返信
-
当方でも再現しました。Access 2013 x86 + Windows 7 Pro SP1 です。
テストコードを掲載しておきます。
'Call DoCmd.RunSQL("CREATE TABLE [" & TableName & "] ([項目1] LONG PRIMARY KEY, [項目2] VARCHAR(50))") Dim CodePage As Variant For Each CodePage In Array(0, 932, 1200, 1201, 65001) Call DoCmd.TransferText(acExportDelim, , TableName, _ cOFolder & "\text\" & TableName & "_" & CStr(CodePage) & ".txt", _ HasFieldNames:=True, CodePage:=CodePage) Next
当方での崩れ方は下記のようになりました。ちょっと違いますね。
<TransferText CodePage=1200> 102,"あいうえおかきくけこ□102" 103,"あ104,"あいうえおかきくけこ□104" 105,"あいうえおかきくけこ□105" <TransferText CodePage=1201> 102,"あいうえおかきくけこ□102" 103,"あい104,"あいうえおかきくけこ□104" 105,"あいうえおかきくけこ□105"
また、CodePage が 1200 および 1201 の時において、それぞれ
「tData1_何某_エクスポート エラー」テーブルが同時に生成され、"エラー","フィールド","行"
"解析不能なレコード",,106という一行が出力されています。
手順的に問題は無いと思いますので、マイクロソフトの有償サポートに問い合わせた方が良さそうですね。
手持ちのインシデントがあるので、今回は私の方で問い合わせを行ってみます。何か情報が得られればフィードバックしますが、当方からは緊急度:低にて問い合わせますので、お急ぎの案件であれば、御自身でも問い合わせされることをお奨めします。
-
こちらでも現象を確認しました。
レコード数が200程度でも再現し。また、項目2のデータ型が「長いテキスト」でも、連番振らなくても、再現しました。
Access 2016 + Windows 10
VB側で例外エラーが発生しているかと思ったのですが、発生していないようですね。
- 編集済み kenjinoteMVP 2016年2月24日 1:35
-
魔界の仮面弁士 さん
>"エラー","フィールド","行"
>"解析不能なレコード",,106
>という一行が出力されています。
どういうわけか、テストしたテーブルではそれは出ませんでしたが、確認しよう思った元になったテーブルではたしかにそのエラーが出ていました。
書き漏らしました。申し訳ございません。
>手持ちのインシデントがあるので、今回は私の方で問い合わせを行ってみます。
ありがとうございます。実務的にはFileSystemobjectを使った出力で逃げられますので、急いでいません。
何かマイクロソフトからの回答がございましたら、教えてください。宜しくお願いいたします。 -
> マイクロソフトの有償サポートに問い合わせた方が良さそうですね。
問い合わせてみました。
結論から言えば、本件は未報告の不具合であったとのことで、開発部門へ報告されました。
暫定的な対処として、HasFieldNames を False にすることで現象が発生しなくなるようです。
[Windows 7] + [Access 2007/2010/2013/2016] においては、
HasFieldNames が True かつ CodePage が 1200/1201 のときに再現。
[Windows 8.1 x64] + [Access 2013] あるいは
[Windows 10] + [Access 2016] においては、
HasFieldNames が True かつ CodePage が 1200 のときに再現。
※CodePage 1201 の場合、HasFieldNames でも再現せず。
組み合わせによって動作が異なることから、
OS の文字コードの扱いと、Access 側の処理の双方の影響で
発生している問題のようです。
> 実務的にはFileSystemobjectを使った出力で逃げられますので、
列名の出力が不要な場合は、HasFieldNames 引数を False 指定にすることが、もっとも簡単な回避策になります。
それと FileSystemObject で出力する場合、CodePage 1200 (もしくは 0) 相当でしか書き出せないという制限があります。今回は不要だと思いますが、もしも他の CodePaage で出力が必要な場合は、ADODB.Stream を利用することを検討してみてください。
- 編集済み 魔界の仮面弁士MVP 2016年3月4日 3:28 「それ」という表記が曖昧だったため、回避策の表現を修正
- 回答としてマーク Note-taking distance 2016年3月5日 6:17
-
>結論から言えば、本件は未報告の不具合であったとのことで、開発部門へ報告されました。
>暫定的な対処として、HasFieldNames を False にすることで現象が発生しなくなるようです。
確認いたしました。確かに、現象は発生しませんでした。どうも、ありがとうございます。
>それと FileSystemObject で出力する場合、CodePage 1200 (もしくは 0) 相当でしか書き出せないという制限があります。今回は不要だと思いますが、もしも他の CodePaage で出力が必要な場合は、ADODB.Stream を利用することを検討してみてください。
UTF-8で出力する場合は、ADODB.Streamを使いますが、UTF-16の時はどうしても慣れたFileSystemObjectを使ってしまいます。