2012-11-11 78 views
5

से पाठ का उपयोग कर selection.find से लौटने के पृष्ठ संख्या (नोट: समाधान के लिए नीचे देखें।)VBA: सरणी

मैं पृष्ठों है कि विभिन्न शीर्षकों एक शब्द दस्तावेज़ में पर रहते हैं का उपयोग करने से पृष्ठ संख्या प्राप्त करने का प्रयास किया गया है VBA। मेरा वर्तमान कोड या तो 2 या 3 देता है, और सही ढंग से संबंधित पृष्ठ संख्या नहीं, इस पर निर्भर करता है कि मैं अपने मुख्य उप में कहां और कैसे उपयोग करता हूं।

astrHeadings = docSource.GetCrossReferenceItems(wdRefTypeHeading) 

For Each hds In astrHeadings 
     docSource.Activate 
     With Selection.Find 
      .Text = Trim$(hds) 
      .Forward = True 
      MsgBox hds & ":" & Selection.Information(wdActiveEndPageNumber), vbOKOnly 
     End With 
     Selection.Find.Execute 
Next 

docSource एक परीक्षण दस्तावेज़ मैं 3 पृष्ठों पर 10 शीर्षकों के साथ स्थापित किया है। मेरे पास कोड में बाद में उपयोग में getCrossReferenceItems विधि से शीर्षलेख पुनर्प्राप्त किए गए हैं।

मैं जो कोशिश कर रहा हूं वह getCrossReferenceItems विधि से परिणामों को लूप करना है और प्रत्येक को docSource पर ऑब्जेक्ट में ढूंढें और इससे पता लगाएं कि परिणाम किस पृष्ठ पर है। उसके बाद पृष्ठ संख्याओं को बाद में मेरे कोड में एक स्ट्रिंग में उपयोग किया जाएगा। यह स्ट्रिंग प्लस पेज नंबर किसी अन्य दस्तावेज़ में जोड़ा जाएगा जो मेरे मुख्य उप की शुरुआत में बनाया गया है, बाकी सब कुछ एक इलाज करता है लेकिन यह कोड सेगमेंट।

आदर्श रूप से मुझे इस सेगमेंट की आवश्यकता है जो प्रत्येक खोज परिणाम से संबंधित पृष्ठ संख्याओं के साथ एक दूसरी सरणी भरें।

समस्याएं हल

धन्यवाद केविन आप एक बहुत मदद यहाँ किया गया है, अब मैं वास्तव में मैं क्या इस Sub के उत्पादन से की जरूरत है।

डॉकसोर्स एक परीक्षण दस्तावेज है जिसे मैंने 3 पृष्ठों पर 10 शीर्षकों के साथ स्थापित किया है। डॉकऑटलाइन एक नया दस्तावेज़ है जो सामग्री सारणी तालिका के रूप में कार्य करेगा।

मैं क्योंकि इस Sub पद के अंतर्निहित टीओसी सुविधाओं से अधिक का उपयोग करने के लिए किया है:

  1. मैं शामिल करने के लिए एक से अधिक दस्तावेज़ है, मैं RD क्षेत्र इस्तेमाल कर सकते हैं लेकिन

  2. मैं इन शामिल करने के लिए एक और Sub है जो प्रत्येक दस्तावेज़ 0.0.0 (Chapter.section.page प्रतिनिधि) में कस्टम दशमलव पृष्ठ क्रमांकन उत्पन्न करता है, जो पूरे दस्तावेज़ पैकेज को समझने के लिए, TOC में पृष्ठ संख्याओं के रूप में शामिल करने की आवश्यकता है। ऐसा करने का शायद एक और तरीका है लेकिन मैं वर्ड की अंतर्निहित सुविधाओं के साथ खाली हो गया।

यह मेरे पृष्ठ नंबर Sub में शामिल करने के लिए एक समारोह बन जाएगा। मैं वर्तमान में इस छोटी परियोजना को पूरा करने के तरीके के 3/4 हूं, अंतिम तिमाही सीधा होना चाहिए।

संशोधित और अंतिम संहिता साफ

