Not sure how to solve this NullReferenceException

0

I have a method that is supposed to take customer names, customer towns, and the fire extinguishers + serial numbers of each extinguisher that belongs to those customers, from an excel file, and write that information to a bunch of separate excel files depending on what customer the extinguishers belong to. I'm getting a NullReferenceException halfway through this process, seemingly in a random place. The location is different on all 3 spreadsheets that I encounter this error on. It should also be noted that two other spreadsheets are encountering no difficulties at all, and transfer perfectly every time. I'm not willing to post the spreadsheets, to protect the information of my customers. However, below you will find the error code, and below that is the DatabaseBuilder method that is causing these errors.

I believe my problem lies in the FirstOrDefault(); methods. I've confirmed that none of the searchCell values are null through debugging, and the error only happens at those methods.

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

The error code is pasted below.

  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()

I'm using EPPlus for my Excel-writing purposes. This is in C#, on a WinForms application. If any other information is needed, please let me know.

c#
excel
nullreferenceexception
epplus
asked on Stack Overflow May 6, 2020 by RampageRobot

1 Answer

0

Looks like when searchCell is being resolved (when the FirstOrDefault() is executed) you are getting the NullReferenceException.

Checking that excel query, it could be either cell.Value.ToString() or cell.Start.Row

Change that query so it looks like:

var searchCell = 
    from cell in workSheet.Cells[cellRange]
    where cell.Value != null && cell.Value.ToString() == custName && cell.Start != null
    select cell.Start.Row;
answered on Stack Overflow May 7, 2020 by Cleptus • edited May 7, 2020 by Cleptus

User contributions licensed under CC BY-SA 3.0