12

OleDbConnection を使用して Excel 2007 スプレッドシートをクエリしています。OleDbDataReader が列のデータ型として文字列のみを使用するように強制したい。

システムはデータの最初の 8 行を見て、データ型が Double であると推測します。問題は、行 9 にその列に文字列があり、Double にキャストできなかったため、OleDbDataReader が Null 値を返していることです。

これらの接続文字列を使用しました:

Provider=Microsoft.ACE.OLEDB.12.0;Data Source="ExcelFile.xlsx";Persist Security Info=False;Extended Properties="Excel 12.0;IMEX=1;HDR=No"

Provider=Microsoft.Jet.OLEDB.4.0;Data Source="ExcelFile.xlsx";Persist Security Info=False;Extended Properties="Excel 8.0;HDR=いいえ;IMEX=1"

reader.GetSchemaTable().Rows[7].ItemArray[5] を見ると、dataType が Double になっています。

このスキーマの行 7 は、問題が発生している Excel の特定の列と相関しています。ItemArray[5] はその DataType 列です

リーダー用のカスタム TableSchema を作成して、ExcelFiles にアクセスするときに、システムがデータ型を推測するのではなく、すべてのセルをテキストとして扱うことはできますか?


このページで良い情報を見つけました: ADO.NET を使用して Excel スプレッドシートを読み取るためのヒント

ADO.NET インターフェイスの主な特徴は、データ型の処理方法です。(スプレッドシートを読んでいるときに、どのデータ型が返されるかという質問を慎重に避けてきたことに気付くでしょう。) 準備はできていますか? ADO.NET はデータの最初の 8 行をスキャンし、それに基づいて各列のデータ型を推測します。次に、その列のすべてのデータをそのデータ型に強制しようとし、強制が失敗するたびに NULL を返します!

ありがとう、
キース


これが私のコードの縮小版です:

using (OleDbConnection connection = new OleDbConnection(BuildConnectionString(dataMapper).ToString()))
{
    connection.Open();
    using (OleDbCommand cmd = new OleDbCommand())
    {
        cmd.Connection = connection;
        cmd.CommandText = SELECT * from [Sheet1$];
        using (OleDbDataReader reader = cmd.ExecuteReader())
        {
            using (DataTable dataTable = new DataTable("TestTable"))
            {
                dataTable.Load(reader);
                base.SourceDataSet.Tables.Add(dataTable);
            }
        }
    }
}
4

4 に答える 4

7

ご存じのように、OLEDB は微調整できる方法が制限されている Jet を使用します。OleDbConnection を使用して Excel ファイルから読み取るように設定されている場合はHKLM\...\Microsoft\Jet\4.0\Engines\Excel\TypeGuessRows、システムが結果セット全体をスキャンするように、値をゼロに設定する必要があります。

とはいえ、代替エンジンを使用して Excel ファイルから読み取ることにオープンである場合は、ExcelDataReaderを試すことを検討してください。すべての列を文字列として読み取りますが、dataReader.Getxxx メソッドを使用して型付きの値を取得できます。を埋めるサンプルを次に示しますDataSet

DataSet result;
const string path = @"....\Test.xlsx";
using ( var fileStream = new FileStream( path, FileMode.Open, FileAccess.Read ) )
{
    using ( var excelReader = ExcelReaderFactory.CreateOpenXmlReader( fileStream ) )
    {
        excelReader.IsFirstRowAsColumnNames = true;
        result = excelReader.AsDataSet();
    }
}
于 2010-04-08T03:59:27.570 に答える
2

64ビットOSの場合は、次のとおりです。

My Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel
于 2012-12-14T22:40:24.330 に答える
1

このページの最終回答を確認してください。


あなたが参照しているページが同じことを言っていることに気付きました...


更新

問題は、ADO ではなく、JET エンジン自体にあるようです。JET がタイプを決定すると、それに固執します。それ以降に何をしても効果はありません。SQL で値を文字列にキャストするのと同じように (例: Cstr([Column]))、空の文字列が返されるだけです。

この時点で (他に回答がない場合)、他の方法を選択します。スプレッドシートを変更します。レジストリの変更 (JET を使用する他のすべてのアプリの設定を変更することになるため、理想的ではありません)。JET を使用しない Excel オートメーションまたはサード パーティ コンポーネント。

自動化オプションが遅い場合は、それを使用してスプレッドシートを扱いやすい別の形式で保存してください。

于 2010-04-05T18:34:48.553 に答える