解析 excel 电子表格时对象引用未设置为对象实例
Object reference not set to instance of object when parsing excel spreadsheet
我从 excel 方法编写了自己的 import for excel sheet 我公司用来显示商店中不同部门的预算。 sheet 我只关心与日期和我们部门的预算相关的两列。
public static string[][] ImportBudgets(string filename)
{
var xlApp = new Application();
var xlWorkBook = xlApp.Workbooks.Open(filename, 0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
var xlWorkSheet = (Worksheet)xlWorkBook.Worksheets.Item[1];
var range = xlWorkSheet.UsedRange;
var budgetsArray = new string[range.Rows.Count][];
// loop through excel spreadsheet and get data
for (var rCnt = 3; rCnt <= range.Rows.Count; rCnt++)
{
var budgetDate = (string)((Range)range.Cells[rCnt, 1]).Value2;
var budgetAmount = (decimal)((Range)range.Cells[rCnt, 8]).Value2;
budgetsArray[rCnt - 3] = new[] { budgetDate, budgetAmount.ToString(CultureInfo.CurrentCulture) };
}
// cleanup
xlWorkBook.Close(true, null, null);
xlApp.Quit();
Marshal.ReleaseComObject(xlWorkSheet);
Marshal.ReleaseComObject(xlWorkBook);
Marshal.ReleaseComObject(xlApp);
return budgetsArray;
}
public string ImportBudgets(string filename)
{
try
{
// get dates and budgets from excel in array
var budgets = CExcel.ImportBudgets(filename);
using (var oDc = new StatTrackerTablesDataContext())
{
foreach (var innerArray in budgets)
{
var budget = new tblBudget();
DateTime budgetdate;
if (DateTime.TryParse(innerArray[0], out budgetdate) != true) continue;
budget.Budget_ID = Guid.NewGuid();
budget.Budget_Date = budgetdate;
budget.Budget_Amount = decimal.Parse(innerArray[1]);
budget.Budget_Goal = decimal.Parse(innerArray[1]) * (decimal)1.1;
oDc.tblBudgets.InsertOnSubmit(budget);
oDc.SubmitChanges();
}
}
return "Budgets imported without problems.";
}
catch (SqlException ex)
{
if (ex.Number == 2627)
{
return "Budget already existed for a date in batch. Import aborted.";
}
else
{
return ex.Message;
}
}
catch (Exception ex)
{
if (ex.Message.Contains("Object reference not set to an instance of an object."))
return "Budgets imported without problems.";
return ex.Message;
}
}
导入将 运行 并正确导入所有日期和预算,但在正确填充最后一个之后的行后,将始终有空对象。我加入了对象引用消息的错误处理,但如果导入过程确实存在问题,这显然不是一个好的策略。我只是看看是否有人可以帮助我改进它以防止消息出现。
好吧,我已经有一段时间没有访问这段代码了,因为它确实完成了工作。这只是我不喜欢在那里避免错误消息的解决方法。我注意到我为 excel 文档的整个行数标注了数组的尺寸,但该文档包含未针对预算进行分析的行,因为它们不是实际日期。每个文档有 2-3 行被跳过,因为 "date" 列表示类似 "Week 2" 的内容。这导致预算数组具有 2-3 个 null innerArrays,而我的辅助预算导入方法将尝试解析空数组。我以为代码:
if (DateTime.TryParse(innerArray[0], out budgetdate) != true) continue;
本来可以让数组不被解析,但忽略了在返回false之前会抛出异常的事实。我刚刚添加了
if (innerArray == null) continue;
在 foreach 循环的开头,现在不需要
就可以导入
catch (Exception ex)
{
if (ex.Message.Contains("Object reference not set to an instance of an object."))
return "Budgets imported without problems.";
return ex.Message;
}
我从 excel 方法编写了自己的 import for excel sheet 我公司用来显示商店中不同部门的预算。 sheet 我只关心与日期和我们部门的预算相关的两列。
public static string[][] ImportBudgets(string filename)
{
var xlApp = new Application();
var xlWorkBook = xlApp.Workbooks.Open(filename, 0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
var xlWorkSheet = (Worksheet)xlWorkBook.Worksheets.Item[1];
var range = xlWorkSheet.UsedRange;
var budgetsArray = new string[range.Rows.Count][];
// loop through excel spreadsheet and get data
for (var rCnt = 3; rCnt <= range.Rows.Count; rCnt++)
{
var budgetDate = (string)((Range)range.Cells[rCnt, 1]).Value2;
var budgetAmount = (decimal)((Range)range.Cells[rCnt, 8]).Value2;
budgetsArray[rCnt - 3] = new[] { budgetDate, budgetAmount.ToString(CultureInfo.CurrentCulture) };
}
// cleanup
xlWorkBook.Close(true, null, null);
xlApp.Quit();
Marshal.ReleaseComObject(xlWorkSheet);
Marshal.ReleaseComObject(xlWorkBook);
Marshal.ReleaseComObject(xlApp);
return budgetsArray;
}
public string ImportBudgets(string filename)
{
try
{
// get dates and budgets from excel in array
var budgets = CExcel.ImportBudgets(filename);
using (var oDc = new StatTrackerTablesDataContext())
{
foreach (var innerArray in budgets)
{
var budget = new tblBudget();
DateTime budgetdate;
if (DateTime.TryParse(innerArray[0], out budgetdate) != true) continue;
budget.Budget_ID = Guid.NewGuid();
budget.Budget_Date = budgetdate;
budget.Budget_Amount = decimal.Parse(innerArray[1]);
budget.Budget_Goal = decimal.Parse(innerArray[1]) * (decimal)1.1;
oDc.tblBudgets.InsertOnSubmit(budget);
oDc.SubmitChanges();
}
}
return "Budgets imported without problems.";
}
catch (SqlException ex)
{
if (ex.Number == 2627)
{
return "Budget already existed for a date in batch. Import aborted.";
}
else
{
return ex.Message;
}
}
catch (Exception ex)
{
if (ex.Message.Contains("Object reference not set to an instance of an object."))
return "Budgets imported without problems.";
return ex.Message;
}
}
导入将 运行 并正确导入所有日期和预算,但在正确填充最后一个之后的行后,将始终有空对象。我加入了对象引用消息的错误处理,但如果导入过程确实存在问题,这显然不是一个好的策略。我只是看看是否有人可以帮助我改进它以防止消息出现。
好吧,我已经有一段时间没有访问这段代码了,因为它确实完成了工作。这只是我不喜欢在那里避免错误消息的解决方法。我注意到我为 excel 文档的整个行数标注了数组的尺寸,但该文档包含未针对预算进行分析的行,因为它们不是实际日期。每个文档有 2-3 行被跳过,因为 "date" 列表示类似 "Week 2" 的内容。这导致预算数组具有 2-3 个 null innerArrays,而我的辅助预算导入方法将尝试解析空数组。我以为代码:
if (DateTime.TryParse(innerArray[0], out budgetdate) != true) continue;
本来可以让数组不被解析,但忽略了在返回false之前会抛出异常的事实。我刚刚添加了
if (innerArray == null) continue;
在 foreach 循环的开头,现在不需要
就可以导入catch (Exception ex)
{
if (ex.Message.Contains("Object reference not set to an instance of an object."))
return "Budgets imported without problems.";
return ex.Message;
}