VBA word restart numbering at 1after each heading - vba

I have a piece of code for a word document that reads its own table of contents and then searches a particular folder for a word document related to each heading. It then copies the contents and pastes it under the appropriate heading. However, these pieces of text are in the form of a numbers list and when they are pasted in, the numbering continues from the previous heading and won't restart at 1. I have tried a few different pieces of code, which I found my recording a macro and I had it where it changed the first number but then from the second number it continued from the last. I feel that I probably need a loop to iterate through the numbers list but I am not sure how to implement this. I would really appreciate any help with this as I am out of ideas.
Thank you in advance!
Robbie
Sub InsertRoomDocumentFile()
'Declare variables
Dim a As String
Dim header As String
Dim f As String
Dim sourceDocument As Document
Dim tocItems As Variant
Dim myField As Field
Set sourceDocument = ActiveDocument
'Call Table of contents function
tocItems = GetTOCItems
a = "\\HEADFOP002V\ST_Dolan_R$\windows\Desktop\"
f = ".docx"
'Print table of contents to window
counter = 0
For Each myField In sourceDocument.TablesOfContents(1).Range.Fields
'Debug.Print myField.result.Text ', Chr(13), "-") & " " & " Type: " & myField.Type
If counter <> 0 Then
header = myField.result.Text
Debug.Print header
Total = a + header + f
Documents.Open FileName:=Total, ReadOnly:=True
Set myWindow = Windows(1)
winNum = myWindow.Index
If Windows.Count >= 2 Then
ActiveDocument.Range(0, 0).Select
Selection.WholeStory
ActiveDocument.Range(WholeStory).Copy
myWindow.Close
If counter = 1 Then
Selection.GoTo What:=wdGoToHeading, Which:=wdGoToFirst
Selection.GoTo What:=wdGoToLine, Which:=wdGoToRelative, Count:=1
Else
Selection.GoTo What:=wdGoToHeading, Which:=wdGoToNext
Selection.GoTo What:=wdGoToLine, Which:=wdGoToRelative, Count:=1
End If
Selection.Range.Paste
End If
End If
DoEvents
counter = counter + 1
Next
End Sub
This is the macro I recorded to restart the numbering. I have included the Selection.Range.Paste line to show you where I put it into my code.
Selection.Range.Paste 'Paste the copied file under the appropriate heading
With ListGalleries(wdNumberGallery).ListTemplates(1).ListLevels(1)
.NumberFormat = "(%1)"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = CentimetersToPoints(-1.27)
.Alignment = wdListLevelAlignLeft
.TextPosition = CentimetersToPoints(-0.27)
.TabPosition = wdUndefined
.ResetOnHigher = 0
.StartAt = 1
With .Font
.Bold = wdUndefined
.Italic = wdUndefined
.StrikeThrough = wdUndefined
.Subscript = wdUndefined
.Superscript = wdUndefined
.Shadow = wdUndefined
.Outline = wdUndefined
.Emboss = wdUndefined
.Engrave = wdUndefined
.AllCaps = wdUndefined
.Hidden = wdUndefined
.Underline = wdUndefined
.Color = wdUndefined
.Size = wdUndefined
.Animation = wdUndefined
.DoubleStrikeThrough = wdUndefined
.Name = ""
End With
.LinkedStyle = ""
End With
ListGalleries(wdNumberGallery).ListTemplates(1).Name = ""
Selection.Range.ListFormat.ApplyListTemplate ListTemplate:= _
ListGalleries(wdNumberGallery).ListTemplates(1), ContinuePreviousList:= _
False, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _
wdWord10ListBehavior

Related

VBA Bullet listing for individual header items