Public Sub CreateOutline() 
' from http://stackoverflow.com/questions/274814/getting-the-headings-from-a-word-document 
    Dim docOutline As Word.Document 
    Dim docSource As Word.Document 
    Dim rng As Word.Range 
    Dim strFootNum() As Integer 
    Dim astrHeadings As Variant 
    Dim strText As String 
    Dim intLevel As Integer 
    Dim intItem As Integer 
    Dim minLevel As Integer 
    Dim tabStops As Variant 

    Set docSource = ActiveDocument 
    Set docOutline = Documents.Add 

    minLevel = 5 'levels above this value won't be copied. 

    ' Content returns only the 
    ' main body of the document, not 
    ' the headers and footer. 
    Set rng = docOutline.Content 
    astrHeadings = docSource.GetCrossReferenceItems(wdRefTypeHeading) 

    docSource.Select 
    ReDim strFootNum(0 To UBound(astrHeadings)) 
    For i = 1 To UBound(astrHeadings) 
     With Selection.Find 
      .Text = Trim(astrHeadings(i)) 
      .Wrap = wdFindContinue 
     End With 

     If Selection.Find.Execute = True Then 
      strFootNum(i) = Selection.Information(wdActiveEndPageNumber) 
     Else 
      MsgBox "No selection found", vbOKOnly 
     End If 
     Selection.Move 
    Next 

    docOutline.Select 

    With Selection.Paragraphs.tabStops 
     '.Add Position:=InchesToPoints(2), Alignment:=wdAlignTabLeft 
     .Add Position:=InchesToPoints(6), Alignment:=wdAlignTabRight, Leader:=wdTabLeaderDots 
    End With 

    For intItem = LBound(astrHeadings) To UBound(astrHeadings) 
     ' Get the text and the level. 
     ' strText = Trim$(astrHeadings(intItem)) 
     intLevel = GetLevel(CStr(astrHeadings(intItem))) 
     ' Test which heading is selected and indent accordingly 
     If intLevel <= minLevel Then 
       If intLevel = "1" Then 
        strText = " " & Trim$(astrHeadings(intItem)) & vbTab & "1" & "." & "2" & "." & strFootNum(intItem) & vbCr 
       End If 
       If intLevel = "2" Then 
        strText = " " & Trim$(astrHeadings(intItem)) & vbTab & "1" & "." & "2" & "." & strFootNum(intItem) & vbCr 
       End If 
       If intLevel = "3" Then 
        strText = "  " & Trim$(astrHeadings(intItem)) & vbTab & "1" & "." & "2" & "." & strFootNum(intItem) & vbCr 
       End If 
       If intLevel = "4" Then 
        strText = "   " & Trim$(astrHeadings(intItem)) & vbTab & "1" & "." & "2" & "." & strFootNum(intItem) & vbCr 
       End If 
       If intLevel = "5" Then 
        strText = "   " & Trim$(astrHeadings(intItem)) & vbTab & "1" & "." & "2" & "." & strFootNum(intItem) & vbCr 
       End If 
      ' Add the text to the document. 
      rng.InsertAfter strText & vbLf 
      docOutline.SelectAllEditableRanges 
      ' tab stop to set at 15.24 cm 
      'With Selection.Paragraphs.tabStops 
      ' .Add Position:=InchesToPoints(6), _ 
      ' Leader:=wdTabLeaderDots, Alignment:=wdAlignTabRight 
      ' .Add Position:=InchesToPoints(2), Alignment:=wdAlignTabCenter 
      'End With 
      rng.Collapse wdCollapseEnd 
     End If 
    Next intItem 
End Sub 

Private Function GetLevel(strItem As String) As Integer 
    ' from http://stackoverflow.com/questions/274814/getting-the-headings-from-a-word-document 
    ' Return the heading level of a header from the 
    ' array returned by Word. 

    ' The number of leading spaces indicates the 
    ' outline level (2 spaces per level: H1 has 
    ' 0 spaces, H2 has 2 spaces, H3 has 4 spaces. 

    Dim strTemp As String 
    Dim strOriginal As String 
    Dim intDiff As Integer 

    ' Get rid of all trailing spaces. 
    strOriginal = RTrim$(strItem) 

    ' Trim leading spaces, and then compare with 
    ' the original. 
    strTemp = LTrim$(strOriginal) 

    ' Subtract to find the number of 
    ' leading spaces in the original string. 
    intDiff = Len(strOriginal) - Len(strTemp) 
    GetLevel = (intDiff/2) + 1 
