9

Excelからデータをインポートして処理するC#/。Netジョブがあります。クライアントがファイルをドロップして処理します。元のファイルを制御することはできません。

OleDbライブラリを使用してデータセットを埋めます。ファイルには、30829300、30071500などの番号が含まれています。これらの列のデータ型は「テキスト」です。

データをインポートすると、これらの数値は科学的記数法に変換されます。これを防ぐ方法はありますか?

4

10 に答える 10

5

この問題の回避策の 1 つは、SELECT * の代わりに次のように選択ステートメントを変更することです。

"SELECT Format([F1], 'General Number')  From [Sheet1$]"
 -or-
"SELECT Format([F1], \"#####\")  From [Sheet1$]"

ただし、セルに 255 文字を超える文字が含まれていると、「複数ステップの OLE DB 操作でエラーが発生しました。利用可能な場合は、各 OLE DB ステータス値を確認してください。作業は行われませんでした。」というエラーが表示された場合、これを行うと失敗します。

幸いなことに、私の顧客はこのシナリオでエラーが発生することを気にしませんでした。

このページにも試してみるべき良いことがたくさんあります: http://www.dicks-blog.com/archives/2004/06/03/external-data-mixed-data-types/

于 2011-10-12T21:35:40.863 に答える
3

OleDb ライブラリ、多くの場合、Excel スプレッドシートのデータを台無しにします。これは主に、各列の最初の 8 つのセルの値から各列の型を推測して、すべてを固定型の列レイアウトに強制するためです。推測が間違っている場合は、数字の文字列が科学的表記法に変換されてしまいます。ブリーチ!

これを回避するには、OleDb をスキップして、自分でシートを直接読むことをお勧めします。これは、Excel の COM インターフェイス (これも blech!)、またはサードパーティの .NET Excel 互換リーダーを使用して行うことができます。 SpreadsheetGearは、適度に機能するライブラリの 1 つであり、Excel の COM インターフェイスと非常によく似たインターフェイスを備えています。

于 2009-01-09T22:13:22.643 に答える
3

この接続文字列の使用:

Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\"

Excel 2010 を使用して、次のことに気付きました。OLEDB SELECT を実行するときに Excel ファイルが開いている場合、保存されたファイルの値ではなく、現在のバージョンのセルが取得されます。さらに、長い数値、10 進数値、および日付に対して返される文字列値は、次のようになります。

5.0130370071e+012
4.08
36808

ファイルが開いていない場合、返される値は次のとおりです。

5013037007084
£4.08
Monday, October 09, 2000
于 2013-04-23T09:36:46.930 に答える
1

Open XML SDK 2.0 Productivity Tool を使用して実際の .XSLX ファイルを確認すると (または単にファイルを解凍してメモ帳で XML を表示すると)、Excel 2007 が生データを実際に科学的形式で保存していることがわかります。

たとえば、0.00001 は 1.0000000000000001E-5 として格納されます

<x:c r="C18" s="11" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  <x:v>1.0000000000000001E-5</x:v>
</x:c>

Excel でセルを見ると、セルと数式バーの両方で 0.00001 と表示されています。したがって、OleDB が問題を引き起こしているとは限りません。

于 2012-03-27T15:12:15.830 に答える
0

最も簡単な方法は、大きな「数値」を持つ列のテキスト形式ではなく、Zip 形式を選択することです。

于 2009-01-09T21:42:15.107 に答える
0

読んでいるときに、フィールドの値を (int) または (Int64) にキャストしようとしましたか?

于 2009-01-09T21:47:40.823 に答える
0

Google で IMEX=1 接続文字列オプションと TypeGuessRows レジストリ設定を調べてください。実際、リーダーは最初の数行 (デフォルトでは 8 行) を見て列のデータ型を推測するため、これを回避する簡単な方法はありません。行にすべての数字が含まれている場合は、運が悪いです。

