繁体   English   中英

代码有时会运行到完成状态,但不一定总是得到相同的输入

[英]Code runs to completion sometimes, but not always given the same inputs

以下程序在第1列中输入具有产品ID(以MT或MU开头)的excel文件。 然后,它会按采购订单(PO)进行检查,这些订单包含按供应商提供的文件夹中的产品ID,并按年份包含子文件夹。 用户输入文件夹路径并指定要搜索的年份。 然后,程序将在用户指定的原始电子表格中产品ID旁边的列中返回最近的供应商,价格和日期。 该程序大约需要3到4个小时来运行10,000个产品ID和价值一年的PO(数百个PO)。 有时它完成了(有一个消息框显示完成时已完成),有时它没有给出完全相同的输入。 没有错误,但是CPU使用率突然从大约40%变为1%有人知道为什么吗?

    string filepath = "";
    string folderpath = "";

    private void button1_Click(object sender, EventArgs e)
    {
        //New Excel App
        Excel._Application oApp = new Excel.Application();
        oApp.Visible = true;


        //Opens Worksheet to be updated
        Excel.Workbook oWorkbook = oApp.Workbooks.Open(filepath);
        Excel.Worksheet oWorksheet = oWorkbook.Worksheets["Sheet1"];

        //Takes all MT/MU numbers from first column of worksheet needing updating and puts them into a string
        Excel.Range firstColumn = oWorksheet.UsedRange.Columns[1];
        System.Array myvalues = (System.Array)firstColumn.Cells.Value;
        string[] strArray = myvalues.OfType<object>().Select(o => o.ToString()).ToArray();

        //Specify what year to begin and end looking at POs
        int beginYear = Convert.ToInt32(textBox2.Text);
        beginYear = int.Parse(textBox2.Text);
        int endYear = Convert.ToInt32(textBox3.Text);
        endYear = int.Parse(textBox3.Text);
        int count = 0;
        List<string> yearList = new List<string>();
        while (count <= endYear-beginYear )
        {
            int addYear = beginYear + count;
            string addYearString = addYear.ToString();
            yearList.Add(addYearString);
            count++;

        }
        string[] years = yearList.ToArray();


       foreach (string year in years)
        {
            //Creates array of all excel files existing in path (including subdirectories) in folder chosen by user
            IEnumerable<string> files =
            from f in Directory.GetFiles(folderpath, "*.xls", SearchOption.AllDirectories)
            where Path.GetDirectoryName(f).Contains(year)
            select f;

            foreach (string file in files)
            {
                //Opens file
                Excel._Application oApp2 = new Excel.Application();
                oApp2.Visible = false;
                Excel.Workbook PO = oApp2.Workbooks.Open(file);
                Excel.Worksheet oWorksheet2 = PO.Worksheets["Sheet1"];

                foreach (string item in strArray)
                {
                    Excel.Range currentFind = null;
                    string newestDateSoFar = "01/01/1900";
                    DateTime newestDateTimeSoFar = Convert.ToDateTime(newestDateSoFar);

                    object misValue = System.Reflection.Missing.Value;

                    Excel.Range xlRange = oWorksheet2.get_Range("C1");

                    //Looks through column for MT/MU number
                    currentFind = xlRange.EntireColumn.Find(item,
                    misValue, Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart,
                    Excel.XlSearchOrder.xlByColumns, Excel.XlSearchDirection.xlNext,
                    true, misValue, misValue);

                    //If there is a match in the PO
                    if (currentFind != null)
                    {

                        //Get Date on PO
                        string currentDate = null;
                        DateTime currentDateTime = Convert.ToDateTime(currentDate);
                        if (oWorksheet2.Cells[6, 6].Value != null)
                        {
                            currentDate = oWorksheet2.Cells[6, 6].Value.ToString();
                            currentDateTime = Convert.ToDateTime(currentDate);
                        }

                        Excel.Range xlRange2 = oWorksheet.get_Range("A1");

                        //Looks through column of worksheet needing updating for MT/MU number, so can compare date
                        Excel.Range needsUpdatingFind = xlRange2.EntireColumn.Find(item,
                        misValue, Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart,
                        Excel.XlSearchOrder.xlByColumns, Excel.XlSearchDirection.xlNext,
                        true, misValue, misValue);

                        int dateColumn = Convert.ToInt32(textBox4.Text);
                        dateColumn = int.Parse(textBox4.Text);
                        if (needsUpdatingFind.get_Offset(0, dateColumn-1).Value != null)
                        {
                            newestDateSoFar = needsUpdatingFind.Offset[0, dateColumn-1].Value.ToString();
                            newestDateTimeSoFar = Convert.ToDateTime(newestDateSoFar);
                        }



                        //If Date on PO is most recent, get information that needs updating         
                        if (currentDateTime > newestDateTimeSoFar || needsUpdatingFind.get_Offset(0, dateColumn - 1).Value == null)
                        {

                            //Gets assosciated price and sets it in worksheet that needs updating
                            string price = null;
                            int priceColumn = Convert.ToInt32(textBox6.Text);
                            priceColumn = int.Parse(textBox6.Text);
                            if (currentFind.get_Offset(0, 2).Value != null)
                            {
                                price = currentFind.get_Offset(0, 2).Value.ToString();
                                needsUpdatingFind.Offset[0, priceColumn-1].Value = price;
                            }
                            else if (currentFind.get_Offset(-1, 2).Value != null)
                            {
                                price = currentFind.get_Offset(-1, 2).Value.ToString();
                                needsUpdatingFind.Offset[0, priceColumn-1].Value = price;
                            }
                            else if (currentFind.get_Offset(-2, 2).Value != null)
                            {
                                price = currentFind.get_Offset(-2, 2).Value.ToString();
                                needsUpdatingFind.Offset[0, priceColumn-1].Value = price;
                            }
                            else if (currentFind.get_Offset(-3, 2).Value != null)
                            {
                                price = currentFind.get_Offset(-3, 2).Value.ToString();
                                needsUpdatingFind.Offset[0, priceColumn-1].Value = price;
                            }
                            else if (currentFind.get_Offset(-4, 2).Value != null)
                            {
                                price = currentFind.get_Offset(-4, 2).Value.ToString();
                                needsUpdatingFind.Offset[0, priceColumn-1].Value = price;
                            }
                            else if (currentFind.get_Offset(-5, 2).Value != null)
                            {
                                price = currentFind.get_Offset(-5, 2).Value.ToString();
                                needsUpdatingFind.Offset[0, priceColumn-1].Value = price;
                            }

                            //Gets assosciated supplier and sets it in worksheet that needs updating
                            int supplierColumn = Convert.ToInt32(textBox5.Text);
                            supplierColumn = int.Parse(textBox5.Text);
                            string supplier = oWorksheet2.Cells[6, 2].Value.ToString();
                            needsUpdatingFind.Offset[0, supplierColumn-1].Value = supplier;

                            //Gets assosciated PO date and sets it in worksheet that needs updating

                            needsUpdatingFind.Offset[0, dateColumn-1].Value = currentDateTime.ToString();

                            //Resets current find
                            currentFind = null;
                            needsUpdatingFind = null;

                        }
                        while (Marshal.ReleaseComObject(xlRange2) != 0) { }


                        xlRange2 = null;


                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                    }


                    while (Marshal.ReleaseComObject(xlRange) != 0) { }


                    xlRange = null;

                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
                //Closes PO
                object missing = System.Reflection.Missing.Value;
                PO.Close(false, missing, missing);

                //Quits Excel
                oApp2.Quit();

                //Manual disposal because of COM
                while (Marshal.ReleaseComObject(oApp2) != 0) { }
                while (Marshal.ReleaseComObject(PO) != 0) { }
                while (Marshal.ReleaseComObject(oWorksheet2) != 0) { }


                oApp2 = null;
                PO = null;
                oWorksheet2 = null;


                GC.Collect();
                GC.WaitForPendingFinalizers();
            }

        }



        MessageBox.Show("Done");
    }

    private void button2_Click(object sender, EventArgs e)
    {

        OpenFileDialog openFileDialog1 = new OpenFileDialog();
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            filepath = openFileDialog1.FileName;
            textBox1.Text = filepath;
        }
    }

    private void button3_Click(object sender, EventArgs e)
    {
        FolderBrowserDialog openFileDialog2 = new FolderBrowserDialog();
        if (openFileDialog2.ShowDialog() == DialogResult.OK)
        {
            folderpath = openFileDialog2.SelectedPath;
            textBox7.Text = folderpath;
        }
    }
}
}

您应该使用DataSetOleDbDataAdapter将数据放入内存,然后让C#/ Linq完成工作。 听起来好像您不是在谈论很多数据,所以看来Interop是速度缓慢的根本原因。 这是一个示例/比较: 打开Excel,解析数据? 在那篇文章中,请注意ADO.Net和Interop之间的比较。 选择的答案比替代的有效答案要快得多。 看来您遇到了同样的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM