我目前正在开发一个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互操作来完成。
关于这个问题,我有几个问题:
我是否按照我的方式正确调用文件? (编辑:是的,文件调用方法是正确的,但是它在里面的try语句中引起了麻烦。)
为什么启动应用程序时错误会跳转?
(编辑:当在构造函数上执行的操作比表单本身更快时,错误会跳转,通过将代码移动到Form_Load
事件来修复它)
以下是最终的代码段:
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);
}
}
}
}
答案 0 :(得分:0)
您的所有代码似乎都在表单的构造函数中运行。表单字段尚未创建。
将代码移至form_load
事件中,您的代码将更有效。
说明:这种编程方法经常会出现奇怪的行为。 winforms的线程模型有时难以解释。这就是为什么它可能会与你的“手动”方法一起使用,因为延迟会让后台线程赶上来。