【问题标题】:c# winforms VS2017 linking with excel: error when closing formc# winforms VS2017与excel链接:关闭表单时出错
【发布时间】:2018-11-12 09:52:22
【问题描述】:

see image

这被认为是重复的帖子,因为确切的代码用于另一个问题(大约 5 年前。)。基本上,我收到错误 System.NullreferenceException: 'Object reference not set to an instance on an object '. 每次我关闭表单时,xlWorkBook.Close(true, misValue, misValue); 行(见图)。基于原来的问题:Inserting multiple textbox data into an Excel file,我找不到和我有同样问题的人。我使用的代码与链接相同:

`using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Data;
 using System.Drawing;
 using System.Linq;
 using System.Text;
 using Excel = Microsoft.Office.Interop.Excel;
 using System.Windows.Forms;

 namespace Vehicledettry
   {
     public partial class Form1 : Form
      {
    Microsoft.Office.Interop.Excel.Application xlexcel;
    Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
    Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
    object misValue = System.Reflection.Missing.Value;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        xlexcel = new Excel.Application();

        xlexcel.Visible = true;

        // Open a File
        xlWorkBook = xlexcel.Workbooks.Open(" C:\\vehicledet.xlsx", 0, true, 5, "", "", true,
        Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);

        xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

        xlWorkSheet.Cells[1, 1] = "Plate Number";
        xlWorkSheet.Cells[1, 2] = "Car Model";
        xlWorkSheet.Cells[1, 3] = "Car Brand";
        xlWorkSheet.Cells[1, 4] = "Mileage";
    }

    private void button2_Click(object sender, EventArgs e)
    {
        int _lastRow = xlWorkSheet.Cells[xlWorkSheet.Rows.Count, 1].End[Excel.XlDirection.xlUp].Row + 1;

        xlWorkSheet.Cells[_lastRow, 1] = Plate Number.Text;
        xlWorkSheet.Cells[_lastRow, 2] = Car Model.Text;
        xlWorkSheet.Cells[_lastRow, 3] = Car Brand.Text;
        xlWorkSheet.Cells[_lastRow, 4] = Mileage.Text;

    }

    private void button3_Click(object sender, EventArgs e)
    {
        xlWorkBook.Close(true, misValue, misValue);
        xlexcel.Quit();

        releaseObject(xlWorkSheet);
        releaseObject(xlWorkBook);
        releaseObject(xlexcel);

    }

    private void releaseObject(object obj)
    {
        try
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
            obj = null;
        }
        catch (Exception ex)
        {
            obj = null;
            MessageBox.Show("Unable to release the Object " + ex.ToString());
        }
        finally
        {
            GC.Collect();
        }
    }

}

我尝试在每个按钮事件单击后复制xlWorkBook = xlexcel.Workbooks.Open(" C:\\vehicledet.xlsx", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);,但同样的错误不断发生。希望我能得到一些帮助。谢谢。

【问题讨论】:

  • 这是很多不好的做法。不难得到这个异常,只需在单击 button1 之前单击 button3。
  • 嗨,汉斯。当我单击按钮 3 时,将弹出错误并且无法按下其他按钮。无论如何,按钮 3 用于关闭程序,所以如果我先按下它,我的所有数据甚至都不会被保存(没有差异,因为我什至无法运行程序:()。我会继续尝试。
  • 您可以使用 EPPlus 之类的库直接生成 xlsx 文件,而不是使用 Excel 互操作。 The API is more or less the same 但您不必担心安装 Excel、关闭和正确处理 COM 对象。

标签: c# excel winforms


【解决方案1】:

最近,我也有一个项目,它将数据发送到一个 excel 文件中,但与你的不同,我的数据来自一个文本文件,这个网站上的某个人帮助我弄清楚如何导出我的数组的值在 Excel 文件中。在您的情况下,此代码可能会有所帮助。

using Excel = Microsoft.Office.Interop.Excel;
Excel.Application exc = new Excel.Application();
exc.Interactive = true;
var excelTemplate = "CompareResult.xlsx"; //Change it with your filename
string FromPath = Path.GetFullPath(excelTemplate); //Get the full path of your excel 
//file.
Excel.Workbook wb = exc.Workbooks.Open(FromPath);
Excel.Worksheet sh = wb.Sheets[1];
int _lastRow = xlWorkSheet.Cells[xlWorkSheet.Rows.Count, 1].End[Excel.XlDirection.xlUp].Row + 1;
sh.Cells[row, 1].Value2 = textBox1.Text;
sh.Cells[row, 2].Value2 = textBox1.Text;
sh.Cells[row, 3].Value2 = textBox1.Text;
sh.Cells[row, 4].Value2 = textBox1.Text;
wb.Save(); \\Saving the file when changing
wb.Close(); 
exc.Quit();

【讨论】:

    【解决方案2】:

    (根据反馈编辑)见下文。文本框中的数据将自动进入现有的选择的 Excel 文件。非常感谢https://support.microsoft.com/en-in/help/302084/how-to-automate-microsoft-excel-from-microsoft-visual-c-net 的帮助

    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Excel = Microsoft.Office.Interop.Excel;
    using System.Reflection;
    using System.Windows.Forms;
    
    
    namespace exceltry
      {
        public partial class Form1 : Form
         {
           public Form1()
            {
               InitializeComponent();
            }
    
    private void button1_Click(object sender, System.EventArgs e)
      {
            Excel.Application xlexcel = null;
            Excel._Workbook xlWorkbook = null;
            Excel._Worksheet xlWorkSheet = null;
            Excel.Range oRng;
    
        try
           {
              //start excel and get application object
              oXL = new Microsoft.Office.Interop.Excel.Application();
    
    
              //open existing workbook
                oWB = oXL.Workbooks.Open("C:\\vehicledet.xlsx");
                oSheet = (Excel._Worksheet)oWB.ActiveSheet;
    
             //Add table headers going cell by cell.
              xlWorkSheet.Cells[1, 1] = "Plate Number";
              xlWorkSheet.Cells[1, 2] = "Car Model";
              xlWorkSheet.Cells[1, 3] = "Car Brand";
              xlWorkSheet.Cells[1, 4] = "Mileage";
    
             //Format A1:D1 as bold, vertical alignment = center.
              xlWorkSheet.get_Range("A1", "D1").Font.Bold = true;
              xlWorkSheet.get_Range("A1", "D1").VerticalAlignment = 
              Excel.XlVAlign.xlVAlignCenter;
    
              // insert text at every last row
                int _lastRow = xlWorkSheet.Range["A" +    xlWorkSheet.Rows.Count].End[Excel.XlDirection.xlUp].Row + 1;
    
                xlWorkSheet.Cells[_lastRow, 1] = textBox1.Text;
                xlWorkSheet.Cells[_lastRow, 2] = textBox2.Text;
                xlWorkSheet.Cells[_lastRow, 3] = textBox3.Text;
                xlWorkSheet.Cells[_lastRow, 4] = textBox4.Text;
    
    
                //AutoFit columns A:D.
                oRng = xlWorkSheet.get_Range("A1", "D1");
                oRng.EntireColumn.AutoFit();
    
                //Make sure Excel is not visible and give the user control of Microsoft Excel's lifetime.
                xlexcel.Visible = false;
                xlexcel.UserControl = true;
    
                //can save update to same file but wont close unless user press x button
                xlWorkbook.Save();
                MessageBox.Show("Data saved successfully");
                xlWorkbook.Close();
    
                //allow excel to auto close by itself 
                oXL.Quit();
                Marshal.ReleaseComObject(oXL);
    
            }
            catch (Exception theException)
            {
                String errorMessage;
                errorMessage = "Error: ";
                errorMessage = String.Concat(errorMessage, theException.Message);
                errorMessage = String.Concat(errorMessage, " Line: ");
                errorMessage = String.Concat(errorMessage, theException.Source);
    
                MessageBox.Show(errorMessage, "Error");
            }
        }
    }
    

    【讨论】:

    • 这将在单击按钮后立即引发 NRE - xlexcel 为空。另一个严重的问题是它使用using 块来确保COM 对象被释放。如果抛出错误,Excel 将保持打开状态
    • 大家好。更新了编码。感谢大家的反馈
    猜你喜欢
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多