VBA for Word如何用于将自动编号列表设置在文本右侧?

huangapple go评论93阅读模式
英文:

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 = &quot;mylistparastyle&quot;
Const myListName As String = &quot;mylistname&quot;
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

&#39; 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 = &quot;&quot;
  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

&#39; 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)
    &#39; set up a &quot;reset numbering&quot; level
    .NumberFormat = &quot;%1&quot;
    .NumberStyle = wdListNumberStyleNone
    .ResetOnHigher = 0
    .StartAt = 1
    .LinkedStyle = &quot;&quot;
    .TrailingCharacter = wdTrailingNone
  End With
  With .ListLevels(2)
    &#39; set up an &quot;(a)&quot; level
    .NumberFormat = &quot;(%2)&quot;
    .NumberStyle = wdListNumberStyleLowercaseLetter
    .ResetOnHigher = 1
    .StartAt = 1
    .LinkedStyle = &quot;&quot;
    .TrailingCharacter = wdTrailingNone
  End With
  With .ListLevels(3)
    &#39; set up another &quot;(a)&quot; level
    .NumberFormat = &quot;(%2)&quot;
    .NumberStyle = wdListNumberStyleLowercaseLetter
    .ResetOnHigher = 1
    .StartAt = 1
    .LinkedStyle = &quot;&quot;
    .TrailingCharacter = wdTrailingNone
  End With
  &#39; do more levels if you want.
End With
Set lt2 = Nothing
End Sub

Sub addToList(newlist As Boolean, tagtext As String, listtext As String)
&#39; adds the list at the end of the document
Dim r As Word.Range
Dim r2 As Word.Range
  &#39; add para at end
ActiveDocument.Paragraphs.Add
Set r = ActiveDocument.Content
r.Collapse WdCollapseDirection.wdCollapseEnd
Set r = r.Paragraphs(1).Range
&#39; make sure we&#39;re in a list with the correct template. At the moment, does not seem to matter
&#39; much whether it&#39;s &quot;WithLevels@ or not.
r.ListFormat.ApplyListTemplateWithLevel ActiveDocument.ListTemplates(myListName), False, wdListApplyToWholeList, wdWord10ListBehavior, 1
&#39; but then impose our paragraph style, or the tabs witll be wrong
r.Style = myListParaStyleName
r.Text = &quot;  &quot; &amp; vbTab &amp; &quot; &quot; &amp; vbTab &amp; &quot; &quot;
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 &amp; &quot; \l 2&quot;, 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 &amp; &quot; \l 1&quot;, False
End If
Set r2 = Nothing
Set r = Nothing
End Sub

Sub addtexts()
Call addToList(True, &quot;Ref:&quot;, &quot;abc&quot;)
Call addToList(False, &quot;&quot;, &quot;def&quot;)
Call addToList(False, &quot;&quot;, &quot;ghi&quot;)
Call addToList(True, &quot;Encl:&quot;, &quot;jkl&quot;)
Call addToList(False, &quot;&quot;, &quot;mno&quot;)
Call addToList(False, &quot;&quot;, &quot;pqr&quot;)
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.

huangapple
  • 本文由 发表于 2023年3月9日 20:09:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75684418.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定