为什么我无法自动加载Excel文件?

时间:2017-04-10 19:53:12

标签: c# excel

我目前正在开发一个WFA,作为一个人的本地数据库,它使用Excel文件(.xlsx)将数据提供给应用程序,应用程序在加载时可以正常工作通过OpenFileDialog手动归档。但是,用户必须无法直接与文件交互,我尝试从固定位置启动程序时加载文件:

C:\users\documents\application\Resources\db\tabla.xlsx

使用此代码:

string path = Application.StartupPath;
string file = @"Resources\db\tabla.xlsx";
string full = Path.Combine(path,file);

其中full返回所需的路径,但是,我一直收到以下错误:

  

System.ObjectDisposedException:'无法访问已处置的对象

错误是由工作簿加载操作引起的,问题是工作簿在表单初始化之前甚至尝试加载,因为我的大多数代码都在表单的构造函数上。

以下是用于手动和自动加载文件的代码片段:

手册:

Using system.reflection;
Using Excel = Microsoft.office.interop.excel;

Public partial class Form1 : Form
{
    Excel.application oXL;
    Excel._workbook oWB;
    Excel._worksheet oST;
    Object misvalue = system.reflection.missing.value;

    public Form1()
    {
        InitializeComponent();
        OpenFileDialog open = new OpenFileDialog();
        open.RestoreDirectory = true;

        MessageBox.Show("Selecciona la base de datos a usar (formato .XLS).");

        if (open.ShowDialog() != DialogResult.Cancel)
        {
            try
            {
                oXL = new Excel.Application();
                oXL.Visible = false;
                oXL.UserControl = true;

                oWB = (oXL.Workbooks.Open(open.FileName));
                oST = (Excel._Worksheet)oWB.Sheets.get_Item("Sheet1");

                count = oST.Cells.Find("*", misvalue, misvalue, misvalue, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlPrevious, false, misvalue, misvalue).Row;

                for (int x = 1; x < count; x++)
                {
                    dataGridView1.Rows.Add(oST.Cells[x + 1, 1].value, oST.Cells[x + 1, 2].value, oST.Cells[x + 1, 3].value, oST.Cells[x + 1, 4].value, oST.Cells[x + 1, 5].value, oST.Cells[x + 1, 6].value);
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Ocurrio un error y la aplicacion no se pudo inicializar correctamente, asegurate que no haya una copia de la aplicacion en funcionamiento previo. El programa se cerrara ahora.");

                oXL.Quit();
                this.Close();
            }
        }
        else
        {
            MessageBox.Show("Ha fallado la seleccion de la base de datos, para continuar reinicie la aplicacion.");
        }
    }
}

自动:

Using system.reflection;
Using Excel = Microsoft.office.interop.excel;

Public partial class Form1 : Form
{
    Excel.application oXL;
    Excel._workbook oWB;
    Excel._worksheet oST;
    Object misvalue = system.reflection.missing.value;

    public Form1()
    {
        InitializeComponent();

        MessageBox.Show("Selecciona la base de datos a usar (formato .XLS).");

        try
        {
             oXL = new Excel.Application();
             oXL.Visible = false;
             oXL.UserControl = true;

             string path = Application.StartupPath;
             string file = @"Resources\db\tabla.xlsx";
             string full = Path.Combine(path,file);

             oWB = oXL.Workbooks.Open(full);
             oST = (Excel._Worksheet)oWB.Sheets.get_Item("Sheet1");

             count = oST.Cells.Find("*", misvalue, misvalue, misvalue, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlPrevious, false, misvalue, misvalue).Row;

             for (int x = 1; x < count; x++)
             {
                    dataGridView1.Rows.Add(oST.Cells[x + 1, 1].value, oST.Cells[x + 1, 2].value, oST.Cells[x + 1, 3].value, oST.Cells[x + 1, 4].value, oST.Cells[x + 1, 5].value, oST.Cells[x + 1, 6].value);
             }
        }
        catch (Exception)
        {
            MessageBox.Show("Ocurrio un error y la aplicacion no se pudo inicializar correctamente, asegurate que no haya una copia de la aplicacion en funcionamiento previo. El programa se cerrara ahora.");

            oXL.Quit();
            this.Close();
        }
    }
}

我在Stack Overflow西班牙语分支上发布了相同的问题,我被建议使用ClosedXML,这实际上是一个非常好的选择,并允许您更快地处理这类问题,但目前我需要这可以使用本机Excel互操作来完成。

关于这个问题,我有几个问题:

  1. 我是否按照我的方式正确调用文件? (编辑:是的,文件调用方法是正确的,但是它在里面的try语句中引起了麻烦。)

  2. 为什么启动应用程序时错误会跳转? (编辑:当在构造函数上执行的操作比表单本身更快时,错误会跳转,通过将代码移动到Form_Load事件来修复它)

  3. 以下是最终的代码段:

    using Excel = Microsoft.Office.Interop.Excel;
    using System.Reflection;
    
    namespace ApplicationName
    { 
        public partial class Form : Form
        {
            int count;
            int count2;
            int count3;
    
            Excel.Application oXL;
            Excel._Workbook oWB;
            Excel._Worksheet oST;
            object misvalue = System.Reflection.Missing.Value;
    
            public Form()
            {
                InitializeComponent();
            }
    
            private void Form_Load(object sender, EventArgs e)
            {
                string path = Application.StartupPath;
                string file = @"Resources\db\tabla.xlsx";
                string full = Path.Combine(path, file);
    
                    oXL = new Excel.Application();
                    oXL.Visible = false;
                    oXL.UserControl = true;
    
                try
                {
                    oWB = oXL.Workbooks.Open(full);
                    oST = (Excel._Worksheet)oWB.Sheets.get_Item("Sheet1");
                }
                catch
                {
                    MessageBox.Show("Ocurrio un error al cargar la base de datos, asegurate que exista en la carpeta DB en los archivos del programa.");
                    MessageBox.Show("DEBUG: " + full);
                    oXL.Quit();
                    this.Close();
                }
    
    
                count = oST.Cells.Find("*", misvalue, misvalue, misvalue, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlPrevious, false, misvalue, misvalue).Row;
    
                    for (int x = 1; x < count; x++)
                    {
                        dgv_tab1.Rows.Add(oST.Cells[x + 1, 1].value, oST.Cells[x + 1, 2].value, oST.Cells[x + 1, 3].value, oST.Cells[x + 1, 4].value, oST.Cells[x + 1, 5].value, oST.Cells[x + 1, 6].value);
                    }
                }
            }
        }
    

1 个答案:

答案 0 :(得分:0)

您的所有代码似乎都在表单的构造函数中运行。表单字段尚未创建。

将代码移至form_load事件中,您的代码将更有效。

说明:这种编程方法经常会出现奇怪的行为。 winforms的线程模型有时难以解释。这就是为什么它可能会与你的“手动”方法一起使用,因为延迟会让后台线程赶上来。