【问题标题】:looking for a searching in excel programm在excel程序中寻找搜索
【发布时间】:2021-12-10 00:11:47
【问题描述】:

我正在寻找可以读取 Excel 文档并可以在该文档中搜索单词的程序 谢谢 使用此代码可以读取所有单元格,但我想添加可以搜索我输入的单词的功能(console.readLine)

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

namespace ReadFromExcelComponente
{


    class Program
    {
        static void Main(string[] args)
        {
            //lese den excel
            Excel.Application ExcelApp;
            Excel.Workbook workbook;
            Excel.Worksheet worksheet;
            Excel.Range range;
            int row = 0;              
            int column = 0;             

            ExcelApp = new Excel.Application();
            workbook = ExcelApp.Workbooks.Open(@"D:\Map", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
            worksheet = (Excel.Worksheet)workbook.Worksheets.get_Item(1);

            range = worksheet.UsedRange;

            List<String> myList = new List<string>();
            for (row = 1; row <= range.Rows.Count; row++)
            {
                for (column = 1; column <= range.Columns.Count; column++)
                {
                    Console.WriteLine(" Coulmn Number: " + column + "--> " + (range.Cells[row, column] as Excel.Range).Value2);
                    myList.Add(range.Cells[column].ToString());
                }
            }

            Console.WriteLine(myList[2]);
            Console.WriteLine(range.Cells[2, 2].Value);




            workbook.Close(true, null, null);
            ExcelApp.Quit();

            Console.ReadKey();

        } 


    }
}

【问题讨论】:

