英文:
How can VBA for Word be used to set an autonumber list to the right of text?
问题
I'm working on a userform that completes a correspondence template. I have two fields: References and Enclosures that need to show up on the completed template like this (underscores are spaces):
Ref:____(a) Reference 1
_______ (b) Reference 2
Encl:___(1) Enclosure 1
________(2) Enclosure 2
I can't figure out how to start an aligned autonumbered list to the right of those labels (Ref: & Encl:). I don't have code that works to provide here because I got frustrated and scrapped everything, but all solutions I've tried have resulted in something that looks like this:
(a) Ref: Reference 1
(b) Reference 2
Anything that can get me started in the right direction will be appreciated. Thanks
英文:
I'm working on a userform that completes a correspondence template. I have two fields: References and Enclosures that need to show up on the completed template like this (underscores are spaces):
Ref:____(a) Reference 1 <br/>
_______ (b) Reference 2
Encl:___(1) Enclosure 1 <br/>
________(2) Enclosure 2
I can't figure out how to start an aligned autonumbered list to the right of those labels (Ref: & Encl:). I don't have code that works to provide here because I got frustrated and scrapped everything, but all solutions I've tried have resulted in something that looks like this:
(a) Ref: Reference 1 <br/>
(b) Reference 2
Anything that can get me started in the right direction will be appreciated. Thanks
答案1
得分: 1
抱歉,你的内容包含了许多代码和特殊字符,翻译成中文可能会导致失去原文的意义。如果你有任何关于这段文本的具体问题或需要进一步的解释,请随时告诉我,我将尽力帮助你。
英文:
FWIW I think the suggestion by @TimothyRylatt is by far and away the most reliable way to approach this problem, but (a) there are alternatives, and (b) how useful any approach is depends on what you want to do with the resulting document. If you only need to be able to print or PDF the correspondence (i.e. no-one needs to edit the document you create), frankly, you can avoid autonumbering altogether and use VBA to generate the correct letter for each row in your output.
If you need a user to be able to resequence your Refs and Encls, for example, they are almost always going to have to deal with the problem that the first item in a list is going to be different from subsequent items.
But perhaps have a go with this, which uses a combination (unusual, I suspect) of a multilevel list format and { LISTNUM }
fields. You would need to choose values for the constant names, and modify the paragraph, tab and other formatting as appropriate for your output. Modify Sub addtexts()
to genertae the lists you need, and call it.
Option Explicit
Const myListParaStyleName As String = "mylistparastyle"
Const myListName As String = "mylistname"
Const templateNum As Integer = 2
Sub SetUpListAndParaStyle()
Dim lt1 As Word.ListTemplate
Dim lt2 As Word.ListTemplate
Dim st1 As Word.Style
Dim st2 As Word.Style
' Modify/create the specified paragraph format
For Each st1 In ActiveDocument.Styles
If st1.NameLocal = myListParaStyleName Then
Set st2 = st1
Exit For
End If
Next
If st2 Is Nothing Then
Set st2 = ActiveDocument.Styles.Add(myListParaStyleName, WdStyleType.wdStyleTypeParagraphOnly)
End If
With st2
.BaseStyle = ""
With .ParagraphFormat
.LeftIndent = CentimetersToPoints(2.1)
.FirstLineIndent = -CentimetersToPoints(2.1)
With .TabStops
.ClearAll
.Add CentimetersToPoints(1.3), WdTabAlignment.wdAlignTabLeft
.Add CentimetersToPoints(2.1), WdTabAlignment.wdAlignTabLeft
End With
End With
End With
Set st2 = Nothing
' Modify/Create a suitable list template
For Each lt1 In ActiveDocument.ListTemplates
If lt1.Name = myListName Then
Set lt2 = lt1
Exit For
End If
Next
If lt2 Is Nothing Then
Set lt2 = ActiveDocument.ListTemplates.Add(True, myListName)
End If
With lt2
With .ListLevels(1)
' set up a "reset numbering" level
.NumberFormat = "%1"
.NumberStyle = wdListNumberStyleNone
.ResetOnHigher = 0
.StartAt = 1
.LinkedStyle = ""
.TrailingCharacter = wdTrailingNone
End With
With .ListLevels(2)
' set up an "(a)" level
.NumberFormat = "(%2)"
.NumberStyle = wdListNumberStyleLowercaseLetter
.ResetOnHigher = 1
.StartAt = 1
.LinkedStyle = ""
.TrailingCharacter = wdTrailingNone
End With
With .ListLevels(3)
' set up another "(a)" level
.NumberFormat = "(%2)"
.NumberStyle = wdListNumberStyleLowercaseLetter
.ResetOnHigher = 1
.StartAt = 1
.LinkedStyle = ""
.TrailingCharacter = wdTrailingNone
End With
' do more levels if you want.
End With
Set lt2 = Nothing
End Sub
Sub addToList(newlist As Boolean, tagtext As String, listtext As String)
' adds the list at the end of the document
Dim r As Word.Range
Dim r2 As Word.Range
' add para at end
ActiveDocument.Paragraphs.Add
Set r = ActiveDocument.Content
r.Collapse WdCollapseDirection.wdCollapseEnd
Set r = r.Paragraphs(1).Range
' make sure we're in a list with the correct template. At the moment, does not seem to matter
' much whether it's "WithLevels@ or not.
r.ListFormat.ApplyListTemplateWithLevel ActiveDocument.ListTemplates(myListName), False, wdListApplyToWholeList, wdWord10ListBehavior, 1
' but then impose our paragraph style, or the tabs witll be wrong
r.Style = myListParaStyleName
r.Text = " " & vbTab & " " & vbTab & " "
Set r2 = r.Duplicate
r2.SetRange r.Start + 5, r.Start + 6
r2.Text = listtext
r2.SetRange r.Start + 3, r.Start + 4
r2.Fields.Add r2, WdFieldType.wdFieldListNum, myListName & " \l 2", False
If newlist Then
r2.SetRange r.Start + 1, r.Start + 2
r2.Text = tagtext
r2.SetRange r.Start, r.Start + 1
r2.Fields.Add r2, WdFieldType.wdFieldListNum, myListName & " \l 1", False
End If
Set r2 = Nothing
Set r = Nothing
End Sub
Sub addtexts()
Call addToList(True, "Ref:", "abc")
Call addToList(False, "", "def")
Call addToList(False, "", "ghi")
Call addToList(True, "Encl:", "jkl")
Call addToList(False, "", "mno")
Call addToList(False, "", "pqr")
End Sub
Notes...
Autonumbering lets you put text before your (a), but then you would have to define a multilevel scheme where one level had "Ref:", another did not, an apply the correct levels or paragraph styles. But the problem with that is that it's very hard to get the alignment right. If users need to modify the results, { LISTNUM } has an advantage over { SEQ } fields in that LISTNUM values are updated automatically, but a disadvantage in that they are tied to Word's labyrinthine list structures.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论