2016-04-09 26 views
2

C# de çok yeni ve oldukça karışık bir kod yazdım. İnternette çok fazla kurs yapıyorum ve bir çok problemlere yaklaşmanın çeşitli yolları olduğunu söyleyebilirim. Şimdi bir .Doc Word dosyasını yükleyecek ve ifadeler kullanarak ilgili bilgileri arayacak bir program yaptık.Word Interop işleme nasıl hızlandırılır?

Şimdi benim çözümümdeki benim problemim bu programın FOREVER almasıdır! Aşağıdaki kodu tamamlamak için 30Mins - 1Hour hakkında konuşuyorum.

Benim küçük programımı biraz daha az nasıl temizleyeceğime dair herhangi bir fikir var mı? İnşallah bu çözümlerin bilgimi önemli ölçüde arttıracağını umuyorum ki şimdiden teşekkürler!

Saygılarımızla chris

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace WindowsFormsApplication3 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 
     public int id = 0; 
     public int[] iD = new int[100]; 
     public string[] timeOn = new string[100]; 
     public string[] timeOff = new string[100]; 
     public string[] dutyNo = new string[100]; 
     public string[] day = new string[100]; 

     private void button1_Click(object sender, EventArgs e) 
     { 



      Microsoft.Office.Interop.Word.Application application = new Microsoft.Office.Interop.Word.Application(); 
      Microsoft.Office.Interop.Word.Document document = application.Documents.Open("c:\\Users\\Alien\\Desktop\\TESTJOBS.doc"); 
      //the following for will loop for all words 

      int count = document.Words.Count; 
      for (int i = 1; i <= count; i++) 
      { 
       // the following if statement will look for the first word that is On 
       // this is then (on the file) proceded by 04:00 (thus i+2/3/4 respectively) 
       if (document.Words[i].Text == "On") 
       { 
        iD[id] = id; 
        // Console.WriteLine("ID Number ={0}", iD[id]); 
        dutyNo[id] = document.Words[i - 14].Text; 
        // Console.WriteLine("duty No set to:{0}", dutyNo[id]); 
        timeOn[id] = document.Words[i + 2].Text + document.Words[i + 3].Text + document.Words[i + 4].Text; 
        // Console.WriteLine("on time set to:{0}", timeOn[id]); 
        // the following if (runs if the last word was not "On" and then searches for the word "Off" which procedes "On" in the file format) 
        // this is then (on the file) proceded by 04:00 (thus i+2/3/4 respectively) 
       } 
       else if (document.Words[i].Text == "Off") 
       { 
        timeOff[id] = document.Words[i + 2].Text + document.Words[i + 3].Text + document.Words[i + 4].Text; 
        //Console.WriteLine("off time set to:{0}", timeOff[id]); 
        // the following if (runs if the last word was not "Off" and then searches for the word "Duty" which procedes "Off" in the file format) 
        // this is then (on the file) proceded by 04:00 (thus i+2/3/4 respectively) 
       } 
       else if (document.Words[i].Text == "Days" && !(document.Words[i + 3].Text == "Type")) 
       { 

        day[id] = document.Words[i + 2].Text; 
        //Console.WriteLine("day set to:{0}", day[id]); 
        //we then print the whole new duty out to ListBox1 
        listBox1.Items.Add(string.Format("new duty ID:{0} Time on:{1} Time off:{2} Duty No:{3} Day:{4}", iD[id], timeOn[id], timeOff[id], dutyNo[id], day[id])); 
        id++; 
       } 


      } 

      for (int i = 1; i <= 99; i++) 
      { 
       Console.WriteLine("new duty ID:{0} Time on:{1} Time off:{2} Duty No:{3} Day:{4}", iD[id], timeOn[id], timeOff[id], dutyNo[id], day[id]); 
      } 


     } 
    } 
} 
+1

: \\ Users \ \ Alien \\ Desktop \\ TESTJOBS.doc "_) –

+0

haha ​​onlar bana sadece onları ışınladı! –

+1

Zamanın ne olduğunu görmek için zamanlama teşhislerini (Kronometre sınıfı) koda koydunuz mu? – ChrisF

cevap

2

Büro Interop'un fairly slow olduğunu.