私が過去に使用した不幸な回避策は、HDR=NO 接続文字列オプションを使用し、TypeGuessRows レジストリ設定値を 1 に設定することです。ヘッダー。これはハックですが、機能します。コードは最初の行 (ヘッダーを含む) をテキストとして読み取り、それに応じてデータ型を設定します。

レジストリを変更するのは面倒ですが (常に可能であるとは限りません)、後で元の値を復元することをお勧めします。

インポート データにヘッダー行がない場合、別のオプションとして、ファイルを前処理し、問題のある列の各数値の前に ' 文字を挿入します。これにより、列データがテキストとして扱われます。

全体として、これを回避するためのハックがたくさんありますが、本当に確実なものはありません。

于 2009-02-18T04:23:22.590 に答える
0

私もこれと同じ問題を抱えていましたが、Excel COM インターフェイスやサード パーティのソフトウェアに頼らずに回避できました。少し処理のオーバーヘッドがかかりますが、私にとってはうまくいっているようです。

  1. 最初にデータを読み取って列名を取得します
  2. 次に、これらの各列で新しい DataSet を作成し、各 DataType を文字列に設定します。
  3. この新しいデータセットにデータを再度読み込みます。出来上がり - 科学表記法はなくなり、すべてが文字列として読み込まれます。

これを説明するコードを次に示します。追加のボーナスとして、StyleCopped です。

public void ImportSpreadsheet(string path)
{
    string extendedProperties = "Excel 12.0;HDR=YES;IMEX=1";
    string connectionString = string.Format(
        CultureInfo.CurrentCulture,
        "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"{1}\"",
        path,
        extendedProperties);

    using (OleDbConnection connection = new OleDbConnection(connectionString))
    {
        using (OleDbCommand command = connection.CreateCommand())
        {
            command.CommandText = "SELECT * FROM [Worksheet1$]";
            connection.Open();

            using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
            using (DataSet columnDataSet = new DataSet())
            using (DataSet dataSet = new DataSet())
            {
                columnDataSet.Locale = CultureInfo.CurrentCulture;
                adapter.Fill(columnDataSet);

                if (columnDataSet.Tables.Count == 1)
                {
                    var worksheet = columnDataSet.Tables[0];

                    // Now that we have a valid worksheet read in, with column names, we can create a
                    // new DataSet with a table that has preset columns that are all of type string.
                    // This fixes a problem where the OLEDB provider is trying to guess the data types
                    // of the cells and strange data appears, such as scientific notation on some cells.
                    dataSet.Tables.Add("WorksheetData");
                    DataTable tempTable = dataSet.Tables[0];

                    foreach (DataColumn column in worksheet.Columns)
                    {
                        tempTable.Columns.Add(column.ColumnName, typeof(string));
                    }

                    adapter.Fill(dataSet, "WorksheetData");

                    if (dataSet.Tables.Count == 1)
                    {
                        worksheet = dataSet.Tables[0];

                        foreach (var row in worksheet.Rows)
                        {
                            // TODO: Consume some data.
                        }
                    }
                }
            }
        }
    }
}
于 2010-09-09T16:06:58.187 に答える
0

私は別の場所から1つの解決策を得ましたが、それは私にとって完璧に機能しました。コードを変更する必要はありません。「数値」や「テキスト」などの他の書式設定ではなく、Excel 列のセルを「一般」に書式設定するだけで、Select * from [$Sheet1] または Select Column_name from [$Sheet1] が読み取られます。 9桁を超える大きな数値でも完全に

于 2019-07-24T04:41:39.467 に答える
-1

私はこの状態をグーグルで検索しました..これが私の解決策です

  • テンプレートエクセルファイルの場合

1- Excel の列をテキストとしてフォーマット 2- 数値のエラー警告を無効にするマクロを作成 -> テキスト変換

  Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.ErrorCheckingOptions.BackgroundChecking = Ture
End Sub
Private Sub Workbook_Open()
Application.ErrorCheckingOptions.BackgroundChecking = False
End Sub
  • コードビハインドについて

3-インポートするデータの読み取り中に、受信データをInt64またはInt32に解析しようとします....

于 2011-03-08T13:54:41.517 に答える