ACCESSインポート時のデータ型変換の不具合に関する調査 MaxScanRows

  



ACCESSインポート時のデータ型変換の不具合に関する調査


 1 現象
ACCESSへ、CSVファイルからデータをインポートするときに、ある列の小数の値が、小数点以下を切り捨てられた状態で、整数としてインポートされた。テーブルの該当列のデータ型はテキストになっていた。
データのインポートは、ファイルAを最初に行った。
ACCESSのインポートウィザードを使用し、ウィザード上で新しいテーブルを自動作成して、インポート時のデータ型をテキストに指定してインポートを行った。
Aのインポートの結果は、小数点以下も保持され、問題はなかった。
ファイルBのインポートに当たっては、Aのインポート時に自動作成されたテーブルにインポートした。テーブルからAのデータを削除し、空になったテーブルにインポートウィザードを使用して、Bのデータをインポートした。データ型の指定(インポート定義)は行わなかった。該当列のデータの小数点以下が切り捨てられてインポートされた。また、インポート時のエラーは発生しなかった。
ファイルC、D、E についても同様の作業を行い、インポートの結果は小数点以下が切り捨てられていた。

2 検証
インポート時に、データの上から~行目までのスキャンが行われ、データ型をACCESSが推測するという情報があったので、検証する。
 元のファイルをコピーし、データの上から順に、一つだけ小数の値を入れて、既存のからテーブルにインポートする。

元のファイル 小数点以下が切り捨てられる
    一行目のデータを小数に変更したデータ 小数点以下が切り捨てられる
    二行目のデータを小数に変更したデータ 小数の形が保持される
三行目のデータを小数に変更したデータ  小数の形が保持される
    四~二十五・・・・・・・・・・・・・ 小数の形が保持される
二十六行目のデータを小数に変更したデータ 小数点以下が切り捨てられる

結果としては、2~25行のデータに小数がない場合は、全て整数としてインポートされている。

 3 ACCESSの仕様と挙動 調査した結果を記述する
ACCESSの既定値では、インポートするファイルがテキスト(CSV)の場合、レジストリに設定されているMaxScanRowsの値を参照し、列のデータ型を推測する(詳細は後述)。
ACCESSのエンジンは、2~25行(既定値)のデータを調べ、データ型を推測してインポートを行う。
1行目が使われないのは、ヘッダ行である可能性があるのでスキャンされないか、優先度が落とされていると推測される(推測)。
インポート定義、もしくはscheme.iniを使用しない場合は、列のデータ型は推測される。

 インポート先のテーブルの列のデータ型は、インポート元の列のデータ型と関連しない。
テーブルのデータ型と、インポートするファイルのデータ型は、比較されたり考慮されることはない。ただし、インポート不能であれば、インポート中にエラーを表示する。
 これはインポート時に、テーブルの列のデータ型は考慮されず、無関係ということである。



4 インポート時の動作のイメージ
以下にイメージを添付する。

f:id:hsmtblue:20190312000019p:plain


f:id:hsmtblue:20190319033106p:plain
5 対策 と チェック
  小数が整数にされたりしないために、データ型を推測させない必要がある。
 そのために、できることを挙げる。
対策
  1 インポート定義、もしくはsheme.iniを使用する。
  2 データ型を推測させないように、レジストリを変更する。
  3 データ型推測時に、全行をスキャンするようにレジストリを変更する。
チェック
  4 計算可能なデータであれば、元のファイル、インポート後、各々合計を出して照合する。
  5 必要があれば、元のファイルと、インポート後のデータをすべて照合する。
  6 データ型が推測されてしまうものだということを、頭に止めておく。

対策1,2,3については、1のインポート定義を推奨する。scheme.iniについてはここでは記述しない(外部アプリからACCESSにインポートする場合に使用する)。
2,3のレジストリの変更も可能であるが、すべてのOFFICEアプリケーションに影響が出るために、あまり推奨はしない(試してみる価値はある)。

チェック 4,5については、時間が許す範囲となる。
 特に5については、都度VBAを組む必要があるが、必要があれば対応する。



 6 レジストリの詳細
 以下のレジストリの値は全て
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Text下にあるものをいう。
1:レジストリのMaxScanRwosの値はデフォルトで25になっている。これを0にすることですべての行がスキャンされる。ここでスキャンされたデータの型が混じっている場合は、次の2の値を参照して動作が決定する。混じっていない場合は25行めまでの型に確定する。

2:レジストリのImportMixedTypes の値が「Majority Type」であった場合、多数決によって決まる(実際には、少数と整数があった場合には、表現力の大きい小数になる)。この値が設定されていない場合は、Majority Type になる。

 レジストリの変更による対策を行う場合には、MaxScanRows=0、ImportMixtedTypes=Text に変更する。
 変更後の挙動は、全行をスキャンし、データ型が混じっていればテキスト型でインポートされる。
 CSVではなくXLS等のエクセルファイルをインポートする場合は、レジストリ内のTypeGuessRows と、ImportMixedTypes の値が参照される。TypeGuessRowsがデータ型を推測するためのスキャン行数となっている。こちらの既定値は8で、デフォルトでは8行しかスキャンせずに推測されてしまう。

OFFICEのバージョン、OSの環境によってレジストリの場所は異なるが、Access Connectivity Engine を検索することで発見できる。

2007と2010以降が混在している場合は、レジストリも複数の場所にAccess Connectivity Engineがあるので注意すること。

以上がレジストリの変更による対応の詳細だが、手順、実際の挙動のチェックなどが雑然としており、あまりお勧めはしないが、一度設定がうまくいけば、スムーズに業務が運べるかもしれない。

レジストリの画面を添付しておく。


f:id:hsmtblue:20190311235506p:plain



7 参考URL

調査したURLを列挙しておく

https://blog.esrij.com/2010/06/18/schemaini-301f/
https://dobon.net/vb/bbs/log3-43/26012.html
https://social.msdn.microsoft.com/Forums/ja-JP/e4c45cae-bf09-4f8b-8f28-e9ef3c5ca929/29305234501239865328653151239120316251041237512383653156533165?forum=vsgeneralja
https://answers.microsoft.com/ja-jp/msoffice/forum/msoffice_access-mso_winother-mso_2007/regedit%E3%82%A8%E3%83%87%E3%82%A3%E3%83%83/98fda91e-7343-441a-ac89-155ae4462c4d?messageId=4e05b3a2-86f7-41c6-a52e-7e0368e30700
https://support.microsoft.com/ja-jp/help/968580
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1313045738


f:id:hsmtblue:20190312000019p:plainf:id:hsmtblue:20190312000038p:plain