【问题标题】:Why can't I load an Excel file automatically?为什么我不能自动加载 Excel 文件?
【发布时间】:2017-04-11 22:51:38
【问题描述】:

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

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: '无法访问已处置的对象

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

这里是用于手动和自动加载文件的代码sn-ps:

手册:

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 事件来修复它)

这里是最终代码sn-p:

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);
                }
            }
        }
    }

【问题讨论】:

  • 堆栈跟踪是什么。
  • 在第二个示例中,您的大量外壳看起来不正确 - 这实际上是编译代码吗?
  • 您的代码无法编译。在 C# 中,关键字是小写的。 C# 区分大小写,因此 openfiledialog() 不起作用; OpenFileDialog() 将。请正确缩进您的代码。它使阅读更容易。
  • 现在你的代码有try...catch...else 也有Excel._woorkbook oWB; 看起来不对。我知道这些是“错别字”,但人们通常会避免花时间在看起来甚至无法编译的代码上。
  • Excel._woorkbook >> Excel._workbook ?

标签: c# excel


【解决方案1】:

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

将您的代码移动到form_load 事件中,您的代码将运行得更好。

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

【讨论】:

  • 这解决了加载文件时的问题(ObjectDisposedException),但是,它还不能加载文件。
  • 终于解决了这个问题,你的方法真的很有帮助,让我意识到我做错了什么。我打算将此标记为答案并更新问题内容以匹配实际解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 2019-02-08
  • 1970-01-01
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多