Problem in short:
I need to iterate through all paragraphs in reverse order. I am currently using a For Each loop:
For Each Paragraph in ActiveDocument.Paragraphs
' looping code
Next
Why I need to do this:
I have an export from a tool which incorrectly formats list elements. I need to go through and set all of these elements to the 'List' word style.
I have this part working using the various ListFormat properties on the paragraph. the problem is that the lists just continue, they dont retain when a list restarts. I end up with the list number being aaaaa. then bbbbb. etc.
I intended to use the ListFormat.ListValue property to determine when to restart the list (would restart when this value = 1), but this wont work, as when you transition one paragraph element to the new 'List' type, the following paragraph automatically resets the ListFormat.ListValue to 1 as well. If I can loop through paragraphs in reverse this will no longer be a problem.
Instead of using a For Each loop, iterate through the paragraphs by index, and you can easily loop from the last paragraph to the first with Step -1.
Sub Test()
Dim i As Long
For i = ActiveDocument.Paragraphs.Count To 1 Step -1
ActiveDocument.Paragraphs(i).... ' do whatever you want with each paragraph
Next i
End Sub
Related
Writing a macro to automatically fix paraphrase spacing issues in MS Word docs generated from software we use.
Goal:
All standard paragraphs have 0pt before and after spacing.
All bullet lists have 3pt before and after spacing.
Progress:
Currently I have a function that sets the entire document to 0pt, then looks through for all lists and changes them to 3pt. (currently also have a highlight on so I can easily see what is being treated as a list).
It works great on some parts, but on other parts (I assume based on how the software we use generates the document), the list doesn't exist and it will continue to format blocks of text and heading to 3pt when it is not wanted (see attached images).
Current code is:
Sub Paragraph()
ActiveDocument.Range.ParagraphFormat.SpaceAfter = 0
ActiveDocument.Range.ParagraphFormat.SpaceBefore = 0
Dim li As Word.list
For Each li In ActiveDocument.lists
li.Range.ParagraphFormat.SpaceBefore = 3
li.Range.ParagraphFormat.SpaceAfter = 3
li.Range.HighlightColorIndex = wdYellow
Next li
End Sub
Working:
Not working:
According to the MSDN:
List Object: Represents a single list format that's been applied to specified paragraphs in a document.
So if you have more than one list with some non-bulleted paragraph(s) in the middle, the Range will start with the first item of the first list and end with the last item of the last list including all non-bulleted paragraph(s) in the middle.
To fix this issue, you need to separate the lists (right-click on the bullet and select Separate List). However, you mentioned that the document was generated by some software, so that is probably not an option. In that case, you will have to iterate though the paragraphs of the Range of each List and check if it has a ListFormat.ListTemplate which indicates that it is a list item, otherwise it is a non-bulleted paragraph:
Sub Paragraph()
ActiveDocument.Range.ParagraphFormat.SpaceAfter = 0
ActiveDocument.Range.ParagraphFormat.SpaceBefore = 0
Dim li As Word.List
Dim p As Paragraph
For Each li In ActiveDocument.Lists
For Each p In li.Range.Paragraphs
If Not p.Range.ListFormat.ListTemplate Is Nothing Then
p.Range.ParagraphFormat.SpaceBefore = 3
p.Range.ParagraphFormat.SpaceAfter = 3
p.Range.HighlightColorIndex = wdYellow
End If
Next p
Next li
End Sub
Even before touching VBA:
Use Styles in the document.
Limit the use of Styles in the document to only those that are in the
template.
Set your spacing in the Styles.
If, at some stage, you change your mind and want to use 6pt spacing, you can adjust the template and re-apply it, rather than finding all the VBA code and re-writing it. Not only that, but by using Styles, you can avoid having VBA code, or having VBA-enabled documents which may interfere with some corporate security settings.
Oh, and set up your corporate structure to limit the use of templates to only the approved ones.
I have a word document with automatic numbering and bulleting.
I have selected the text where I need to convert automating numbering and/or bulleting to normal text.
In addition I need to keep both the formatting and numbers/bullets of the selected text.
What I have already tried:
cut the paragraphs and special pasted them (but it breaks formatting);
unpressed the "numbering"/"bulleting" button (but it erases all numbers and bullets);
used VBA-macro (but it returns an error):
Code (error, method or data member not found):
Sub convertNumbersAndBulletsToText()
Selection.ConvertNumbersToText
End Sub
What would you recommend me to do in order to keep both formatting and numbers/bullets?
You have practically done everything yourself!
This code will work:
Sub convertNumbersAndBulletsToText()
Selection.Range.ListFormat.ConvertNumbersToText
End Sub
Your example returns error because ConvertNumbersToText method doesn't work with Selection. It works with Range!
(look here: Change selected automatic numbered list to plain text in word)
Beware!
If you want to carry out many changes, you may find it easier to make them with ActiveDocument (look below).
But if want to do it manually (or through a loop),
then you'd better loop from the last element you want to convert till the first one
(not vice versa, because auto-numbers would then increment by one all the time)!
Small Tips
Personally I would recommend you to use this code instead:
Sub convertNumbersAndBulletsToText()
Dim myRange As Range
Set myRange = Selection.Range
myRange.ListFormat.ConvertNumbersToText
End Sub
Why this one? It is a little bit more flexible! Instead of Selection.Range you could use any other type of Range (ActiveDocument, ActiveDocument.Paragraphs, myRange.SetRange etc)
Here are some links from msdn to give you basic examples of Ranges: 1) Range Object (Word) (msdn), 2)
Range.SetRange Method (Word) (msdn).
Just for your information, you don't need to save VBA if you don't want to. You can use Immediate Window to launch VBA.
Press alt+f11 (VBA-editor), then ctrl+g (Immediate Window).
Paste the code bellow, press enter.
VoilĂ !
Code (for Immediate Window):
ActiveDocument.ConvertNumbersToText
(It converts auto-numbers and auto-bullets to normal numbers and bullets everywhere in ActiveDocument).
The result of any VBA here would be number+tab+text. If you want to have number+space+text you can:
either at the very end replace (press ctrl+h) this one .^t (dot and tab) for . (dot and whitespace),
or at the very beginning 1) select the list, 2) right click on it, 3) click "Adjuct list idents", 4) click "Follow number with: Space". (Look here: Adjust the spacing for a single list item (support.office))
You may need to have a leading zero in (auto-)numbering, then you can press ctrl+f9, write SEQ MyList \# "000" inside curly brackets, press alt+f9 to finish (look here: Insert fields in Word (support.office)). But this goes beyond the question, though you may find word fields really useful in some cases.
To sum up:
You can replace both bullets and numbers for plain text in Word:
for Selection (look above);
for ActiveDocument (look above);
with a Range (examples in msdn);
with a loop (examples are welcomed). But bear in mind that you are to loop from the end of the document to the beginning.
I am new in VBA for Word
I was wondering if it is possible to use ASCII code in .MoveEndUntil for example: .MoveEndUntil cset:=Chr(13) & "-", Count:=wdForward
Yes, it is totally possible to use sample code from your question. However, it depends what you are trying to achieve. Your code will move the end of the selection until any of the specified characters are found in the document (see the documentation of the Range.MoveEndUntil method).
That means that moving the end of the range will stop as soon as a dash or a carriage return is reached.
However, this is probably not what you want. It looks like you are trying to extend the range until the next list item? If this should be the case then you can't use a simple Range.MoveEndUntil. You would have to expand the range to the end of the current paragraph and check whether the following paragraph has a list formatting.
I am looking a way to convert the Bullets in Word document to simple text. E.g.
I have these kind of Bullets:
a)-> Apple
b)-> Orange
c)-> Mangoes
I want them to be like this:
a)Apple
b)Oranges
c)Mangoes
I am using this code but it removes the Bullets entirely:
Dim oPara As Paragraph
For Each oPara In ActiveDocument.Paragraphs()
Set r = oPara.Range
If r.ListFormat.RemoveNumbers = wdListBullet Then
r.ListFormat.ApplyListTemplate _
ListTemplate:=ListGalleries(wdNumberGallery) _
.ListTemplates(1)
End If
Set r = Nothing
Next
Is ActiveDocument.ConvertNumbersToText what you're after?
It can also be run on a specific list if you're not doing this globally.
ETA: It seems like ConvertNumbersToText takes a NumberType argument (this isn't documented by the 2010 spec that F1 brings up, but it is valid). Perhaps the default doesn't apply to all the bullets in your document. A combination of the three possibilities might work.
ActiveDocument.ConvertNumbersToText(wdNumberParagraph) 'Preset numbers you can add to paragraphs by selecting a template in the Bullets and Numbering dialog box.
ActiveDocument.ConvertNumbersToText(wdNumberListNum) 'Default value for LISTNUM fields.
ActiveDocument.ConvertNumbersToText(wdNumberAllNumbers) 'Default value for all other cases.
I tend to use the first one, but your case might be different.
the webapp was already done on office2007 and i need to convert it so it'll work in office2010.
i was able to convert the header generator part of the code but i have problem with the body of the doc itself. the code copy the data from a "data" doc and paste it into the generated doc.
appword.activewindow.activepane.view.seekview = 0
'set appsel1 = appword.activewindow.selection
set appsel1 = appword.window(filepath).selection -that is the original one
appdoc1.bookmarks("b1").select
appword.selection.insertafter("some text")
appsel1.endkey(6) -the code stops here
appword.selection.insertafter("some other text")
the iexplorer debuger says ERROR:appsel1 object required. and when i view its data using the iexplorer debugger its data is "empty" instead of "{...}"
can anyone tell me what i'm doing wrong
if you need more of the code tell me.
From MSDN
After this method is applied, the selection expands to include the new
text.
If you use this method with a selection that refers to an entire
paragraph, the text is inserted after the ending paragraph mark (the
text will appear at the beginning of the next paragraph). To insert
text at the end of a paragraph, determine the ending point and
subtract 1 from this location (the paragraph mark is one character).
However, if the selection ends with a paragraph mark that also happens
to be the end of the document, Microsoft Word inserts the text before
the final paragraph mark rather than creating a new paragraph at the
end of the document.
Also, if the selection is a bookmark, Word inserts the specified
text but does not extend the selection or the bookmark to include the
new text.
So I suspect that you still have no selected text.
I wonder if you can do a Selection Collapse(wdCollapseStart) but that's just a thought.