3

次のコードを使用して、さまざまな Excel ファイルからデータを読み取ります。

    // IMEX=1 - to force strings on mixed data
    // HDR=NO - to process all the available data
    // Locale 1033 is en-US. This was my first attempt to force en-US locale.
    string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Locale Identifier=1033;Extended Properties=\"{1};READONLY=TRUE;HDR=NO;IMEX=1;\"";

    // source type according to the
    // http://www.microsoft.com/en-us/download/details.aspx?id=13255

    // try determining from extension
    bool isOldFormat =
            Path.GetExtension(sourceExcel).Equals(".xls", StringComparison.OrdinalIgnoreCase);

    bool isBinary =
            Path.GetExtension(sourceExcel).Equals(".xlsb", StringComparison.OrdinalIgnoreCase);

    string sourceType = isOldFormat ? "Excel 8.0" : "Excel 12.0";

    if (!isOldFormat)
        sourceType += " Xml"; // for some reason the new binary xlsb files also need Xml

    connectionString = string.Format(connectionString, sourceExcel, sourceType);

    // this was my second attempt to force Excel to use US culture
    var oldCulture = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");

    var dt = new DataTable();
    try
    {
        using (var con = new OleDbConnection(connectionString))
        {
            con.Open();

            // get all the available sheets
            using (DataTable dataSet = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null))
            {
                // this was my third attempt to force Excel to use US culture
                dataSet.Locale = CultureInfo.CreateSpecificCulture("en-US");
                // get the sheet name in the file (will throw if out of range)
                string workSheetName = dataSet.Rows[worksheetIndex]["TABLE_NAME"].ToString();//.Trim(new[] { '$' }).Replace("'", "");

                string sql = String.Format("select * from [{0}]", workSheetName);

                var da = new OleDbDataAdapter(sql, con);
                // this was my fourth attempt to force Excel to use US culture
                dt.Locale = CultureInfo.CreateSpecificCulture("en-US");
                da.Fill(dt);
            }

            con.Close();
        }

ご覧のとおり、データをインポートするときに、Excel で en-US 互換のロケールを使用するように強制しようとして、私はかなり必死でした。私のコードはさまざまなロケールのサーバーで実行される可能性があるため、これが必要ですが、受信データが en-US/neutral ロケールであることを前提として、データには追加の処理が必要です。

CultureInfo.InvariantCultureの代わりにもしてみCultureInfo.CreateSpecificCulture("en-US")ました。

どのように試しても、サーバーのロケールが.、千の区切り記号および,小数点の記号として使用する他のロケールに設定されている場合、dt DataTable.

通貨値 -£200000.00 の結果を比較するには:

サーバーの地域設定が米国のロケールに対応している場合、"-£200,000.00"

サーバーの地域設定がラトビア語ロケールに対応している場合、"-£200 000,00"

Thread.CurrentThread.CurrentCultureOleDb はそれを完全に無視しているように見えるため、現在の数値区切り文字を使用してデータを後処理することさえできません。

OleDb は現在のカルチャをどこから取得しますか? en-USOleDbConnection または Microsoft.ACE.OLEDB.12.0 プロバイダーに、またはカルチャに従ってフォーマットされたデータが必要であることを伝えるにはどうすればよいInvariantですか?

4

1 に答える 1