2012-01-29 77 views
1

我开始写一个小包装类来把我的Excel操作的护理:为什么搜索多张表很慢?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Excel = Microsoft.Office.Interop.Excel; 
using System.Reflection; 

namespace CSVReader 
{ 
    class ExcelManager 
    { 
     // Holds instance of application. 
     public Excel.Application application; 

     /** 
     * Class Constructor. 
     */ 
     public ExcelManager() 
     { 
      // Create a new application instance. 
      application = new Excel.Application(); 
     } 

     /** 
     * Helper to open workbooks. 
     */ 
     public void Open(string filename) { 
      application.Workbooks.Open(filename, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
               Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
               Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
               Type.Missing, Type.Missing); 
     } 

     /** 
     */ 
     public Excel.Range Find(string search) 
     { 
      Excel.Workbooks books = application.Workbooks; 

      Excel.Range currentFind = null; 
      Excel.Range firstFind = null; 

      // Search all workbooks. 
      foreach(Excel.Workbook book in books) 
      { 
       // Get first sheet. 
       Excel.Worksheet sheet = book.Worksheets.get_Item(1); 

       // Get all data for sheet. 
       Excel.Range firstCell = sheet.Range["A1", Type.Missing]; 
       Excel.Range lastCell = sheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing); 
       Excel.Range sheetData = sheet.Range[firstCell, lastCell]; 

       currentFind = sheetData.Find(search, Type.Missing, 
        Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, 
        Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false, 
        Type.Missing, Type.Missing); 

       while (currentFind != null) 
       { 
        // Keep track of the first range you find. 
        if (firstFind == null) 
        { 
         firstFind = currentFind; 
        } 

        // If you didn't move to a new range, you are done. 
        else if (currentFind.get_Address(Type.Missing, Type.Missing, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing) 
          == firstFind.get_Address(Type.Missing, Type.Missing, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing)) 
        { 
         break; 
        } 

        currentFind = sheetData.FindNext(currentFind); 
       } 
      } 

      return currentFind; 
     } 
    } 
} 

我实例化类,并告诉它加载两个工作簿和搜索字符串:

ExcelManager manager = new ExcelManager(); 

manager.Open(@"c:\test\test1.xls"); 
manager.Open(@"c:\test\test2.XLS"); 

Excel.Range result = manager.Find('test cell'); 
if (result != null) 
{ 
    // Do something funky. 
} 
else 
{ 
    // Use a log file instead. 
    Console.WriteLine("item was not found found in the current sheet."); 
} 

问题当我运行这个代码时,它的速度非常慢,即使是小型的工作簿也是如此。我的C#知识很少,所以我一整天都在关注教程。这是一个很好的方式去搜索多张表吗?会使用OLE更快吗?此应用程序的目的仅仅是运行检查来汇总未显示在打开的工作簿中的任何工作表中的值。

+0

定义令人难以置信的缓慢。主要的问题是你搜索了很多领域,这意味着全部阅读(excel实际上并没有索引或其他的概念)。这通常是要避免的 - 没有多大意义。只要你需要它,你必须吃,这需要一些时间。 – TomTom 2012-01-29 12:43:55

+0

令人难以置信的慢10分钟。我明白你对很多领域的看法。也许我可以缩小它的范围。我希望能够搜索各个栏目。 – backdesk 2012-01-29 12:48:53

+0

我有一个问题,看看所有的领域是如何合理的 - 但这纯粹来自商业点。问题是 - 这可能是非常多的非数据字段。 – TomTom 2012-01-29 12:54:07

回答

0

我的第一反应是互操作使用你的Excel安装来收集信息。任何来自Excel安装的初始化逻辑都将运行,并且会使代码的加载时间非常缓慢。

你可以做什么来测试是否是这种情况: 基准测试哪个函数调用使搜索变慢。 find函数或者你的ExcelManager类/ open函数的加载。

如果事实证明速度损失不是由find函数引起的,你可能会考虑一个解析文件本身而不是使用interop的库。