2011-12-04 1 views
3

は、Excelブックからの読み取りを試しており、3560行7列、約1分17秒のシートを読み取るのに時間がかかることに気づいた。私がしたのは、シート全体をループして、値をリストに格納することでした。Excelワークブック - C#からの読み込みがかなり遅いですか?

これは正常ですか、何か間違っていますか?

static void Main(string[] args) 
    { 
     List<string> testList = new List<string>(); 
     Excel.Application excelApp = new Excel.Application(); 
     Excel.Workbook workbook = excelApp.Workbooks.Open(@"C:\Users\rnewell\Desktop\FxData.xlsx"); 
     Excel.Worksheet worksheet = workbook.Sheets[1]; 
     Excel.Range range = worksheet.UsedRange; 

     int rowCount = range.Rows.Count; 
     int colCount = range.Columns.Count; 



     int rowCounter = 1; 
     int colCounter = 1; 

     while (rowCounter < rowCount) 
     { 
      colCounter = 1; 
      while (colCounter <= colCount) 
      { 
       //Console.Write(range.Cells[rowCounter, colCounter].Value2.ToString() + " "); 
       testList.Add(range.Cells[rowCounter, colCounter].Value2.ToString()); 
       colCounter++; 
      } 
      Console.WriteLine(); 
      rowCounter++; 


     } 



     Console.ReadKey(); 
     excelApp.Workbooks.Close(); 


    } 
+3

範囲を読み取るためにセルをループする必要はありません。1回の操作で行うことができます。 Sergeyの答えはこちらをご覧ください:http://stackoverflow.com/questions/7919964/low-performance-when-reading-data-from-excel-workbook-to-arraylist-in-c-sharp .NETからのExcelの自動化は、一般的に( VBAを使用するよりも処理が遅くなります。これは、同じプロセス内ではなく複数のプロセスを操作しているためです。 –

+0

当分の間、私は遅れを上げます。データセットが大きすぎる場合は、このスレッドで提案されているソリューションを使用します。ありがとう – Roge

答えて

4

Open XML(* .xlsx)ファイル形式のデータを読み込んでいるので、Open XML SDKを使用することをお勧めします。あなたがコードを実行する必要がある場合は特に、良いことであるバックグラウンドでExcelを起動しませんnon-interactively

Excelでデータにアクセスするさまざまな方法については、blog postと書かれていますが、役に立つかもしれません。

2

一般に、秒数である必要があります。

しかし、アドオンを含むExcel自体のインスタンスを作成する場合、インスタンス内のすべてを初期化するのに時間がかかることがあります。

あなたの目的のために、Excelを起動しない任意のパブリックドメインExcelシート読み取りライブラリを使用することができます。

+0

私はそれをタイムアウトしたとき、私はwhileループに入る直前のタイミングを開始したので、理論的にはExcelを起動する時間は含まれていませんでした。しかし、私は完全なExcelインスタンスを使用することはおそらくここでの犯人であることに同意します。 – Roge

4

@TimWilliamsのコメントが正しい答えです。単一のセルを読み取ることは、任意のサイズの範囲を読み取る限り長くかかる。これはCOMレイヤーとの会話のオーバーヘッドであり、何千回も発生しています。範囲をobject[,]に書き込んで、その配列セルにセル単位でアクセスする必要があります。

int rowCount = range.Rows.Count; 
    int colCount = range.Columns.Count; 

    object[,] values= range.Value2; 

    int rowCounter = 1; 
    int colCounter = 1; 

    while (rowCounter < rowCount) 
    { 
     colCounter = 1; 
     while (colCounter <= colCount) 
     { 
      // check for null? 
      testList.Add(values[rowCounter, colCounter].ToString()); 
     } 
    } 

通常のC#配列と同じように、配列は0ベースではなく1ベースであることに注意してください。データは1からrowCount、1からcolCountになりますが、RowsおよびColumnsプロパティは1 + rowCountおよび1 + colCountではなくrowCountおよびcolCountを返します。データを書き戻したい場合は、適切なサイズの0ベースの配列を使用できます(実際には、1ベースの配列を作成できないため、AFAIKする必要があります)。

関連する問題