计算具有特定值的单元格 - 线程通信

时间:2014-03-06 15:44:50

标签: c# multithreading excel

我需要知道特定列(“C”列)中具有特定值(“DE”或“CH”或“AT”)的行数

在片刻我正在使用for循环,这可行,但问题是,我的程序需要将近10分钟才能通过我的Excel工作表的40k行

有没有办法更快地获取此信息?

编辑:

我现在遇到问题,我有3个线程使用相同的Excel表格,没有问题,当我等待“//MessageBox.Show("Es gibt”+ Convert.ToString(count)+“ Verträgefür“+ searchword +”!“);”对于所有线程,并在所有线程准备好后单击“确定”。 当我不等待它时,我会从Excel中获得2个提示(下图)并且程序崩溃。

正如我所看到的,当第一个线程准备就绪时,它会关闭excelsheet和App,其他线程有问题吗? 当程序崩溃时,它显示“HRESULT异常:0x800AC472”(已评论) 任何的想法?

下一个问题是:要从Thread获取信息到主窗体,我使用.txt文件,是否有任何好的方法将信息返回到主窗体或让线程相互通信?这个结论并不是很好:/

ExcelPrompt

    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; }




}

2 个答案:

答案 0 :(得分:1)

如果您要自动执行Excel,也可以使用WorksheetFunction.CountIf

使用此功能,您只需给出范围和匹配标准。

电话会看起来像这样:

Application.WorksheetFunction.CountIf(yourRange, "DE");

如果在40,000个电池范围内花费超过几秒钟,我会感到惊讶。

该功能的文档是here

答案 1 :(得分:1)

Jochot尝试以下代码,在第二列中搜索关键字“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();