End Function 

इस कोड को अब उत्पादन किया जाता है (क्या यह मेरे शीर्षकों विनिर्देश परीक्षण doc.docx में पाया के अनुसार होना चाहिए):

This is heading one     1.2.1 
    This is heading two    1.2.1 
    This is heading two.one   1.2.1 
    This is heading two.three  1.2.1 
This is heading one.two    1.2.2 
    This is heading three   1.2.2 
     This is heading four   1.2.2 
      This is heading five  1.2.2 
      This is heading five.one 1.2.3 
      This is heading five.two 1.2.3 

में इसमें वृद्धि .Active का उपयोग करने के बजाय docSource.select और docOutline.Select कथन का उपयोग कर ActiveDocument स्विचिंग समस्या हल कर दी है।

धन्यवाद फिर केविन, बहुत सराहना :-)

फिल

+0

इसके लिए धन्यवाद, फिल। मैंने कोशिश करने के लिए एक नया कोड स्निपेट के साथ अपना जवाब अपडेट कर दिया है। यह मेरे उत्तर में अंतिम कोड खंड है। पोस्टिंग प्रक्रियाओं में कोई समस्या नहीं - इसे सही करने में हमेशा कुछ समय लगता है। :-) –

+0

हालांकि यह सराहनीय है कि आपने अपना अंतिम कोड पोस्ट किया है, मूल प्रश्न अब आपके ediTing – brettdj

उत्तर

5

यह Selection.Information(wdActiveEndPageNumber) तरह लग रहा है बिल फिट होगा, हालांकि यह वर्तमान में आपके कोड के गलत बात में है। आप खोज पर अमल के बाद इस लाइन रखो, ताकि जैसे:

For Each hds In astrHeadings 
    docSource.Activate 
    With Selection.Find 
     .Text = Trim$(hds) 
     .Forward = True 
    End With 
    Selection.Find.Execute 
    MsgBox hds & ":" & Selection.Information(wdActiveEndPageNumber), vbOKOnly 
Next 

नया प्रश्न के लिए अतिरिक्त:

आप strFooter मूल्य निर्धारित कर रहे हैं, जब आप सरणी आकार बदलने के लिए ReDim उपयोग कर रहे हैं ReDim Preserve का उपयोग करना चाहिए:

ReDim Preserve strFootNum(1 To UBound(astrHeadings)) 

लेकिन, जब तक UBound(astrHeadings) प्रश्न में For पाश के दौरान बदल रहा है, यह शायदको खींचने के लिए सबसे अच्छा अभ्यास हो जाएगा लूप के बाहरबयान:

ReDim strFootNum(0 To UBound(astrHeadings)) 
For i = 0 To UBound(astrHeadings) 
    With Selection.Find 
     .Text = Trim(astrHeadings(i)) 
     .Wrap = wdFindContinue 
    End With 

    If Selection.Find.Execute = True Then 
     strFootNum(i) = Selection.Information(wdActiveEndPageNumber) 
    Else 
     strFootNum(i) = 0 'Or whatever you want to do if it's not found' 
    End If 
    Selection.Move 
Next 

संदर्भ के लिए, ReDim बयान एक सरणी में सभी आइटम सेट वापस 0 करने के लिए, ReDim Preserve सरणी में सभी डेटा को बरकरार रखता है, जबकि इससे पहले कि आप का आकार बदलें।

Selection.Move और .Wrap = wdFindContinue लाइनों को भी ध्यान दें - मुझे लगता है कि ये मेरे पिछले सुझावों के साथ इस मुद्दे की जड़ थीं। चयन अंतिम पृष्ठ पर सेट किया जाएगा क्योंकि यह खोज पहले रन के अलावा किसी अन्य रन पर लपेट नहीं रहा था।

+0

पोस्ट के बाद स्पष्ट नहीं है हाय केविन मेरे पास 15+ प्रतिनिधि नहीं है, इसलिए आप अभी तक वोट नहीं दे सकते :-( –

+0

ठीक है - सब अच्छे समय में! :-) खुशी है कि मैं मदद कर सकता हूँ! –