2016-07-29 14 views
0

C#で新しくなったのは、C#Windowsアプリケーションに1つ問題があります。 私はC#で1つのWindowsアプリケーションを作成していますが、すべてのタスクを正常に処理していますが、C#Windowsアプリケーションを初めて開こうとすると、最初にExcelファイルがアプリケーションに読み込まれるため、アプリケーションを開こうとしています。ExcelファイルデータをC#アプリケーションに読み込む時間を短縮する方法初めてアプリケーションを開く

このExcelファイルは、 "AutoCompleteStringCollection"に使用されます。

次のコードを参照し、アプリケーションの起動時間を短縮する方法を提案してください。

private void Form1_Load(object sender, EventArgs e) 
    { 

InitializeTextSearchListView(); 

textBox1.AutoCompleteMode = AutoCompleteMode.Suggest;   
      textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource; 
      AutoCompleteStringCollection DataCollection = new AutoCompleteStringCollection(); 
      addItems(DataCollection,listView1); 
      textBox1.AutoCompleteCustomSource = DataCollection; 

    } 

public void addItems(AutoCompleteStringCollection col, ListView ListView1) 
    { 

     Excel.Application xlApp; 
     Excel.Workbook xlWorkBook; 
     Excel.Worksheet xlWorkSheet; 
     Excel.Range range; 

     object missing = System.Reflection.Missing.Value; 

     string str; 
     int rCnt = 0; 
     int cCnt = 0; 

     xlApp = new Excel.Application(); 
     xlWorkBook = xlApp.Workbooks.Open("C:\\SAM Files\\Static Ticker Data.xlsx", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); 

     xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);   
     range = xlWorkSheet.UsedRange; 

     for (rCnt = 1; rCnt <= range.Rows.Count; rCnt++) 
     { 
      for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++) 
      { 
       if (!(((range.Cells[rCnt, cCnt] as Excel.Range).Value2) == null)) 
       { 
        if ((range.Cells[rCnt, cCnt] as Excel.Range).Value2.GetType().ToString() == "System.Double") 
        { 
         double d1 = (Double)(range.Cells[rCnt, cCnt] as Excel.Range).Value2; 
         str = Convert.ToString(d1); 
         col.Add(str); 
        } 
        else 
        { 
         str = (string)(range.Cells[rCnt, cCnt] as Excel.Range).Value2; 
         col.Add(str); 
        } 
       } 

      } 
     } 

注:私は、より少ないデータを選択すると、次にExcelのApplication開放時間を含んでも大規模なデータを選択するためにその問題は、ファイルをエクセル含ん意味軽減されます。

私のアプリケーションを開く時間を短縮する方法を教えてください。

+0

アプリケーションの起動後、別のスレッドを使用してExcelからデータを読み込めます。 – Elangovan

+0

プログラムとExcelプロセスとの間の分割を橋渡しするために必要なプロセスinteropは、このコードを非常に高価にします。 1つのセルではなく、* 1回*、[配列の読み込み](http://stackoverflow.com/questions/910400/reading-from-excel-range-into-multidimensional-array-c-sharp)を必ず読んでください。時間。代わりにOpenXML APIを使用することを強く検討して、Excelが起動するまで待つ必要はありません。 –

+0

それでは、アイテムの線形リストを追加するだけで、なぜExcelの代わりに単純なテキストファイルやXML設定ファイルを使用しないのですか? – cjb110

答えて

0

Excelシートをアプリケーションに読み込まないようにすることをお勧めします。これには多くの理由があります。

  1. アプリケーションを実行する各コンピュータにExcelをインストールする必要があります。
  2. 遅いです。
  3. 実行可能なセキュリティ上の問題の可能性があります。

あなたのコードには、Excelシートから値を読み取る必要があります。この場合の良い選択肢は、NPOIライブラリです。これはオープンソースライブラリで、ここにはhttps://npoi.codeplex.com/があります。

たとえば、Excelシートにデータを書き込んでExcelシートを再計算するなどのExcel機能が必要な場合は、http://www.spreadsheetgear.com/というSpreadSheet Gearライブラリを検討することができます。これはオープンソースではありませんが、うまくいきます。

私が使用するNPOIライブラリのバージョンは、NPOI 2.2.1です。https://npoi.codeplex.com/releasesからダウンロードできます。

以下は、Excelシートを開いてデータを繰り返し処理するためのコードです。

using NPOI.HSSF.UserModel; 
using NPOI.SS.UserModel; 
using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      HSSFWorkbook hssfwb; 
      using (var file = new FileStream(args[0], FileMode.Open, FileAccess.Read)) 
      { 
       hssfwb = new HSSFWorkbook(file); 
      } 

      ISheet sheet = hssfwb.GetSheet("Arkusz1"); 
      for (int row = 0; row <= sheet.LastRowNum; row++) 
      { 
       if (sheet.GetRow(row) != null) //null is when the row only contains empty cells 
       { 
        Console.WriteLine(sheet.GetRow(row).GetCell(0).StringCellValue); 
       } 
      } 
     } 
    } 
} 
+0

