2012-03-01 13 views
11

का उपयोग करके वर्ड दस्तावेज़ में खोज प्रतिस्थापन के प्रदर्शन में सुधार करें कुछ प्रयोगों के बाद मैं एमएसडॉर्ड में खोज और प्रतिस्थापन करने के लिए निम्न कोड के साथ समाप्त हुआ। यह कोड शीर्षलेख और पाद लेख में पूरी तरह से काम करता है, जिसमें पहले पृष्ठ या अजीब/यहां तक ​​कि पृष्ठों के लिए हेडर और/या पाद लेख अलग-अलग हैं।ओएलई और डेल्फी

समस्या यह है कि मुझे प्रतिस्थापित प्रत्येक स्ट्रिंग के लिए MSWordSearchAndReplaceInAllDocumentParts पर कॉल करने की आवश्यकता है, और मुझे एक अस्वीकार्य प्रदर्शन (4 पेज डॉक शब्द में लगभग 50 तारों के लिए 2 मिनट) मिलते हैं। आदर्श रूप में यह निश्चित रूप से "तात्कालिक" होना चाहिए।

शीर्षलेख और पाद लेखों को संभालने से पहले मैं केवल मुख्य दस्तावेज़ (wdSeekMainDocument का उपयोग करके) खोज और प्रतिस्थापित कर रहा था। उस स्थिति में perofmrance स्वीकार्य था (भले ही काफी धीमी हो)। मुझे आश्चर्य है कि यह इतना धीमा क्यों है: स्विचिंग दृश्य में समय लगता है? आम तौर पर शीर्षलेख या पाद लेख में कुछ शब्द होते हैं, इसलिए मुझे उम्मीद थी कि हेडर और पाद लेखों में सभी खोज और प्रतिस्थापन समग्र प्रदर्शन को इतना खराब नहीं बना रहा था। लेकिन यह मैंने नहीं देखा है।

इस कोड है, तल पर मैं प्रोफाइलर परिणाम रख:

// global variable (just for convenience of posting to Stack Overflow) 
var 
aWordApp: OLEVariant; // global 

// This is the function that is executed once per every string I replace 
function MSWordSearchAndReplaceInAllDocumentParts; 
begin 
    try 
     iseekValue := aWordApp.ActiveWindow.ActivePane.View.SeekView; 
     iViewType := aWordApp.ActiveWindow.ActivePane.View.Type; 
     if iViewType <> wdPrintView then 
     aWordApp.ActiveWindow.ActivePane.View.Type := wdPrintView; 
     if aWordApp.ActiveDocument.PageSetup.OddAndEvenPagesHeaderFooter then 
     begin 
     Try 
      aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekEvenPagesFooter; 
      SearchAndReplaceInADocumentPart; 
     Except 
      // do nothing ..it was not able to set above view 
     end; 
     Try 
      aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekEvenPagesHeader; 
      SearchAndReplaceInADocumentPart; 
     Except 
      // do nothing ..it was not able to set above view 
     end; 
     end; 
     if aWordApp.ActiveDocument.PageSetup.DifferentFirstPageHeaderFooter then 
     begin 
     Try 
      aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekFirstPageFooter; 
      SearchAndReplaceInADocumentPart; 
     Except 
      // do nothing ..it was not able to set above view 
     end; 
     Try 
      aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekFirstPageHeader; 
      SearchAndReplaceInADocumentPart; 
     Except 
      // do nothing ..it was not able to set above view 
     end; 
     end; 
     //Replace in Main Docpart 
     Try 
     aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekMainDocument; 
     SearchAndReplaceInADocumentPart; 
     Except 
      // do nothing ..it was not able to set above view 
     end; 
     //Replace in Header 
     Try 
     aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekCurrentPageHeader; 
     SearchAndReplaceInADocumentPart; 
     Except 
      // do nothing ..it was not able to set above view 
     end; 
     //Replace in Footer 
     Try 
     aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekCurrentPageFooter; 
     SearchAndReplaceInADocumentPart; 
     Except 
      // do nothing ..it was not able to set above view 
     end; 
     //Replace in Header 
     Try 
     aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekPrimaryHeader; 
     SearchAndReplaceInADocumentPart; 
     Except 
     // do nothing ..it was not able to set above view 
     end; 
     //Replace in Footer 
     Try 
     aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekPrimaryFooter; 
     SearchAndReplaceInADocumentPart; 
     Except 
     // do nothing ..it was not able to set above view 
     end; 
    finally 
     aWordApp.ActiveWindow.ActivePane.View.SeekView := iseekValue; 
     if iViewType <> wdPrintView then 
     aWordApp.ActiveWindow.ActivePane.View.Type := iViewType; 
    end; 
end; 

// This is the function that performs Search And Replace in the selected View 
// it is called once per view 

function SearchAndReplaceInADocumentPart; 
begin 
    aWordApp.Selection.Find.ClearFormatting; 
    aWordApp.Selection.Find.Text := aSearchString; 
    aWordApp.Selection.Find.Replacement.Text := aReplaceString; 
    aWordApp.Selection.Find.Forward := True; 
    aWordApp.Selection.Find.MatchAllWordForms := False; 
    aWordApp.Selection.Find.MatchCase := True; 
    aWordApp.Selection.Find.MatchWildcards := False; 
    aWordApp.Selection.Find.MatchSoundsLike := False; 
    aWordApp.Selection.Find.MatchWholeWord := False; 
    aWordApp.Selection.Find.MatchFuzzy := False; 
    aWordApp.Selection.Find.Wrap := wdFindContinue; 
    aWordApp.Selection.Find.Format := False; 
    { Perform the search} 
    aWordApp.Selection.Find.Execute(Replace := wdReplaceAll); 
end; 

