Не уверен, как решить это исключение NullReferenceException - PullRequest
0 голосов
/ 06 мая 2020

У меня есть метод, который должен брать имена клиентов, города клиентов и огнетушители + серийные номера каждого огнетушителя, принадлежащего этим клиентам, из файла Excel и записывать эту информацию в кучу отдельных файлов Excel. в зависимости от того, какому покупателю принадлежат огнетушители. Я получаю исключение NullReferenceException в середине этого процесса, по-видимому, в случайном месте. Расположение отличается на всех трех таблицах, в которых я обнаружил эту ошибку. Следует также отметить, что две другие таблицы вообще не сталкиваются с трудностями и каждый раз передаются безупречно. Я не хочу публиковать электронные таблицы, чтобы защитить информацию моих клиентов. Однако ниже вы найдете код ошибки, а ниже - метод 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()

I Я использую EPPlus для написания Excel. Это C# в приложении WinForms. Если потребуется дополнительная информация, дайте мне знать.

1 Ответ

0 голосов
/ 07 мая 2020

Похоже, что при разрешении 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...