none
AccessのデータをUTF-16でテキスト出力した時の不思議な現象 RRS feed

  • 質問

  • 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

    2016年2月23日 13:31

回答

  • > マイクロソフトの有償サポートに問い合わせた方が良さそうですね。

    問い合わせてみました。

    結論から言えば、本件は未報告の不具合であったとのことで、開発部門へ報告されました。

    暫定的な対処として、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 を利用することを検討してみてください。


    2016年3月2日 14:50

すべての返信

  • 当方でも再現しました。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

    という一行が出力されています。

    手順的に問題は無いと思いますので、マイクロソフトの有償サポートに問い合わせた方が良さそうですね。
    手持ちのインシデントがあるので、今回は私の方で問い合わせを行ってみます。

    何か情報が得られればフィードバックしますが、当方からは緊急度:低にて問い合わせますので、お急ぎの案件であれば、御自身でも問い合わせされることをお奨めします。

    2016年2月24日 0:53
  • こちらでも現象を確認しました。
    レコード数が200程度でも再現し。また、項目2のデータ型が「長いテキスト」でも、連番振らなくても、再現しました。

    Access 2016 + Windows 10

    VB側で例外エラーが発生しているかと思ったのですが、発生していないようですね。


    2016年2月24日 1:06
  • 魔界の仮面弁士 さん

    >"エラー","フィールド","行"
    >"解析不能なレコード",,106

    >という一行が出力されています。

    どういうわけか、テストしたテーブルではそれは出ませんでしたが、確認しよう思った元になったテーブルではたしかにそのエラーが出ていました。
    書き漏らしました。申し訳ございません。

    >手持ちのインシデントがあるので、今回は私の方で問い合わせを行ってみます。

    ありがとうございます。実務的にはFileSystemobjectを使った出力で逃げられますので、急いでいません。
    何かマイクロソフトからの回答がございましたら、教えてください。宜しくお願いいたします。
    2016年2月24日 21:29
  • kenjinoteさん

    >レコード数が200程度でも再現し。また、項目2のデータ型が「長いテキスト」でも、連番振らなくても、再現しました。

    ご確認ありがとうございました。
    2016年2月24日 21:29
  • > マイクロソフトの有償サポートに問い合わせた方が良さそうですね。

    問い合わせてみました。

    結論から言えば、本件は未報告の不具合であったとのことで、開発部門へ報告されました。

    暫定的な対処として、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 を利用することを検討してみてください。


    2016年3月2日 14:50
  • >結論から言えば、本件は未報告の不具合であったとのことで、開発部門へ報告されました。

    >暫定的な対処として、HasFieldNames を False にすることで現象が発生しなくなるようです。

    確認いたしました。確かに、現象は発生しませんでした。どうも、ありがとうございます。

    >それと FileSystemObject で出力する場合、CodePage 1200 (もしくは 0) 相当でしか書き出せないという制限があります。今回は不要だと思いますが、もしも他の CodePaage で出力が必要な場合は、ADODB.Stream を利用することを検討してみてください。

    UTF-8で出力する場合は、ADODB.Streamを使いますが、UTF-16の時はどうしても慣れたFileSystemObjectを使ってしまいます。

    2016年3月5日 6:16