Pourquoi la search de plusieurs feuilles est-elle si lente?

J'ai commencé à écrire une petite class wrapper pour m'occuper de mes opérations 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(ssortingng 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(ssortingng 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; } } } 

Je crée une instanciation dans la class et requestz-lui de charger deux classurs et de searchr une string:

 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."); } Gestionnaire ExcelManager = nouveau ExcelManager (); 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."); } manager.Open (@ "c: \ test \ test1.xls"); 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."); } manager.Open (@ "c: \ test \ test2.XLS"); 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."); } Excel.Range result = manager.Find ('cellule de test'); 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."); } if (result! = null) 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."); } // Faites quelque chose de génial. 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."); } // Utilisez un file journal à la place. 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."); } Console.WriteLine ("l'élément n'a pas été trouvé dans la feuille actuelle"); 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."); } 

Le problème est quand je cours ce code, il est incroyablement lent, même avec des classurs de petite taille. Ma connaissance C # est minime, donc j'ai suivi les tutoriels toute la journée. Est-ce un bon moyen de searchr des feuilles multiples? utiliser OLE plus rapidement? Le but de cette application est simplement d'exécuter un contrôle pour résumer les valeurs qui n'apparaissent dans aucune des feuilles de mes classurs ouverts.

Ma première réponse serait que l'interop utilise votre installation Excel pour rassembler les informations. Toute logique d'initialisation à partir de l'installation Excel sera exécutée et permettra un time de chargement très lent du code.

Ce que vous pouvez faire pour tester si c'est le cas: Benchmark lequel des appels de la fonction rend la search lente. La fonction de search ou le chargement de votre class ExcelManager / la fonction ouverte.

S'il s'avère que la perte de vitesse n'est pas causée par la fonction de search, vous pouvez considérer une bibliothèque qui parsing le file lui-même au lieu d'utiliser interop.