DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ADO.NETでのCSVファイルインポート

環境/言語:[VB.NET]
分類:[.NET]

はじめまして。

ADFO.NETでcsvファイルをインポートしてdatatableに格納した後、吐き出す際に以下の現象で困っています。

パスとCSVファイル名を引数に以下の関数を実行。

取得データデータセット内のテーブルの1列目で以下の現象が発生します。

[CSV]
1234,1234,1234
1234,1234,1234
1234,1234,1234

を吸い込むと

[Datatable]
1234,1234,1234
1234,1234,1234
1234,1234,1234

これは正常。

[CSV]
1234,1234,1234
1234,1234,1234
a234,1234,1234

を吸い込むと

[Datatable]
1234,1234,1234
1234,1234,1234
DBNULL,1234,1234

英数字が混在した際なぜかDBNULLでブランクが返ってきます。

ちなみに

[CSV]
1234,1234,1234
a234,1234,1234
a234,1234,1234

を吸い込むと

[Datatable]
1234,1234,1234
a234,1234,1234
a234,1234,1234

で1列目に英数字が混在した際に、混在が多数(2:1)派になるとちゃんと取得します。分かりやすく3件で示しましたが15件や30件で試しても多数派を締めた時点で期待する動きになります。

datatypeが怪しいとおもうのですが、コネクションを作成して一気に吸い上げるのでどこで設定していいのか分かりません。

現状DBNULLの場所はDBNULLタイプ。
その他はSTRING型となっています。












Public Shared Function ImportCsv(ByVal xlsPath As String, ByVal fileName As String) As DataSet

'コネクション情報作成
Dim m_sConn1 As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & xlsPath & ";" & _
"Extended Properties=""Text;HDR=NO;FMT=Delimited"""

Dim objConn As New OleDbConnection(m_sConn1)
objConn.Open()
Dim objCmdSelect As New OleDbCommand("SELECT * FROM " & fileName, objConn)
Dim objAdapter1 As New OleDbDataAdapter
objAdapter1.SelectCommand = objCmdSelect
Dim objDataset1 As New DataSet
objAdapter1.Fill(objDataset1, "XlsDT")

Return objDataset1

End Function
それはある意味仕様なんですが・・・

回避策は、schema.iniを定義して下さい。
要は各フィールドの属性を定義する・・・

http://support.microsoft.com/kb/408179/ja

以上。参考まで
■No26012に返信(やすさんの記事)
> ByVal xlsPath As String, ByVal fileName As String
前者はディレクトリパス、後者は CSV のファイル名なのですよね。
引数の名前が不自然ではありませんか?


> どこで設定していいのか分かりません。
Schema.ini が用意されている場合には、Schema.ini の設定が利用されます。
Schema.ini が存在しない場合には、レジストリで指定された設定が利用されます。

後者については、具体的には
 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Text\
の下に、文字列(REG_SZ)キー「ImportMixedTypes」を用意し、
その値を "Text" にすることで、テキスト型固定で読み込まれます。

このキーの値を、"Majority Type" にした場合、MaxScanRows で
指定された行数分がスキャンされ、多数決で型が決定されます。

なお、ImportMixedTypes の初期値は未設定です。
(未設定の場合には、既定値である "Majority Type" と看做されます)
また、MaxScanRows の初期値は 25 (dword:00000019) です。

-------------
ただし、HKLM\SOFTWARE\Microsoft\Jet\4.0\ を修正すると、
他の JET 4.0 アプリケーションにも影響を与えることに注意してください。

通常はそれでも問題無いと思いますが、もしも都合が悪いようであれば、
アプリ固有のプロファイルを用意し、そのエントリを利用させることもできます。

具体的には、HKLM\SOFTWARE\ の下に、自アプリ用のレジストリ エントリを
用意します。良く利用されるのは、自アプリ名のバージョンなどを関した
 HKEY_LOCAL_MACHINE\SOFTWARE\MyCorporation\MyApplication\1.0\
というエントリですが、別のキー名でも構いません。そして、ここに
 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\
の内容を複製しておきます。