提案していただきありがとうございますが、どのように使用するのか、どのバージョンのNPOIライブラリを自分のコードで使用しているのかわからないので、教えてください。 –

+0

@ TusharPatil、私はちょうどコード例とライブラリを入手する場所からのリンクを追加しました –

1

Excelで範囲内のさまざまなセルをステッピングすることは非常に遅いです。通常は、オブジェクトの配列として範囲全体を処理する方がはるかに高速です(読み取りと書き込みの両方の操作)。あなたのデータが単純なテーブル構造であると仮定すると(UsedRangeはテーブル、セルなどの異なる組み合わせにまたがっていない)、次に私は試してみることをお勧めします:

var array = range.Value;

これは、テーブルに一致するオブジェクトの配列を作成します。

Rangeオブジェクトから行と列のディメンションを取得すると、Excel範囲内のセルをステップ実行するよりも、結果の配列をステップ実行するほうがはるかに高速になります。

は、あなたがする必要がある。すなわち、これが提供する配列が(0ベースではなく)1ベースであることに注意してください: { ため を(私は++;;私は< = range.Rows.Count I = 1 INT)以下のための(int型J = 1; jの< = range.Columns.Countあり、j ++){ //プロセス配列[I、J]ここ }}

0

あなたの質問に、より一般的な答え「私はしました私のプログラムをブロックする重い/長いプロセスがある」というのは、複数のスレッドを使用することです。で、その後、DoWork方法でそう

textBox1.AutoCompleteMode = AutoCompleteMode.Suggest;   
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource; 
AutoCompleteStringCollection DataCollection = new AutoCompleteStringCollection(); 

BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += (s, ev) => 
{ 
    addItems(DataCollection,listView1); 
}; 
worker.RunWorkerCompleted += (s, ev) => 
{ 
    textBox1.AutoCompleteCustomSource = DataCollection;  
}; 
worker.RunWorkerAsync(); 

ある重い/長い実行中のプロセス:Form1_Loadにおける基本的MSDN page

あなたがに似た何かをしたい:最も簡単な方法は、組み込みのBackgroundWorkerクラスを使用することですそのプロセスが完了したときに何をするかはRunWorkerCompletedです。

UIを持つ落とし穴、espがないわけではありません。通常、スレッドをマーシャリングする必要があるので、通常は1つのスレッドしかUIを更新できません。そして、あなたは答えに二次的な質問もあります:この作業が進行中で、どのくらいプログラムを使うことができますか?バックグラウンドでの作業をユーザーに示す必要がありますか?

+0

あなたのコード(BackgroundWorker)が私のアプリケーションのために完全に働いてくれてありがとう、ありがとうございました。もう一度 "cjb100"に感謝します。 –

+0

@TusharPatilクール、答えをマークすることを忘れないでください! – cjb110

関連する問題