不确定如何解决此 NullReferenceException
Not sure how to solve this NullReferenceException
我有一个方法应该从 excel 文件中获取客户姓名、客户城镇和灭火器 + 属于这些客户的每个灭火器的序列号,并将该信息写入一堆单独的 excel 文件,具体取决于灭火器所属的客户。我在这个过程的中途收到 NullReferenceException,似乎是在一个随机的地方。我遇到此错误的所有 3 个电子表格的位置都不同。还应该指出的是,另外两个电子表格完全没有遇到任何困难,并且每次都可以完美传输。我不愿意 post 电子表格,以保护我客户的信息。但是,您会在下方找到错误代码,下方是导致这些错误的 DatabaseBuilder 方法。
我认为我的问题在于 FirstOrDefault();方法。我已经通过调试确认 none 的 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 写作目的。这是在 C# 中,在 WinForms 应用程序上。如果需要任何其他信息,请告诉我。
看起来当 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;
我有一个方法应该从 excel 文件中获取客户姓名、客户城镇和灭火器 + 属于这些客户的每个灭火器的序列号,并将该信息写入一堆单独的 excel 文件,具体取决于灭火器所属的客户。我在这个过程的中途收到 NullReferenceException,似乎是在一个随机的地方。我遇到此错误的所有 3 个电子表格的位置都不同。还应该指出的是,另外两个电子表格完全没有遇到任何困难,并且每次都可以完美传输。我不愿意 post 电子表格,以保护我客户的信息。但是,您会在下方找到错误代码,下方是导致这些错误的 DatabaseBuilder 方法。
我认为我的问题在于 FirstOrDefault();方法。我已经通过调试确认 none 的 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 写作目的。这是在 C# 中,在 WinForms 应用程序上。如果需要任何其他信息,请告诉我。
看起来当 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;