といっても、すべての項目を用意する必要は無く、上書きしたい項目のみを
複写しておけば OK です。今回の場合には、最低限、
 HKEY_LOCAL_MACHINE\SOFTWARE\MyCorporation\MyApplication\1.0\Text
を用意し、そこに ImportMixedTypes = "Text" を置いておけば良いでしょう。


エントリを用意したら、接続文字列の部分を、
 「Provider=Microsoft.Jet.OLEDB.4.0;Data Source=〜;……」
から
 「Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Registry Path=SOFTWARE\MyCorporation\MyApplication\1.0;Data Source=〜;……」
のように変更してください。
"Jet OLEDB:Registry Path" で指定したプロファイルが利用されるようになります。
オショウさん
早速ありがとうございました。

仕様で開き直っている辺りがマイクロソフトらしいですね・・・

schema.iniで設定すると問題なく取り込めました。


ありがとうございました★


■No26013に返信(オショウさんの記事)
> それはある意味仕様なんですが・・・
>
> 回避策は、schema.iniを定義して下さい。
> 要は各フィールドの属性を定義する・・・
>
> http://support.microsoft.com/kb/408179/ja
>
> 以上。参考まで
魔界の仮面弁士さん


返信ありがとうございます。

変数の名前は修正したいと思います^^;

やはり設定行スキャンをして多数決で決まってしまうのですね・・・

今回は簡易なschema.iniで対応したいと思います。

プロファイルの作成も試してみます★

ありがとうございました。








■No26018に返信(魔界の仮面弁士さんの記事)
> ■No26012に返信(やすさんの記事)
>>ByVal xlsPath As String, ByVal fileName As String
> 前者はディレクトリパス、後者は CSV のファイル名なのですよね。
> 引数の名前が不自然ではありませんか?
>
>
>>どこで設定していいのか分かりません。
> Schema.ini が用意されている場合には、Schema.ini の設定が利用されます。
> Schema.ini が存在しない場合には、レジストリで指定された設定が利用されます。
>
> 後者については、具体的には
>  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Text\
> の下に、文字列(REG_SZ)キー「ImportMixedTypes」を用意し、
> その値を "Text" にすることで、テキスト型固定で読み込まれます。
>
> このキーの値を、"Majority Type" にした場合、MaxScanRows で
> 指定された行数分がスキャンされ、多数決で型が決定されます。
>
> なお、ImportMixedTypes の初期値は未設定です。
> (未設定の場合には、既定値である "Majority Type" と看做されます)
> また、MaxScanRows の初期値は 25 (dword:00000019) です。
>
> -------------
> ただし、HKLM\SOFTWARE\Microsoft\Jet\4.0\ を修正すると、
> 他の JET 4.0 アプリケーションにも影響を与えることに注意してください。
>
> 通常はそれでも問題無いと思いますが、もしも都合が悪いようであれば、
> アプリ固有のプロファイルを用意し、そのエントリを利用させることもできます。
>
> 具体的には、HKLM\SOFTWARE\ の下に、自アプリ用のレジストリ エントリを
> 用意します。良く利用されるのは、自アプリ名のバージョンなどを関した
>  HKEY_LOCAL_MACHINE\SOFTWARE\MyCorporation\MyApplication\1.0\
> というエントリですが、別のキー名でも構いません。そして、ここに
>  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\
> の内容を複製しておきます。
>
> といっても、すべての項目を用意する必要は無く、上書きしたい項目のみを
> 複写しておけば OK です。今回の場合には、最低限、
>  HKEY_LOCAL_MACHINE\SOFTWARE\MyCorporation\MyApplication\1.0\Text
> を用意し、そこに ImportMixedTypes = "Text" を置いておけば良いでしょう。
>
>
> エントリを用意したら、接続文字列の部分を、
>  「Provider=Microsoft.Jet.OLEDB.4.0;Data Source=〜;……」
> から
>  「Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Registry Path=SOFTWARE\MyCorporation\MyApplication\1.0;Data Source=〜;……」
> のように変更してください。
> "Jet OLEDB:Registry Path" で指定したプロファイルが利用されるようになります。

DOBON.NET | プログラミング道 | プログラミング掲示板