C# 计数具有特定值的单元格-线程通信
我需要知道特定列(列“C”)中具有特定值(“DE”或“CH”或“AT”)的行数 目前,我正在使用for循环,这是可行的,但问题是,我的程序需要将近10分钟才能完成excel工作表中的40k行 有没有办法更快地获取这些信息 编辑: 我现在有一个问题,我有3个线程使用同一个Excel工作表,当我等待“//MessageBox.Show(“Es gibt”+Convert.ToString(count)+“Verträge für”+searchword+”)时,这没有问题;所有线程都准备好了,单击OK。 当我不等待它时,我从Excel(下图)得到两个提示,程序崩溃 在我看来,当第一个线程准备就绪时,它会关闭excelsheet和应用程序,而其他线程对此有问题吗? 当程序崩溃时,会显示“来自HRESULT的异常:0x800AC472”(注释) 有什么想法吗 下一个问题是:为了从线程到主窗体获取信息,我使用了一个.txt文件,有没有什么好方法可以将信息返回到主窗体,或者让线程彼此通信?这个结论不是很好:/C# 计数具有特定值的单元格-线程通信,c#,multithreading,excel,C#,Multithreading,Excel,我需要知道特定列(列“C”)中具有特定值(“DE”或“CH”或“AT”)的行数 目前,我正在使用for循环,这是可行的,但问题是,我的程序需要将近10分钟才能完成excel工作表中的40k行 有没有办法更快地获取这些信息 编辑: 我现在有一个问题,我有3个线程使用同一个Excel工作表,当我等待“//MessageBox.Show(“Es gibt”+Convert.ToString(count)+“Verträge für”+searchword+”)时,这没有问题;所有线程都准备好了,单击O
class RowCheckThread
{
public RowCheckThread()
{
}
public void asdf()
{
string localrow = row;
string localsearchword = searchword;
string localfile = file;
Excel.Application ExcelApp = new Excel.Application();
Excel.Workbook ExcelWorkBook = ExcelApp.Workbooks.Open(localfile);
Excel.Sheets ExcelSheets = ExcelWorkBook.Worksheets;
Excel.Worksheet Sheet = (Excel.Worksheet)ExcelWorkBook.Worksheets.get_Item(1);
Excel.Range allCellsInColumn = Sheet.get_Range(localrow + ":" + localrow);
//
Excel.Range usedCells = allCellsInColumn.Find(localsearchword, LookAt: Excel.XlLookAt.xlWhole, SearchOrder: Excel.XlSearchOrder.xlByRows, SearchDirection: Excel.XlSearchDirection.xlNext);//Sucht ersten wert mit searchwort
string firstFound = usedCells.get_Address();
Excel.Range next = allCellsInColumn.FindNext(usedCells);
string nextFound = next.get_Address();
int count = 1;
while (nextFound != firstFound)
{
next = allCellsInColumn.FindNext(next);//Exception from HRESULT: 0x800AC472
nextFound = next.get_Address();
count++;
if (KeepAlive == false)
{
ExcelWorkBook.Close();
ExcelApp.Quit();
return;
}
}
//MessageBox.Show("Es gibt " + Convert.ToString(count) + " Verträge für " + searchword + "!");
ExcelWorkBook.Close();
ExcelApp.Quit();
string path = System.IO.Path.GetTempPath() + "test.txt";
int wert = 0;
if(File.Exists(path))
{
StreamReader myFile = new StreamReader(path, System.Text.Encoding.Default);
wert = Convert.ToInt32(myFile.ReadToEnd());
myFile.Close();
}
wert = wert + count;
StreamWriter tempfile = new StreamWriter(path);
tempfile.Write(wert);
tempfile.Close();
}
public string row { get; set; }
public string searchword { get; set; }
public string file { get; set; }
public bool KeepAlive { get; set; }
}
如果您仍然要自动运行Excel,那么最好使用
WorksheetFunction.CountIf
使用此函数,您只需给出范围和匹配条件
该呼叫将如下所示:
Application.WorksheetFunction.CountIf(yourRange, "DE");
如果在40000个细胞范围内这需要几秒钟的时间,我会感到惊讶
函数的文档是。请尝试以下代码,在第二列中搜索关键字“DE”
发布您的循环代码,以便我们提供足够的信息。没有比for循环更快的循环,除非您可以异步处理信息,在这种情况下,请使用Parallel.for()。我不想要更快的循环,而是另一种解决方案。Gun works的答案是,现在需要44秒,这对我来说没关系。什么是“yourRange”,需要哪种格式?我在谷歌上找不到任何东西。给出上面的代码,是不是
ExcelApp.WorksheetFunction.CountIf(yourRange,“DE”)代码>?它是一个范围
对象。有关此函数的文档,请参阅我文章中的链接。太棒了!很高兴它起作用了。在这种情况下,你可以考虑将它作为正确的答案。
Excel.Application ExcelApp = new Excel.Application();
Excel.Workbook ExcelWorkBook = ExcelApp.Workbooks.Open(@"E:\test.xlsx");
Excel.Sheets ExcelSheets = ExcelWorkBook.Worksheets;
Excel.Worksheet Sheet = (Excel.Worksheet)ExcelSheets.get_Item("Sheet1");
Excel.Range allCellsInColumn = Sheet.get_Range("B:B");
Excel.Range usedCells = allCellsInColumn.Find("DE", LookAt: Excel.XlLookAt.xlWhole, SearchOrder: Excel.XlSearchOrder.xlByRows, SearchDirection: Excel.XlSearchDirection.xlNext);
string firstFound = usedCells.get_Address();
Excel.Range next = allCellsInColumn.FindNext(usedCells);
string nextFound = next.get_Address();
int count = 1;
while (nextFound != firstFound)
{
next = allCellsInColumn.FindNext(next);
nextFound = next.get_Address();
count++;
}
Console.WriteLine("Search Found in {0} Rows",count);
ExcelWorkBook.Save();
ExcelWorkBook.Close();
ExcelApp.Quit();