【问题标题】:C# Excel Worksheet Object reference not set to an instance of an objectC# Excel 工作表对象引用未设置为对象的实例
【发布时间】:2016-06-07 13:49:29
【问题描述】:

当我以交互方式运行 SSIS 包时,在运行时在脚本任务上收到错误对象引用未设置为对象的实例

所以我使用断点调试了代码,在一步步执行之后,代码在这一行失败objExcelWbk.Close(true, Type.Missing, Type.Missing);

我已经检查了我所有的参考资料,它们都在那里,导入也很好。

下面提供函数

public void FormatExcel_DVP(string strFinalFileName, string ExcelOutputFolder, SqlConnection Conn)
{
    Microsoft.Office.Interop.Excel.ApplicationClass objExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
    Microsoft.Office.Interop.Excel.Workbook objExcelWbk = default(Excel.Workbook);
    Microsoft.Office.Interop.Excel.Worksheet objWrksheet = default(Excel.Worksheet);
    string sFilePath = string.Empty;
    DataSet ds = new DataSet();
    string DVP_Name = string.Empty;
    string sFilename = string.Empty;

    int RowCount = 0;
    try
    {
        SqlCommand cmd = new SqlCommand("select distinct LTRIM(RTRIM(DVP_Name))as DVP_Name from SBBCP_DVP_SVP Order By DVP_Name", Conn);
        SqlDataAdapter _da = new SqlDataAdapter(cmd);
        _da.Fill(ds);


        if (ds.Tables[0].Rows.Count > 0)
        {
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                DVP_Name = dr[0].ToString().Trim().Replace("'", "''");
                sFilename = DVP_Name.Trim();

                sFilePath = strFinalFileName + ExcelOutputFolder.Trim() + sFilename;

                if (System.IO.File.Exists(sFilePath))
                {
                    objExcelWbk = objExcelApp.Workbooks.Open(sFilePath.Trim(), Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                    objExcelApp.DisplayAlerts = false;
                    objExcelApp.Visible = false;

                    objWrksheet = (Excel.Worksheet)objExcelWbk.Worksheets["Details"];
                    ((Microsoft.Office.Interop.Excel._Worksheet)objWrksheet).Activate();

                    Microsoft.Office.Interop.Excel.Range range;

                    range = (Excel.Range)objWrksheet.get_Range("A1:J1", Type.Missing);

                    range.Interior.ColorIndex = 15;
                    range.Interior.Pattern = Microsoft.Office.Interop.Excel.XlPattern.xlPatternSolid;
                    range.NumberFormat = "@";
                    range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
                    range.VerticalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
                    range.WrapText = true;
                    range.Font.Bold = true;
                    range.Font.Name = "Arial";
                    range.Font.Size = 10;
                    range.AutoFilter(1, Type.Missing, Microsoft.Office.Interop.Excel.XlAutoFilterOperator.xlAnd, Type.Missing, true);


                    RowCount = objWrksheet.UsedRange.Rows.Count;
                    range = objWrksheet.get_Range("A2:J2", "A" + RowCount + ":J" + RowCount);
                    range.WrapText = true;


                    FormatPivotTable(ref objExcelWbk, "Summary");
                    objExcelWbk.SaveAs(sFilePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                }
            }
        }
        objExcelWbk.Close(true, Type.Missing, Type.Missing);
        objExcelApp.Quit();
    }
    catch (Exception e)
    {
        throw e;
    }
}

【问题讨论】:

  • ObjExcelWbk 按数据行打开,并且仅在文件打开的情况下打开 - 但是它在该范围之外很久就关闭了。所以是的,我希望它有时会失败。
  • @BugFinder 你是对的,当我调试它时它没有进入 if 语句。所以你的意思是把它放在 if 语句中,但在每个循环的外面是吗?
  • 将它放在与创建/实例化相同的代码块中。在您的情况下,if(file exists)。
  • @BugFinder 可以,谢谢。如果您能给出答案,我想将其标记为正确并 +1。

标签: c# ssis script-task


【解决方案1】:

在你的代码中你有

for each row
{
  if file exists 
  {
     open spreadsheet.
     do stuff
  }
}
Close spreadsheet

问题在于,您的电子表格可能从未打开过,并且它试图关闭它但尚未设置。

您应该在打开电子表格的同一范围内关闭电子表格,因此在我的伪代码中,在“做事”之后 - 因为那时,如果您打开它是因为它没有出错或死亡,您可以关闭一些东西。

【讨论】:

  • 如果您有 99% 的可能性总是有 1 件或多件事情要做,那么另一个可能使您的代码更高效的选项是将电子表格的开头移到每行之前 - 如看起来您每次迭代都打开同一个电子表格。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多