2017-04-10 25 views
0

私は現在、単一の人にローカルデータベースとして機能するWFAを開発しています.Excelファイル(.xlsx)を使用してデータをアプリケーションに送りますが、アプリケーションは手動でOpenFileDialog経由でロードする際に問題なく動作します。しかし、ユーザが直接ファイルと相互作用することができない必要があり、Iは、固定された場所からプログラムの起動時にファイルをロードしようとした: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

エラーは、ブックの読み込み操作によって引き起こされ、問題トンがありますフォームのコンストラクタ上にあるコードの大半が初期化されているため、フォームの前であってもワークブックはロードしようとします。ここで

は、手動と自動でファイルをロードするために使用され、両方のコードスニペットです:

マニュアル:

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. は私が正しく、私はそれを行う方法ファイルを呼び出すのですか? (編集:はい、ファイルの呼び出し方法は正しいですが、その中にあったtry文に問題が発生しました)

  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

2番目の例では、大量のケーシングが見えます。実際にコンパイルされたコードですか? –

+0

コードがコンパイルされません。 C#では、キーワードは小文字です。 C#は大文字小文字を区別するので、 'openfiledialog()'は動作しません。 'OpenFileDialog()'はそれになります。そしてコードを正しくインデントしてください。それは読みやすくします。 –

答えて

0

すべてのコードがフォームのコンストラクタで実行されているようです。フォームフィールドはまだ作成されていません。

コードをform_loadイベントに移動すると、コードがうまく機能します。

説明:このプログラミング手法では、しばしば奇妙な動作が発生します。 winformsのスレッドモデルは時々説明するのが難しいです。これは、バックグラウンドスレッドが追いつくのを許す遅延のために、あなたの「手動」アプローチでうまくいくかもしれないからです。

+0

これは、ファイル(ObjectDisposedException)のロード中に問題を修正しましたが、まだファイルをロードできませんでした。 –

+1

最後に問題を解決しました。あなたのアプローチは本当に役に立ち、私が間違っていたことを理解することができました。私はこれを答えとしてマークし、質問の内容を実際の解決策に合わせて更新します。 –

関連する問題