Openxml, faster olabilir, ancak dosya .doc'dur, bu nedenle büyük olasılıkla işleyemeyecektir. AFAIK bu RCW sarılı ayrı Range örneğinin oluşturulmasını neden olduğu, indeksi tarafından Range her kelimeyi erişmezseniz -


Ama sadece this question yılında Excel ile benzeri

performansı artırabilirsiniz bir yol var Ve bu uygulamada bir performans darboğazı için birincil adaydır. en iyi bahis performansını artırmak anlamına gelir

fiili işlemesi önce String s bazı çift taraflı koleksiyonuna yük tüm kelimeler (.Text) etmektir ve ancak o zaman çıktı oluşturmak için bu koleksiyonu kullanın.

En hızlı şekilde nasıl yapılır? Tam olarak emin değilim, ancak _Document.Wordsenumerator'dan tüm kelimeleri almayı deneyebilirsiniz (daha fazla performans gösterebilir veya olmayabilir, ancak en azından gerekli kelimeleri almak için ne kadar zaman gerektiğini görebilirsiniz):

var words = document 
    .Cast<Range>() 
    .Select(r => 
     r.Text) 
    .ToList(); 

veya daha sonra kendiniz tek kelimeleri ayırmak zorunda kalacak olsa _Document.Content aralığı Text kullanmayı deneyebilirsiniz. Bunun yerine kullanmanın

+0

Teşekkür ederim Eugene Yarın bu değişiklikler üzerinde çalışacağım. –

0

: döngü üstündeki

String Text = document.Words[i].Text; 

ve "Metin" (veya ne olursa olsun onu aramak istediğiniz) yerine kullanın:

document.Words[i].Text 

birden çok kez yapmak. Eugene Podskal'ın önerileri çok yardımcı görünüyor ama bu basit gelişim (Eugene'nin cevabını görmeden önce düşündüğümdür) yapmak çok kolay ve önemli bir gelişme sağlayabiliyor.

+0

Bunun işe yaramayacağını düşünmüyorum, çünkü kelimeler [i] 'i kullanıyorum ve İfadelerin kendileri için gerekli bilgilerin belirli yerlerini bulmak için yukarı ve aşağı doğru ilerliyorum. Eğer yanılıyorsam beni düzeltin! –

0