Attached is my code my I tried to format a bullet list.
For example if I have the following list
I am trying to change to bullet from the following:
But I managed to change to the following using the code I have describe below,
The is some problem: the 1st bullet point is still bullet form.
The 2nd bullet point should restart the numbering, should be a,a,a,a instead of a,b,c,d
Attached is my code hope you can assist:
Sub ListLevelNumber()
'https://stackoverflow.com/questions/46119719/determine-bullet-list-style-using-word-vba
'template 1
With ListGalleries(wdNumberGallery).ListTemplates(1).ListLevels(1)
.NumberFormat = "%1."
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = CentimetersToPoints(0.63)
.Alignment = wdListLevelAlignLeft
.TextPosition = CentimetersToPoints(1.27)
.TabPosition = wdUndefined
.ResetOnHigher = 0
.StartAt = 1
With .Font
.Bold = wdUndefined
.Italic = wdUndefined
.StrikeThrough = wdUndefined
.Subscript = wdUndefined
.Superscript = wdUndefined
.Shadow = wdUndefined
.Outline = wdUndefined
.Emboss = wdUndefined
.Engrave = wdUndefined
.AllCaps = wdUndefined
.Hidden = wdUndefined
.Underline = wdUndefined
.Color = wdUndefined
.Size = wdUndefined
.Animation = wdUndefined
.DoubleStrikeThrough = wdUndefined
.Name = ""
End With
.LinkedStyle = ""
End With
'template 2
With ListGalleries(wdNumberGallery).ListTemplates(2).ListLevels(1)
.NumberFormat = "%1)"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleLowercaseLetter
.NumberPosition = CentimetersToPoints(0.63)
.Alignment = wdListLevelAlignLeft
.TextPosition = CentimetersToPoints(1.27)
.TabPosition = wdUndefined
.ResetOnHigher = 0
.StartAt = 1
With .Font
.Bold = wdUndefined
.Italic = wdUndefined
.StrikeThrough = wdUndefined
.Subscript = wdUndefined
.Superscript = wdUndefined
.Shadow = wdUndefined
.Outline = wdUndefined
.Emboss = wdUndefined
.Engrave = wdUndefined
.AllCaps = wdUndefined
.Hidden = wdUndefined
.Underline = wdUndefined
.Color = wdUndefined
.Size = wdUndefined
.Animation = wdUndefined
.DoubleStrikeThrough = wdUndefined
.Name = ""
End With
.LinkedStyle = ""
End With
With ListGalleries(wdBulletGallery).ListTemplates(3).ListLevels(1)
.NumberFormat = ChrW(61607)
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleBullet
.NumberPosition = CentimetersToPoints(0.63)
.Alignment = wdListLevelAlignLeft
.TextPosition = CentimetersToPoints(1.27)
.TabPosition = wdUndefined
.ResetOnHigher = 0
.StartAt = 1
With .Font
.Bold = wdUndefined
.Italic = wdUndefined
.StrikeThrough = wdUndefined
.Subscript = wdUndefined
.Superscript = wdUndefined
.Shadow = wdUndefined
.Outline = wdUndefined
.Emboss = wdUndefined
.Engrave = wdUndefined
.AllCaps = wdUndefined
.Hidden = wdUndefined
.Underline = wdUndefined
.Color = wdUndefined
.Size = wdUndefined
.Animation = wdUndefined
.DoubleStrikeThrough = wdUndefined
.Name = "Wingdings"
End With
.LinkedStyle = ""
End With
Dim oPara As Word.Paragraph
Dim count As Integer
count = 0
'Select Entire document
'Selection.WholeStory
With Selection
For Each oPara In .Paragraphs
If oPara.Range.ListFormat.ListLevelNumber = 1 Then
oPara.Range.ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
ListGalleries(wdNumberGallery).ListTemplates(1), ContinuePreviousList:= _
True, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _
wdWord10ListBehavior
End If
If oPara.Range.ListFormat.ListLevelNumber = 2 Then
oPara.Range.ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
ListGalleries(wdNumberGallery).ListTemplates(2), ContinuePreviousList:= _
False, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _
wdWord10ListBehavior
End If
If oPara.Range.ListFormat.ListLevelNumber = 3 Then
oPara.Range.ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
ListGalleries(wdNumberGallery).ListTemplates(3), ContinuePreviousList:= _
True, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _
wdWord10ListBehavior
End If
'count = count + 1
'End If
Next
End With
End Sub

