不确定如何解决此NullReferenceException

问题描述 投票:0回答:1

我有一种方法,应该从excel文件中获取客户名称,客户所在的城镇和灭火器+属于这些客户的每个灭火器的序列号,然后将这些信息写入一堆单独的excel文件中,具体取决于灭火器属于哪个客户。我在此过程中途遇到了一个N​​ullReferenceException异常,似乎在一个随机的地方。我遇到此错误的所有3个电子表格上的位置都不同。还应注意,另外两个电子表格完全没有遇到困难,并且每次都能完美传输。我不愿意发布电子表格来保护客户的信息。但是,在下面您将找到错误代码,而在下面是导致这些错误的DatabaseBuilder方法。

我相信我的问题出在FirstOrDefault();方法。我已经通过调试确认,searchCell的值都不为空,并且错误仅在这些方法中发生。

public void DatabaseBuilder()
        {
            // Purpose of method:
            // Make Excel package, read Excel file, find customer data, find extg data, make customer database files, append extg data to customer database files.

            // Tests for if the user has selected a CIDB (Check-In Database) file.
            if (fileChosen == true)
            {
                // Make Excel package to lookup customer names.
                FileInfo excelFile = new FileInfo(file);
                using (ExcelPackage excel = new ExcelPackage(excelFile))
                {
                    ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
                    ExcelWorksheet workSheet = excel.Workbook.Worksheets[0];
                    // Iterate through the document.
                    var start = 2;
                    var end = workSheet.Dimension.End;
                    for (int row = start; row <= end.Row; row++)
                    {
                        // Append the Customer Name and Customer Town HashSets with the names and towns from each cell in their respective rows.
                        string custName = workSheet.Cells["O"+row].Text;
                        string custTown = workSheet.Cells["P"+row].Text;
                        string fullName = custName + " - " + custTown;
                        custNames.Add(fullName);
                    };
                    // Write the Database folder.
                    string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    string dirPathParent = path + "/Check-In Database/";
                    DirectoryInfo di = Directory.CreateDirectory(dirPathParent);
                    string dirPath = dirPathParent + "/Customer Database/";
                    DirectoryInfo dir = Directory.CreateDirectory(dirPath);
                    // Iterate through the custNames HashSet, and create a new Excel file in the database for each entry.
                    foreach (string varName in custNames)
                    {                                         
                        // Create a file for each customer.
                        string name = GetSafeFilename(varName);
                        string fullPath = dirPath + name + ".xlsx";
                        FileInfo custFile = new FileInfo(fullPath);
                        using (ExcelPackage custPkg = new ExcelPackage(custFile))
                        {
                            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
                            // Test for the worksheet existing in the customer file. If not, make one.
                            if (SheetExist(fullPath, "Extinguishers") == false)
                            {
                                custPkg.Workbook.Worksheets.Add("Extinguishers");
                            }
                            // Initialize Customer Worksheet, add and format header row.
                            ExcelWorksheet custSheet = custPkg.Workbook.Worksheets[0];
                            custSheet.Cells["A1"].Value = "Model Num.";
                            custSheet.Cells["B1"].Value = "Serial Num.";
                            custSheet.Cells["A1:B1"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                            custSheet.Cells["A1:B1"].Style.Font.Size = 14;
                            custSheet.Cells["A1:B1"].Style.Font.Bold = true;
                            custSheet.Cells["A1:B1"].AutoFitColumns();

                            // Start by trimming the name variable to just the Customer Name.
                            int rowStart = workSheet.Dimension.Start.Row;
                            int rowEnd = workSheet.Dimension.End.Row + 1;

                            string cellRange = "A" + rowStart + ":" + "X" + rowEnd;
                            string custName;
                            int index = name.LastIndexOf("-")-1;
                            custName = name.Substring(0, index);

                            // Now, search for the first occurence of that Customer Name in the document, as well as how many times it repeats.
                            Console.WriteLine(cellRange);
                            var searchCell = from cell in workSheet.Cells[cellRange]
                                                where cell.Value.ToString() == custName
                                                select cell.Start.Row;
                            var countCell = workSheet.Cells[cellRange].Count(c => c.Text == custName);
                            if (custName == null)
                            {
                                searchCell = null;
                            }

                            int? rowNum;
                            int? nameCount;
                            if (searchCell != null)
                            {
                                nameCount = countCell;
                                if (nameCount != null)
                                {
****This is where two sheets are erroring, at around the 18th cell and the 50th cell in the respective spreadsheets.****                                    
                                    rowNum = searchCell.FirstOrDefault();
                                }
                                else
                                {
                                    nameCount = 0;
                                    rowNum = 1;
                                }
                            }

                            else
                            {
                                nameCount = 0;
                                rowNum = 1;
                            }
                            int rowCnt = 2;

                            // Loop for as many times as the Customer Name appears.

                            if (nameCount > 0)
                            {
                                while (nameCount > 0)
                                {
                                    // Set modelNum and serialNum to the values of the cells in the rows where Customer Name was found.
                                    string modelNum = workSheet.Cells["A" + rowNum].Value.ToString();
                                    string serialNum = workSheet.Cells["B" + rowNum].Value.ToString();


                                    custSheet.Cells["A" + rowCnt].Value = modelNum;
                                    custSheet.Cells["B" + rowCnt].Value = serialNum;

                                    rowCnt++;



                                    if (nameCount >= 1)
                                    {
                                        string cellRange2 = "A" + rowNum + ":" + "X" + rowEnd;
                                        var searchCell2 = from cell in workSheet.Cells[cellRange2]
                                                          where cell.Value.ToString() == custName
                                                          select cell.Start.Row;
                                        var searchCell4 = workSheet.Cells[cellRange].FirstOrDefault(c => c.Text == custName);

                                        // Find the next occurence of Customer Name.
                                        if (searchCell2 != null)
                                        {
****This is where one sheet is erroring, around the 57th cell in the spreadsheet..****                                            
                                            rowNum = Convert.ToInt32(searchCell2.FirstOrDefault());                                            
                                        }
                                    }
                                    // Set the range to 1 row past the previous occurence of Customer Name.
                                    rowNum++;
                                    // Save the customer file.
                                    custPkg.SaveAs(custFile);

                                    // Decrement the loop counter, and go again.
                                    nameCount--;
                                }
                            }

                        }
                    }
                }
                // Show success dialogbox.
                MessageBox.Show("Customer databases created.", "SUCCESS: Database retrieval complete.",
                   MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                // Error message, in case the user hasn't chosen a database.
                MessageBox.Show("Please click \"Browse...\" and select a check-in database in order to build a Customer Database.", "ERROR: No CIDB Selected.",
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

错误代码粘贴在下面。

  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=CheckInGUI
  StackTrace:
   at CheckInGUI.CustDatabase.<>c__DisplayClass10_0.<DatabaseBuilder>b__0(ExcelRangeBase cell)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
   at CheckInGUI.CustDatabase.DatabaseBuilder()
   at CheckInGUI.CustDatabase.buildDatabaseButton_Click(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at CheckInGUI.Program.Main()

我将EPPlus用于Excel编写。这是WinForms应用程序中的C#。如果需要其他信息,请让我知道。

c# excel nullreferenceexception epplus
1个回答
0
投票
看起来像解析searchCell时(执行FirstOrDefault()时),您正在获取NullReferenceException

检查该excel查询,它可以是cell.Value.ToString()cell.Start.Row

更改该查询,使其看起来像:

var searchCell = from cell in workSheet.Cells[cellRange] where cell.Value != null && cell.Value.ToString() == custName && cell.Start != null select cell.Start.Row;

© www.soinside.com 2019 - 2024. All rights reserved.