  • 欢迎来到 SO。我假设您没有收到任何错误。如果您有包含工作表中单元格值的列表myList,那么您不能在myList 中“搜索”您要查找的单词吗?另外,如果您确实找到了搜索词的匹配项,您希望发生什么?另外,您是否需要使用Interop.Excel?我只是说还有其他第三方 Excel 阅读器做得更好。
  • 最后,您应该“释放”您的代码创建的 COM 对象,即 Excel 应用程序和工作簿。关闭工作簿并退出应用程序是不够的……如果您多次运行代码,那么,请查看 Windows 任务管理器……我敢打赌,您会看到许多 Excel 应用程序在后台运行。这被称为“泄漏”资源,您希望避免这种情况。

标签: c# excel search readfile


【解决方案1】:

当“您的代码”启动 Excel 应用程序并打开一个 Excel 文件时……然后您的代码将负责“释放”它创建的 COM 对象……即……工作簿和 Excel 应用程序。

如果您不释放这些对象,就像您当前的代码那样,那么这些对象将作为活动对象保留在内存中,并且基本上永远不会被释放。即使您的代码关闭了文件和 Excel 应用程序……您的代码仍然必须明确“释放”COM 对象。当然,如果您重新启动机器甚至退出应用程序……那么这些对象可能/将会被释放。

幸运的是,管理 Excel 资源并不难。一种相当直接的方法是使用try/catch/finally 语句来管理资源。 try 部分是我们放置所有处理 Excel 文件的代码的地方。 catch 部分用于明显捕获异常。 finally 部分是我们放置代码以“释放” Excel COM 对象的位置。

通过这种方法,我们应该能够更轻松地知道 COM 对象仍将被释放……即使代码在使用 Excel 文件时崩溃。

接下来,我知道有时您必须使用Interop 来处理 Excel 文件,而我经常使用它并且知道它可能会很尴尬。更不用说Interop 是出了名的慢,尤其是在处理大型 Excel 文件时。我的观点是,如果您确实可以选择,我强烈推荐第三方 Excel 库。有很多可供选择,有些是免费的。

从我的肥皂盒上下来……

查看您的代码,当代码从 Excel 工作表中获取 UsedRange 时,我没有关注一件事……

range = worksheet.UsedRange;

这个range 是一个基本的Excel Range 对象,其中包含工作表中所有“使用”的单元格。到目前为止一切顺利……

但是……稍后我们看到 for 的双循环遍历 range 的行和列。然后代码将每个单元格的值放入 (List&lt;string&gt;) myList。这将起作用,但似乎没有必要。即使您想在所有单元格中搜索单词,也无需将单元格值放入列表中……您已经在 range 变量中找到了单元格!换句话说,不是将单词添加到列表中,而是循环遍历range 并搜索它。

当我说你有 range 可以使用时,这意味着 Excel.Range 对象。而且您已经知道,您可以轻松地循环遍历该 range 对象,就像您的代码演示的那样……但是……如果 range 很大,那么您会注意到性能受到显着影响。底线是“循环”通过Excel.Range'es 既昂贵又缓慢。

基本上我们希望通过range 最小化任何循环。一种可能的解决方案是将 range 转换为两 (2) 维 Object 数组。然后,通过Object 数组执行所有循环,这应该会明显更快,并且使代码更易于阅读。

因此,这行代码……

range = worksheet.UsedRange;

可能最终看起来像……

range = worksheet.UsedRange;
object[,] worksheetValues = (object[,])range.Cells.Value;

现在,我们可以循环遍历 worksheetValues 数组而不是 range 本身。

这个“应该”替换 mylist 变量,因为它不是必需的……所有值都在 worksheetValues 数组中。

现在我们有了一个简单的对象数组来“搜索”……那么我们所需要的只是一个要查找的搜索词。如果我们从用户那里获得搜索词,那么我们可以创建一个方法,该方法使用该搜索词和数组进行搜索,并返回搜索词匹配的单元格的所有 X 和 Y 坐标。这种方法可能看起来像……

private static List<Point> FindWordInArray(string target, object[,] data) {
  List<Point> foundIndexes = new List<Point>();
  for (int row = 1; row <= data.GetLength(0); row++) {
    for (int col = 1; col <= data.GetLength(1); col++) {
      if (data[row, col] != null) {
        if (data[row, col].ToString().Equals(target)) {
          foundIndexes.Add(new Point { X = col, Y = row });
        }
      }
    }
  }
  return foundIndexes;
}


public class Point {
  public int X { get; set; }
  public int Y { get; set; }
}

我知道Point 类可能不需要,只是为了简化示例。

以下是上述内容的一个小而完整的示例。这包括设置try/catch/finally 代码以及释放COM 对象。

注意:Excel 从 1 开始数组索引。因此对象数组 worksheetValues 将从索引 1 开始。

Excel.Application ExcelApp = null;
Excel.Workbook workbook = null;
Excel.Worksheet worksheet= null;
Excel.Range range = null;
string searchWord = "";
try {
  ExcelApp = new Excel.Application();
  workbook = ExcelApp.Workbooks.Open(@"D:\Map", 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
  worksheet = (Excel.Worksheet)workbook.Worksheets.get_Item(1);
  range = worksheet.UsedRange;
  object[,] worksheetValues = (object[,])range.Cells.Value;
  Console.WriteLine("There are " + worksheetValues.GetLength(0) + " Rows and " + worksheetValues.GetLength(1) + " Columns");
  for (int row = 1; row <= worksheetValues.GetLength(0); row++) {
    Console.Write("Row " + row + ": ");
    for (int col = 1; col <= worksheetValues.GetLength(1); col++) {
      if (worksheetValues[row, col] != null) {
        Console.Write(worksheetValues[row, col]);
      }
      else {
        Console.Write(" - ");
      }
    }
    Console.WriteLine();
  }
  Console.WriteLine("Type the word you want to search for...");
  searchWord = Console.ReadLine().Trim();
  List<Point> foundItems = FindWordInArray(searchWord, worksheetValues);
  foreach (Point point in foundItems) {
    Console.WriteLine("Found at Row: " + point.Y + " - Col: " + point.X);
  }
}
catch (Exception ex) {
  Console.WriteLine("Excel error: " + ex.Message);
}
finally {
  if (range != null) {
    Marshal.ReleaseComObject(range);
  }
  if (worksheet != null) {
    Marshal.ReleaseComObject(worksheet);
  }
  if (workbook != null) {
    workbook.Close(true, null, null);
    Marshal.ReleaseComObject(workbook);
  }
  if (ExcelApp != null) {
    ExcelApp.Quit();
    Marshal.ReleaseComObject(ExcelApp);
  }
}

我希望这有意义并有所帮助。

【讨论】:

    【解决方案2】:

    试试这个:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Excel = Microsoft.Office.Interop.Excel;
    
    namespace ReadFromExcelComponente
    {
    
    
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter the word you want to search for:");
            string SearchWord = Console.ReadLine();
            //lese den excel
            Excel.Application ExcelApp;
            Excel.Workbook workbook;
            Excel.Worksheet worksheet;
            Excel.Range range;
            int row = 0;              
            int column = 0;             
    
            ExcelApp = new Excel.Application();
            workbook = ExcelApp.Workbooks.Open(@"D:\Map", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
            worksheet = (Excel.Worksheet)workbook.Worksheets.get_Item(1);
    
            range = worksheet.UsedRange;
    
            for (row = 1; row <= range.Rows.Count; row++)
            {
                for (column = 1; column <= range.Columns.Count; column++)
                {
                   if(range.Range(row, column).Value = SearchWord)
                     {
                      Console.WriteLine("Found word!");
                      break;
                   }
                }
            }
    
            Console.WriteLine(myList[2]);
            Console.WriteLine(range.Cells[2, 2].Value);
    
    
    
    
            workbook.Close(true, null, null);
            ExcelApp.Quit();
            ExcelApp = null;
            Console.ReadKey();
    
        } 
    }
          }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多