2

ブックのすべてのシートのすべてのセルを列挙する最も効率的な方法は何ですか?

以下の方法は、約130,000セルのワークブックで適切に機能するようです。私のマシンでは、ファイルを開くのに約26秒、セルを列挙するのに約5秒かかりました。ただし、私はExcelの専門家ではないため、このコードスニペットをより広いコミュニティで検証したいと考えていました。

DateTime timer = DateTime.Now;
Microsoft.Office.Interop.Excel.Application excelApplication = new Microsoft.Office.Interop.Excel.Application();
try
{
    exampleFile = new FileInfo(Path.Combine(System.Environment.CurrentDirectory, "Large.xlsx"));
    excelApplication.Workbooks.Open(exampleFile.FullName, false, false, missing, missing, missing, true, missing, missing, true, missing, missing, missing, missing, missing);
    Console.WriteLine(string.Format("Took {0} seconds to open file", (DateTime.Now - timer).Seconds.ToString()));

    timer = DateTime.Now;
    foreach(Workbook workbook in excelApplication.Workbooks)
    {
            foreach(Worksheet sheet in workbook.Sheets)
            {
            int i = 0, iRowMax, iColMax;
            string data = String.Empty;

            Object[,] rangeData = (System.Object[,]) sheet.UsedRange.Cells.get_Value(missing);

            if (rangeData != null)
            {
                iRowMax = rangeData.GetUpperBound(0);                       
                iColMax = rangeData.GetUpperBound(1);                                                       

                for (int iRow = 1; iRow < iRowMax; iRow++)
                {
                        for(int iCol = 1; iCol < iColMax; iCol++)
                    {
                        data = rangeData[iRow, iCol] != null ? rangeData[iRow, iCol].ToString() : string.Empty;
                        if (i % 100 == 0)
                        {
                            Console.WriteLine(String.Format("Processed {0} cells.", i));
                        }

                        i++;
                    }                                                                                                   
                }   
            }
        }

        workbook.Close(false, missing, missing);
    }

    Console.WriteLine(string.Format("Took {0} seconds to parse file", (DateTime.Now - timer).Seconds.ToString()));              
    }
    finally
    {
        excelApplication.Workbooks.Close();             
        excelApplication.Quit();                  
    }                   

編集

Excelファイルで直接機能するAPIによって公開されていないExcelブックのプロパティにアクセスするために、PIAと相互運用機能を使用したいことを述べる価値があります。

4

3 に答える 3

2

Koograと呼ばれるExcelリーダーおよびライターのオープンソース実装があります。これにより、Excelファイルを読み込んで、純粋なマネージコードを使用して変更できます。これはおそらく、現在使用しているコードよりもはるかに高速です。

于 2008-11-04T10:57:50.707 に答える
2

Excel PIA Interop は、セルごとに処理を行うと非常に遅くなります。

プロパティで行ったように、抽出する範囲を選択し、次Worksheet.UsedRangeを呼び出してget_Value()(または単にValueorValue2プロパティを読み取るだけで、どちらを思い出せません) 1 つのステップで範囲全体の値を読み取る必要があります。それ。

これにより、object[,]簡単に列挙でき、すぐに読み取れる 、つまり 2 次元配列が生成されます。

編集:私はあなたの実際のコードを読んだところ、それが実際に私が提案したことを実行することに気付きました。答える前に質問をきちんと読んでいないことを恥じてください。その場合、これ以上速くすることはできません。Excel PIA Interop が遅い。より迅速な解決策が必要な場合は、jExcelApi を Java から C# に移行する (それほど難しいことではありません) か、商用コンポーネントを使用する必要があります。あなたの正気を保つために、OLEDBインターフェースを絶対に避けることをお勧めします。

無関係ですが、役立つヒント: ?? を使用する必要があります。オペレーター。本当に便利です。それ以外の

data = rangeData[iRow, iCol] != null ? rangeData[iRow, iCol].ToString() : string.Empty;

あなたはただ書くことができます

data = Convert.ToString(rangeData[iRow, iCol]) ?? string.Empty;

その場合、Convert.ToString(object)nullはとにかく空の文字列に 変換されるため、String.Empty も必要ありません。

于 2008-11-04T10:11:51.300 に答える
1

私は、これが最も効率的な方法だと思います.PIAでそれを行う方法. 「for」の代わりに「foreach」を使用すると少し速くなるかもしれませんが、劇的な変化はありません。

効率が主な目標である場合は、Excel アプリケーションを使用せずに、Excel ファイルを直接操作する必要があります。

于 2008-11-04T10:37:56.660 に答える