2017-07-25 7 views
0

私はクライアントと連携して、かなり大きなExcelファイル(37K行以上)をカスタムシステムにインポートし、優れたLinqToExcelライブラリを利用しています。すべてのデータを読み込んでいるうちに、レコードを80%ほど壊していて、もう少し掘り下げていたことに気付きました。それが失敗する理由は、大部分のレコード(関連する日付が2011年〜2015年)は正常です。 1/3/2015ですが、2016年以降は構造体が'1/4/2016(日付の冒頭に「tick」と書かれています)に変わり、LinqToExcelがその列のDBNullを返すようになります。LinqToExcelの解析日がありません

それがそれを行う方法とその方法についてのアイデアはありますか?これはキャストの問題ではないことに注意してください。イミディエイトウィンドウを使用してLinqToExcel.Row値のすべての値を表示し、その列インデックスがどこにあるかは空です。ここで

編集

は、私は、ファイルを読み込むために使用していますコードです:

var excel = new LinqToExcel.ExcelQueryFactory(Path.Combine(this.FilePath, this.CurrentFilename)); 
foreach (var row in excel.Worksheet(file.WorksheetName)) 
{ 
    data.Add(this.FillEntity(row)); 
} 

私が参照してる問題はLinqToExcel.Rowインスタンスであるrow変数、内側にあり、 Excelの生データが含まれています。 row内の値はすべて空白の日付の列を除いて並んでいます。

** 編集2 **

私はGitHubのからLinqToExcelコードをダウンロードし、自分のプロジェクトに接続されており、問題は、このライブラリーよりもさらに深いように見えます。 IDataReaderを使用してすべての値を読み取ると、読み取られていない問題のセルはそのレベルから空になります。ここで失敗している LinqToExcel.ExcelQueryExecutorクラスからのコードのブロックです:

private IEnumerable<object> GetRowResults(IDataReader data, IEnumerable<string> columns) 
    { 
     var results = new List<object>(); 
     var columnIndexMapping = new Dictionary<string, int>(); 
     for (var i = 0; i < columns.Count(); i++) 
      columnIndexMapping[columns.ElementAt(i)] = i; 

     while (data.Read()) 
     { 
      IList<Cell> cells = new List<Cell>(); 
      for (var i = 0; i < columns.Count(); i++) 
      { 
       var value = data[i]; 

       //I added this in, since the worksheet has over 37K rows and 
       //I needed to snag right before it hit the values I was looking for 
       //to see what the IDataReader was exposing. The row inside the 
       //IDataReader relevant to the column I'm referencing is null, 
       //even though the data definitely exists in the Excel file 
       if (value.GetType() == typeof(DateTime) && value.Cast<DateTime>() == new DateTime(2015, 12, 31)) 
       { 
       } 



       value = TrimStringValue(value); 
       cells.Add(new Cell(value)); 
      } 
      results.CallMethod("Add", new Row(cells, columnIndexMapping)); 
     } 
     return results.AsEnumerable(); 
    } 

そのクラスは結果を取得するためにOleDbDataReaderを使用しているので、私はそれが問題のセルの値を見つけることができない何だと思います。私はそこからどこへ行くかわからない。

+1

日付が有効になるようにExcelスプレッドシートをクリーニングするオプションはありますか? – mjwills

+0

私はクライアントから適切なものを取得しようとしています。そうしないと、手作業での編集が唯一のオプションになり、修正する5Kレコードの北です。私はこの価値が他の何よりも一般的に読み取ることができないことに、より驚いています。 – RubyHaus

+0

私のコードではありません。LinqToExcelライブラリ自体の一部です。それは値を正しく読まないことです。 – RubyHaus

答えて

0

見つけました!いったん私はそれがLinqToExcelライブラリ自体ではなく、失敗していたOleDbDataReaderであると辿ったところ、私は別の道を見て周りを見回しました。明らかにExcelファイルがOleDbDataReaderで読み込まれると(ほとんどすべてのユーティリティがカバーしているので)、最初のいくつかのレコードがスキャンされて、列に関連付けられたコンテンツのタイプが判別されます。私のシナリオでは、20Kを超えるレコードは「通常」の日付を持っていたので、すべてが日付だったと仮定しました。一度それが "悪い"レコードになったら、日付の前の'は日付に解析できないことを意味したので、値はnullでした。

これを回避するために、ファイルをロードし、列ヘッダーを無視するように指示します。この列のヘッダーは文字列であり、ほとんどの値は日付なので、型が一致しないためにすべてが文字列になり、必要な値が適切に読み込まれます。そこから、私はそれに応じて解析して動作させることができます。

ソース:What is IMEX in the OLEDB connection string?

+0

私はLinqToExcelが最初の行(ヘッダー行)をデフォルトで無視したと考えました。私はそれについて間違っていますか? – Rod

+1

これはオプションの設定です。この側のデータは非常に悪かったので、これはLinqToExcelの欠点ではないと私は考えています。 – RubyHaus

関連する問題