2017-04-10 41 views
0

我目前正在開發一個WFA,作爲一個人的本地數據庫,它使用Excel文件(.xlsx)將數據提供給應用程序,當通過OpenFileDialog手動加載文件時,應用程序沒有問題。但是,用戶必須不能夠直接與文件交互,我試圖加載文件在從固定位置的程序的啓動:使用此代碼爲什麼我無法自動加載Excel文件?

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: 'Cannot access a disposed object

錯誤是由工作簿加載操作造成的,這個問題還有爲t因爲大部分代碼都在表單的構造函數上,工作簿甚至在初始化之前嘗試加載表單。

這裏是用來手動加載的文件都代碼段,並自動:

手冊:

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

我張貼在堆棧溢出西班牙同樣的問題分支和我被建議使用ClosedXML,這實際上是一個非常好的選擇,並允許您處理這種問題的方式更快,但目前我需要這樣做才能使用本機Excel互操作。

我有幾個關於這個問題的問題:

  1. 我是正確調用文件我做到這一點? (編輯:是的,文件調用的方法是正確的,但是它在內部的嘗試句子中造成了麻煩。)

  2. 爲什麼在啓動應用程序時錯誤會跳轉?

下面是最終的代碼段(編輯時由代碼移動到事件上的構造執行的動作比形式本身更快,固定它的錯誤跳躍)

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

什麼是堆棧跟蹤。 – SLaks

+0

在第二個例子中,您的外殼很好看 - 這是實際編譯的代碼嗎? –

+0

你的代碼不能編譯。在C#中,關鍵字是小寫字母。 C#區分大小寫,所以'openfiledialog()'不起作用; 'OpenFileDialog()'會。並請正確縮進您的代碼。它使閱讀更容易。 –

回答

0

您的所有代碼似乎都在窗體的構造函數中運行。表單字段尚未創建。

將您的代碼移到form_load事件中,您的代碼將更好地工作。

說明:通過這種編程方法,您經常會遇到奇怪的行爲。 winforms的線程模型有時很難解釋。這就是爲什麼它可能與您的「手動」方法一起工作,因爲延遲會導致後臺線程追趕。

+0

這在加載文件(ObjectDisposedException)時解決了問題,但是,它尚未加載文件。 –

+1

終於解決了這個問題,你的方法真的很有幫助,並讓我意識到我做錯了什麼。我會將此標記爲答案並更新問題內容以匹配實際解決方案。 –

相關問題