2016-06-16 13 views
-1

オブジェクトのインスタンスに設定されていないスローそのDataTableとをループそのExcel Fileの出力を保存するには、DataGridのセル数と行数および列数、またはDataTableが抽出された場所に応じて時間がかかります。変数の値を有するが、オブジェクト参照が私は<code>DataTable</code>ループと気付い<code>C#</code></p> <p>ため<code>SpreadSheetLight</code>を用い<code>Excel File</code>として保存する機能を有する

BackgroundWorkerを使用する前に、関数が正しく実行されます。 BackgroundWorkerのない唯一のサイドノートは、コード実行中にUIがフリーズすることです。 BackgroundWorkerを利用することによって、私は別のスレッドでsave関数を処理することでこれを排除できることを知っています。

ですが、BackgroundWorkerを私の関数に適用した後、保存関数全体が壊れます。私はObject Reference not set to an instance of an Objectをスローしますが、デバッグしてトレースして、渡された変数の両方に値があり、nullでないことを確信しました。私が使ったループはこれまでと同じで、For Loopを使ってみました。

ここに私が遭遇したことのスニペットがあります。ご覧のとおり、下のウィンドウは、cellvalueの両方の変数に内容が含まれていることを示しています。まだ私にnull参照を投げます。

enter image description here

はさらに、ここに私は私の BackgroundWorkerを実装しました前に、もともと、この同じコードが働い

 public void exportSingleDataGridToExcelFile(DataTable dt) { 
      using(var sfd = new SaveFileDialog()) { 
       sfd.FileName = string.Format("WIP Monitoring-{0}", DateTime.Now.ToString("MM.dd.yyyy")); 
       sfd.Filter = "Excel File (*.xlsx)|*.xlsx"; 

       if(sfd.ShowDialog() == DialogResult.OK) { 
        clb.Enabled = false; 
        cb.Enabled = false; 
        btn.Visible = false; 
        pb.Visible = true; 
        pb.Value = 50; 

        using(var excel = new SLDocument()) { 
         var style = excel.CreateStyle(); 
         style.SetHorizontalAlignment(DocumentFormat.OpenXml.Spreadsheet.HorizontalAlignmentValues.Center); 
         style.SetVerticalAlignment(DocumentFormat.OpenXml.Spreadsheet.VerticalAlignmentValues.Center); 

         var bgw = new BackgroundWorker(); 
         bgw.WorkerReportsProgress = true; 

         bgw.DoWork += (ss, ee) => { 
          var worker = ss as BackgroundWorker; 

          var count = (dt.Rows.Count + 1) * dt.Columns.Count; 
          var steps = (double) count/100; 
          var prog = 0.0; 
          var row = 0; 
          var col = 0; 

          //Get Column Headers 
          foreach(DataColumn dc in dt.Columns) { 
           var cell = string.Format("{0}1", col.getExCol()); 
           var value = dc.ColumnName; 

           excel.SetCellValue(cell, value); 
           excel.AutoFitColumn(string.Format("{0}1", col.getExCol())); 
           excel.SetCellStyle(string.Format("{0}1", col.getExCol()), style); 

           prog += steps; 
           worker.ReportProgress(((int) prog * 100)); 

           col++; 
          } 

          col = 0; 

          //Get Cell Data 
          foreach(DataRow dr in dt.Rows) { 
           foreach(DataColumn dc in dt.Columns) { 
            var cell = string.Format("{0}{1}", col.getExCol(), row); 
            var value = dr[dc].ToString(); 

            excel.SetCellValue(cell, value); 
            excel.AutoFitColumn(cell, row); 
            excel.SetCellStyle(cell, style); 

            prog += steps; 
            worker.ReportProgress(((int) prog * 100)); 

            col++; 
           } 
           col = 0; 
           row++; 
          } 
         }; 

         bgw.ProgressChanged += (ss, ee) => { 
          pb.Value = ee.ProgressPercentage/100; 
         }; 

         bgw.RunWorkerCompleted += (ss, ee) => { 
          try { 
           excel.SaveAs(sfd.FileName); 
           form.Close(); 
          } catch(Exception ex) { 
           MessageBox.Show(ex.Message, "Error while saving", MessageBoxButtons.OK, MessageBoxIcon.Error); 
          } 
         }; 

         bgw.RunWorkerAsync(); 
        } 
       } 
      } 
     } 

私の関数の完全なコードです。

私はここを歩くことができますか?

+2

'using'ステートメントの' excel'変数が 'bgw.DoWork'イベントハンドラに渡されません – Claies

+1

非常に良い質問表示btw;多くの情報がうまくレイアウトされています。 –

+0

@Claiesはそれのようです。 – TheQuestioner

答えて

2

SLDocuemntインスタンス内の何かがexcelにあると、あなたのバックグラウンドワーカーが実行されるときは、おそらくnullになる可能性があります。

excelusingの文で作成しています。つまり、usingブロックの最後にはexcelが処分されます。しかし、そのブロック内では、このexcel変数を使用するバックグラウンドワーカーを開始します。

バックグラウンドワーカーは確実にusingブロックよりも長く実行されるため、アクセスしようとするとexcelが既に破棄され、例外をスローする行が実行されます。

の即時解決はここでusingを使用しないことになります。しかし、excel変数の内部にのバックグラウンドワーカーのメソッドをインスタンス化する方が良いかもしれません。なぜなら、とにかく外には必要ないと思われるからです。

+0

私たちも同じことを疑う。この質問を投稿した後、私はusingブロックを削除し、関数の上に 'excel'変数を宣言しようとしました。問題は解消して、私はそれを再び働かせました。他の人が私と同じことを考えていた場合に、この質問を残しておきます。ありがとう – TheQuestioner

1

例外を読み取るときに、あなたのexcel変数がNullであることは間違いありません。メソッド呼び出しの値ではありません。

これはあなたのバックグラウンド作業によるものだと思われます。

+0

私はusing(){}を削除しました。ブロックされ、物事は再びうまくいった。ありがとうございました – TheQuestioner

関連する問題

 関連する問題