VBA word sub bullet points

I'm trying to figure out how to use alpha bullet points after the numeric bullet points. Specifically, I have bullets 1 through 4 with text, and then I wish to write more text on A,B,C bullets indented underneath number 4, and then continue typing on number 5,6 etc. This is done in vba to generate word documents. The information on these lines is static and does not change. I'm also curious as what listtemplate type gets me arrow formatted bullets.
ListGalleries(wdOutlineNumberGallery).ListTemplates(2).Name = ""
.Selection.range.ListFormat.ApplyListTemplate ListTemplate:=.ListGalleries(wdOutlineNumberGallery).ListTemplates(2), _
defaultlistbehavior:=wdWord3ListBehavior
.
do you actually have to do it programmatically? you can define a new multilevel list in the paragraph tab.
here is an excerpt from a recorded macro where i changed the level1 bullet to number and level2 bullet to alpha
the recorded macro had 9 levels of bullets
it is possible that this is your answer:
ListGalleries(wdOutlineNumberGallery).ListTemplates(1).ListLevels(2).NumberFormat = "%2"
recorded code is below
With ListGalleries(wdOutlineNumberGallery).ListTemplates(1).ListLevels(1)
.NumberFormat = "%1"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleArabic
.NumberPosition = InchesToPoints(0)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.25)
.TabPosition = wdUndefined
.ResetOnHigher = 0
.StartAt = 1
With .Font
.Bold = wdUndefined
.Italic = wdUndefined
.StrikeThrough = wdUndefined
.Subscript = wdUndefined
.Superscript = wdUndefined
.Shadow = wdUndefined
.Outline = wdUndefined
.Emboss = wdUndefined
.Engrave = wdUndefined
.AllCaps = wdUndefined
.Hidden = wdUndefined
.Underline = wdUndefined
.Color = wdUndefined
.Size = wdUndefined
.Animation = wdUndefined
.DoubleStrikeThrough = wdUndefined
.Name = ""
End With
.LinkedStyle = ""
End With
With ListGalleries(wdOutlineNumberGallery).ListTemplates(1).ListLevels(2)
.NumberFormat = "%2"
.TrailingCharacter = wdTrailingTab
.NumberStyle = wdListNumberStyleUppercaseLetter
.NumberPosition = InchesToPoints(0.25)
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.5)
.TabPosition = wdUndefined
.ResetOnHigher = 1
.StartAt = 1
With .Font
.Bold = wdUndefined
.Italic = wdUndefined
.StrikeThrough = wdUndefined
.Subscript = wdUndefined
.Superscript = wdUndefined
.Shadow = wdUndefined
.Outline = wdUndefined
.Emboss = wdUndefined
.Engrave = wdUndefined
.AllCaps = wdUndefined
.Hidden = wdUndefined
.Underline = wdUndefined
.Color = wdUndefined
.Size = wdUndefined
.Animation = wdUndefined
.DoubleStrikeThrough = wdUndefined
.Name = ""
End With
.LinkedStyle = ""
End With

MS Word How to select hidden text