Tamam Tamam, tamam şimdi tüm bilgileri daha önce olduğu gibi işleme alıp belgenin tamamını içe aktarıyoruz. Toplam çalışma zamanı 2780 cümle için 02: 09.8 ve yaklaşık 44.000 kelime (boşluklar dahil!) Aşağıda (C# 2 hafta önce aldığım düşünüldüğünde kötü değil) kötü değil;

public Form1() 
    { 
     InitializeComponent(); 
    } 
    public int id = 0; 
    public int[] iD = new int[400]; 
    public string[] timeOn = new string[400]; 
    public string[] timeOff = new string[400]; 
    public string[] dutyNo = new string[400]; 
    public string[] day = new string[400]; 
    public string[] hours = new string[400]; 

    //Create File Location Var 
    public string fileLocation = null; 

    // On Click of Add Dutys 
    private void button1_Click(object sender, EventArgs e) 
    { 
     //Sets Progress Bar visible and prepares to increment 
     pBar1.Visible = true; 
     pBar1.Minimum = 1; 
     pBar1.Value = 1; 
     pBar1.Step = 1; 


     //Stopwatch test Declared 
     Stopwatch stopWatch = new Stopwatch(); 

     try { 
      //Self Test to see if a File Location has been set for Duty document. 
      if (fileLocation == null) { 
       //If not set prompts user with message box and brings up file explorer 
       MessageBox.Show("It Appears that a file location has not yet been set, Please Select one now."); 
       Stream myStream = null; 
       OpenFileDialog openFileDialog1 = new OpenFileDialog(); 
       //Sets default Location and Default File type as .doc 
       openFileDialog1.InitialDirectory = "c:\\"; 
       openFileDialog1.Filter = "All files (*.*)|*.*|Word Files (*.doc)|*.doc"; 
       openFileDialog1.FilterIndex = 2; 
       openFileDialog1.RestoreDirectory = true; 
       //Waits for User to Click ok in File explorer and then Sets file location to var 
       if (openFileDialog1.ShowDialog() == DialogResult.OK) 
       { 
        try 
        { 
         //Checks to make sure a file location is set 
         if ((myStream = openFileDialog1.OpenFile()) != null) 
         { 
          using (myStream) 
          { 
           //This is where we set location to var 
           fileLocation = openFileDialog1.FileName; 
          } 
          //Prompts user to click a file before OK 
         }else { MessageBox.Show("Please Select a file location before clicking ok"); } 
        } 
        catch (Exception ex) 
        { 
         MessageBox.Show("Error: Could not read file from disk: " + ex.Message); 
        } 
       } 
      } 

      //Loads New Duty file 
      Microsoft.Office.Interop.Word.Application application = new Microsoft.Office.Interop.Word.Application(); 
      Microsoft.Office.Interop.Word.Document document = application.Documents.Open(fileLocation); 
      //Begin stop watch (COPY TIME) 
      stopWatch.Start(); 

      //Sets Count to No of sentences and then prepares Array using Number of sentences 
      //**This process reduces amount of processng time by taking everything in to the program to start and then dealing with it. 
      int count = document.Sentences.Count; 
      string[] sents = new string[count]; 
      //Then sets the Progress bar to the Number of sentences that will be Copied to our array 
      pBar1.Maximum = count; 

      try { 
       //For loop runs throug every sentence and adds it to the array. 
       for (int i = 0; i < count; i++) { 
        sents[i] = document.Sentences[i+1].Text; 
        //increment Progress bar by 1 for every sentence(Parse made) 
        pBar1.PerformStep(); 
       } 
       //Closes our instance of word 
       application.Quit(); 
       try { 

        for (int i = 0; i < count; i++) 
        { 
         //Sets our Split criteria 
         char[] delimiterChars = { ' ','\t' }; 
         string[] test = (sents[i].Split(delimiterChars)); 
         //we then enter For loop that runs for the number of ords found/Split 
         for (int a = 0; a < test.Length; a++) 
         { 
          //If tests only begin if the word is NOT a space blank, tab , - As these do parse through into our Test arrays 
          if (!(test[a] == "" || test[a].Contains("/t")|| test[a].Contains("-") || test[a].Contains(" "))) 
          { 
           //If tests to find Duty numbers ours on off and assigns ID number for easy indexing. 
           //##THIS DOES ASSUME THAT OUR TIMES ARE 1 SPACE AFTER THEIR IDENTIFIERS. 
           if (test[a] == "TG") 
           { 
            dutyNo[id] = test[a + 2]; 
           } 
           else if (test[a] == "On") 
           { 
            iD[id] = id; 
            timeOn[id] = test[a + 1]; 
           } 
           else if (test[a] == "Off") 
           { 
            timeOff[id] = test[a + 1]; 
           } 
           else if (test[a] == "Hrs") 
           { 
            hours[id] = test[a + 1]; 
           } 
           else if (test[a] == "Days") 
           { 
            day[id] = test[a + 1]; 
            //PRINTS TO USER VIA LIST BOX ALL THE DUTYS ADDED. 
            listBox1.Items.Add(string.Format("ADDED:Duty No:{3} Time on:{1} Time off:{2} Hours{5} Day:{4} ID:{0}", iD[id], timeOn[id], timeOff[id], dutyNo[id], day[id], hours[id])); 
            id++; 
           } 

          } 
         } 
        } 
       } 
       catch(Exception ex) { MessageBox.Show("Error in split:" + ex.Message); } 
      } 
      catch(Exception ex) { MessageBox.Show("error setting string to Document:" + ex.Message); } 
      //Stopwatch Is then printed for testing purposes. 
      TimeSpan ts = stopWatch.Elapsed; 
      string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, 
      ts.Milliseconds/10); 
      Console.WriteLine("RunTime (total):" + elapsedTime); 

      stopWatch.Reset(); 

     } 
     catch(Exception ex) { MessageBox.Show("Error in reading/finding file: "+ ex.Message); } 

    } 


} 

}

Oldukça büyük Liste kutusu (ListBox1) bir düğme (Button1) ve başlangıç ​​İlerleme çubuğu (pBar1) üzerinde Olmayan Görünür tüm bu kodu kullanın.

0

Sen openxml ve süreç ile tüm .content aralığı yükleyebilir böyle, o zaman reimport zaman Aliens dan açık belgeler ... (_ "Aç (" c böyle olur

İlgili konular