यहाँ मैं रूपरेखा परिणाम पेस्ट (मैं aqtime समर्थक है): enter image description here

आप कृपया मुझे pinpointing में मदद कर सकते हैं मुसीबत?

+0

यदि आपको वास्तव में ओएलई/एक्टिवएक्स के माध्यम से वर्ड का उपयोग करके प्रदर्शन की आवश्यकता है तो मूल रूप से इसे काटने वाला नहीं है ... शब्द दस्तावेज़ों को एक विकल्प को संभालने के लिए लाइब्रेरी (वर्ड निर्भरता के बिना) का उपयोग कर रहा है? – Yahia

+3

बेहतर होगा यदि आप बेंचमार्किंग के लिए उचित नमूना दस्तावेज प्रदान कर सकते हैं। – menjaraz

+0

क्या आप प्रोफाइलिंग परिणामों पर विस्तार कर सकते हैं: सेकंड या मिलीसेकंड में समय, प्रति हिट या सभी हिट का संचयी समय है? –

उत्तर

8

मुझे मेरी मशीन पर परीक्षण करते समय इतना भयानक प्रदर्शन दिखाई नहीं दिया, लेकिन फिर भी, प्रदर्शन में सुधार करने के तरीके हैं।

MSWordSearchAndReplaceInAllDocumentParts को कॉल करने से पहले aWordApp.ActiveWindow.VisibleFalse पर सबसे बड़ा सुधार सेट कर रहा है।

दूसरा सुधार aWordApp.ScreenUpdatingFalse पर सेट कर रहा है।

जब आप पंक्ति में कई बार MSWordSearchAndReplaceInAllDocumentParts को कॉल कर रहे हैं, तो एक बार सेटिंग्स के ऊपर लागू करें। इसके अलावा, MSWordSearchAndReplaceInAllDocumentParts को कई बार कॉल करने से पहले ActiveWindow.ActivePane.View.Type से wdPrintView पर सेट करें।

संपादित करें:

मैं जिस तरह से आप डी को खोजने बदलकर एक और सुधार मिला/बदल देते हैं: इसके बजाय SeekView बदलने की, सभी वर्गों के माध्यम से पुनरावृति और दस्तावेज़ की सीमा हो, हेडर और खुद के पाद और उन श्रेणियों पर खोजें/बदलें।

procedure TForm1.MSWordSearchAndReplaceInAllDocumentParts(const aDoc: OleVariant); 
var 
    i: Integer; 
    lSection: OleVariant; 
    lHeaders: OleVariant; 
    lFooters: OleVariant; 
    lSections: OleVariant; 
begin 
    lSections := aDoc.Sections; 
    for i := 1 to lSections.Count do 
    begin 
    lSection := lSections.Item(i); 
    lHeaders := lSection.Headers; 
    lFooters := lSection.Footers; 
    if lSection.PageSetup.OddAndEvenPagesHeaderFooter then 
    begin 
     SearchAndReplaceInADocumentPart(lHeaders.Item(wdHeaderFooterEvenPages).Range); 
     SearchAndReplaceInADocumentPart(lFooters.Item(wdHeaderFooterEvenPages).Range); 
    end; 
    if lSection.PageSetup.DifferentFirstPageHeaderFooter then 
    begin 
     SearchAndReplaceInADocumentPart(lHeaders.Item(wdHeaderFooterFirstPage).Range); 
     SearchAndReplaceInADocumentPart(lFooters.Item(wdHeaderFooterFirstPage).Range); 
    end; 
    SearchAndReplaceInADocumentPart(lHeaders.Item(wdHeaderFooterPrimary).Range); 
    SearchAndReplaceInADocumentPart(lFooters.Item(wdHeaderFooterPrimary).Range); 

    SearchAndReplaceInADocumentPart(lSection.Range); 
    end; 
end; 

procedure TForm1.SearchAndReplaceInADocumentPart(const aRange: OleVariant); 
begin 
    aRange.Find.ClearFormatting; 
    aRange.Find.Text := aSearchString; 
    aRange.Find.Replacement.Text := aReplaceString; 
    aRange.Find.Forward := True; 
    aRange.Find.MatchAllWordForms := False; 
    aRange.Find.MatchCase := True; 
    aRange.Find.MatchWildcards := False; 
    aRange.Find.MatchSoundsLike := False; 
    aRange.Find.MatchWholeWord := False; 
    aRange.Find.MatchFuzzy := False; 
    aRange.Find.Wrap := wdFindContinue; 
    aRange.Find.Format := False; 

    { Perform the search} 
    aRange.Find.Execute(Replace := wdReplaceAll); 
end; 

यदि आप दस्तावेज़ को खोलने आप संशोधित करना है, जबकि आवेदन अदृश्य है चाहते हैं, या यदि आप दर्शनीय साथ दस्तावेज़ को खोलने तुम भी एक बड़ा सुधार देखेंगे: झूठी =; (फिर से दिखाई देने वाले एप्लिकेशन को सेट करने से दस्तावेज़ भी दिखाई देगा)।

+0

सुझावों के लिए धन्यवाद, मैं उन्हें आज़माउंगा, वे समझ में आ जाएंगे। केवल एक जिसे मैं समझ नहीं पा रहा हूं wdPrintVIew है, जो ऐसा करने का लाभ है? – LaBracca

+0

एक और टिप्पणी: मेरे मामले में प्रदर्शन भयानक है क्योंकि मैं लगभग 150 तारों (प्रोफाइलर परिणामों के अनुसार) को प्रतिस्थापित करता हूं। – LaBracca

+0

इसके अलावा मैं पहले से ही aWordApp.AcitveWIndow सेट कर रहा हूं। गलत के लिए दृश्यमान। – LaBracca

संबंधित मुद्दे