So I have a set of code that would select a specific range of text to be hidden and I need to have a macro that would select those hidden text and unhide them. However, I don't know how to select those hidden text without first displaying them. Is there a way to select hidden text while they're not displayed. I'm trying to create a dynamic template where if certain conditions are selected only certain text will appear. So far this is my code to unhide hidden text.
Sub Macro2()
'
' Macro2 Macro
'
'
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.MoveUp Unit:=wdParagraph, Count:=4, Extend:=wdExtend
With Selection.Font
.NameFarEast = "+Body Asian"
.NameAscii = "+Body"
.NameOther = "+Body"
.Name = "+Body"
.Size = 11
.Bold = False
.Italic = False
.Underline = wdUnderlineNone
.UnderlineColor = wdColorAutomatic
.StrikeThrough = False
.DoubleStrikeThrough = False
.Outline = False
.Emboss = False
.Shadow = False
.Hidden = False
.SmallCaps = False
.AllCaps = False
.Color = wdColorAutomatic
.Engrave = False
.Superscript = False
.Subscript = False
.Spacing = 0
.Scaling = 100
.Position = 0
.Kerning = 0
.Animation = wdAnimationNone
.DisableCharacterSpaceGrid = False
.EmphasisMark = wdEmphasisMarkNone
.Ligatures = wdLigaturesNone
.NumberSpacing = wdNumberSpacingDefault
.NumberForm = wdNumberFormDefault
.StylisticSet = wdStylisticSetDefault
.ContextualAlternates = 0
End With
End Sub
The hidden text has to be visible on the screen to be selected. So you need this in your code. You don't need to un-hide them;
ActiveDocument.ActiveWindow.View.ShowHiddenText = True
If you want the user to not see the texts while running this may do the job. However, it is not tested;
Application.ScreenUpdating = False
Remember to turn it back on at the end of your code;
Application.ScreenUpdating = True

Place a button and assign a macro to it

I have the following code to create a button.
ActiveSheet.Buttons.Add(264, 230.25, 127.5, 11.25).Select
Selection.OnAction = "choose_worksheet_1"
Range("C16").Select
ActiveSheet.Buttons.Add(264, 230.25, 127.5, 11.25).Select
Selection.Characters.Text = "Next step (2)"
With Selection.Characters(Start:=1, Length:=13).Font
.Name = "Tahoma"
.FontStyle = "Standaard"
.Size = 8
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
'.ThemeColor = 2
'.TintAndShade = 0
'.ThemeFont = xlThemeFontNone
End With
This all works but the thing is that I would like to add a macro to it straight away. Could anybody tell me how I can a macro to the button, for example "Macro2"

How to merge two cells in excel(both with contents) keeping the formatting intact using VBA?

I have two cells A1 and A2. I want to merge them and store in A3 keeping the formatting intact. I was able to use the below code to do this. But there is a huge performance issue. Can any one suggest a better solution? Is there a simpler way to do this?
Sub Merge_Cells(rngFrom1 As Range, rngFrom2 As Range, rngTo As Range)
Dim iOS As Integer
Dim lenFrom1 As Integer
Dim lenFrom2 As Integer
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlManual
lenFrom1 = rngFrom1.Characters.Count
lenFrom2 = rngFrom2.Characters.Count
rngTo.Value = rngFrom1.Text & rngFrom2.Text
For iOS = 1 To lenFrom1
With rngTo.Characters(iOS, 1).Font
.Bold = rngFrom1.Characters(iOS, 1).Font.Bold
.Size = 9 'rngFrom1.Characters(iOS, 1).Font.Size
.Color = rngFrom1.Characters(iOS, 1).Font.Color
.Italic = rngFrom1.Characters(iOS, 1).Font.Italic
.Strikethrough = rngFrom1.Characters(iOS, 1).Font.Strikethrough
.Underline = rngFrom1.Characters(iOS, 1).Font.Underline
End With
Next iOS
For iOS = 1 To lenFrom2
With rngTo.Characters(lenFrom1 + iOS, 1).Font
.Name = rngFrom2.Characters(iOS, 1).Font.Name
.Bold = rngFrom2.Characters(iOS, 1).Font.Bold
.Size = 9 'rngFrom2.Characters(iOS, 1).Font.Size
.Color = rngFrom2.Characters(iOS, 1).Font.Color
.Italic = rngFrom2.Characters(iOS, 1).Font.Italic
.Strikethrough = rngFrom2.Characters(iOS, 1).Font.Strikethrough
.Underline = rngFrom2.Characters(iOS, 1).Font.Underline
End With
Next iOS
Application.Calculation = xlAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Three suggestions:
1. Set a character's properties only if you need to
It's possible (I don't know for sure) that setting a character's properties is more expensive than getting a character's properties. If the cost differential is high enough then it makes sense to check the property to see if it needs to be set, before you actually set it.
So, for example, your code would become:
Sub Merge_Cells2(rngFrom1 As Range, rngFrom2 As Range, rngTo As Range)
Dim iOS As Integer
Dim lenFrom1 As Integer
Dim lenFrom2 As Integer
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlManual
lenFrom1 = rngFrom1.Characters.Count
lenFrom2 = rngFrom2.Characters.Count
rngTo.Value = rngFrom1.Text & rngFrom2.Text
For iOS = 1 To lenFrom1
With rngTo.Characters(iOS, 1).Font
If .Bold <> rngFrom1.Characters(iOS, 1).Font.Bold Then .Bold = rngFrom1.Characters(iOS, 1).Font.Bold
If .Size <> 9 Then .Size = 9
If .Color <> rngFrom1.Characters(iOS, 1).Font.Color Then .Color = rngFrom1.Characters(iOS, 1).Font.Color
If .Italic <> rngFrom1.Characters(iOS, 1).Font.Italic Then .Italic = rngFrom1.Characters(iOS, 1).Font.Italic
If .StrikeThrough <> rngFrom1.Characters(iOS, 1).Font.StrikeThrough Then .StrikeThrough = rngFrom1.Characters(iOS, 1).Font.StrikeThrough
If .Underline <> rngFrom1.Characters(iOS, 1).Font.Underline Then .Underline = rngFrom1.Characters(iOS, 1).Font.Underline
End With
Next iOS
For iOS = 1 To lenFrom2
With rngTo.Characters(lenFrom1 + iOS, 1).Font
If .Bold <> rngFrom2.Characters(iOS, 1).Font.Bold Then .Bold = rngFrom2.Characters(iOS, 1).Font.Bold
If .Size <> 9 Then .Size = 9
If .Color <> rngFrom2.Characters(iOS, 1).Font.Color Then .Color = rngFrom2.Characters(iOS, 1).Font.Color
If .Italic <> rngFrom2.Characters(iOS, 1).Font.Italic Then .Italic = rngFrom2.Characters(iOS, 1).Font.Italic
If .StrikeThrough <> rngFrom2.Characters(iOS, 1).Font.StrikeThrough Then .StrikeThrough = rngFrom2.Characters(iOS, 1).Font.StrikeThrough
If .Underline <> rngFrom2.Characters(iOS, 1).Font.Underline Then .Underline = rngFrom2.Characters(iOS, 1).Font.Underline
End With
Next iOS
Application.Calculation = xlAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
As I mentioned, I don't really know if this is a win, and the degree of advantage might vary from property to property. Maybe someone more knowledgable than I can comment. Or you can just try it out and see if it helps.
2. Set size all at once
Since you seem to be setting size to 9 all the time, I'd suggest setting size to 9 for the entire cell all at once, a rather than character by character. Then again, maybe you commented it out because you intend to restore size copying, and if so, this suggestion won't work.
3. Exploit sparseness
If the formatting is sparse, then you can check long runs of characters (or entire cells) for a particular property before you do anything. For example, if many cells have no bolding, check each cell before doing anything else. You might not have to do anything at all about bolding. My Excel returns Null when a property isn't uniform across a run of characters. (ymmv) If you get a Null, then you know you'll have to slice that character run more finely.
4. Addendum
#DavidZemens' suggestion about font size led me to this idea, which pays off only if Set is more expensive than Get for character properties. One could by inspection formulate a guess of the most common character style (font, size, color, bold, etc.), define that by hand as a cell style and apply it to the target range by hand. That would minimize the number of If's that trigger property sets.
-hth