添加内容控件和检索用户选择

时间:2017-07-20 19:36:39

标签: excel-vba word-vba vba excel

我有Word 2013文档,其中包含7到100多个文本部分。为简单起见,我将它们称为bios。 目标:为每个选项提供一个下拉框,其中包含3个选项,然后在选择它们之后计算选择。 我对VBA很新,只能通过谷歌来学习。到目前为止我所拥有的是:

Sub AddStateDropDown()
Dim Counter As Integer
Dim sum As Integer
Dim maxnumber As Integer
sum = 0
Counter = 1
maxnumber = 31

我的"游乐场"文件有31个BIOS。

For Counter = 1 To maxnumber Step 1

sum = Counter + sum
Selection.Range.ContentControls.Add (wdContentControlDropdownList)
Selection.ParentContentControl.Title = "Bio " & sum
Selection.ParentContentControl.Tag = "Approval" & sum
Selection.ParentContentControl.DropdownListEntries.Clear
Selection.ParentContentControl.DropdownListEntries.Add Text:="Approve", _
    Value:="Approve"
Selection.ParentContentControl.DropdownListEntries.Add Text:="Hold", Value _
    :="Hold"
Selection.ParentContentControl.DropdownListEntries.Add Text:="Delete", _
    Value:="Delete"
Next Counter
End Sub

不幸的是,这会导致错误&#34; 运行时错误&#39; 4605&#39;:此方法或属性不可用,因为当前选择部分涵盖纯文本内容控件。< / EM>&#34; 据我所知,这是关于内容控件的可用空间的问题,但是在启动宏时,无论光标上方,下方或旁边的可用空间如何,都会收到此错误。

我正在尝试以这种方式为最终计数编号标签或标题 - 据我了解,我需要使用SelectContentControlsByTag或SelectContentControlsByTitle来恢复所选的值。

可以帮助我克服障碍

1)添加多个差异化内容控件,最好是在特定单词或短语的每个实例之后(将内容传播到bios中)

2)从这些内容控件中检索信息

提前致谢! StackOverflow对我刚刚开始的VBA实验非常有帮助,但这次我不得不写自己的问题。

1 个答案:

答案 0 :(得分:0)

这一周几乎消失了。是时候取得一些进展了。请将以下代码复制到带有测试BIOS的文档副本中的标准模块中。

Option Explicit

Enum Ncb                        ' Context button
    ' 27 Jul 2017
    NcbCap
    NcbCmd
    NcbEvaluate = 0
    NcbApprove
    NcbReject
    NcbHold
    NcbReport
    NcbA = 80
    NcbH = 87
    NcbR = 97
    NcbRep = 720
End Enum

Private Sub DelContextControl()
    ' 06 Oct 2016

    ' ===================================================
    '      Use this sub to DELETE the context control
    ' ===================================================

    Dim Doc As Document
    Dim Ctl As CommandBarControl
    Dim Del As Boolean

    Set Doc = ActiveDocument
    CustomizationContext = Doc
    Do
        Set Ctl = CommandBars("Text").Controls(1)
        Del = (Ctl.Tag = BtnSpecs(NcbEvaluate, NcbCap))
        If Del Then Ctl.Delete
    Loop While Del
End Sub

Private Sub TestSet()

    ' ===================================================
    '      Use this sub to SET the context control
    ' ===================================================

    SetContextControl ActiveDocument
End Sub
Sub SetContextControl(Doc As Document)
    ' 27 Jul 2017

    Dim Cbar As CommandBar
    Dim Bctl As CommandBarControl
    Dim Fid As Variant
    Dim i As Long

    CustomizationContext = Doc
    Set Cbar = CommandBars("Text")

    Set Bctl = Cbar.Controls(1)
    If Not (Bctl.Tag = BtnSpecs(NcbEvaluate, NcbCap)) Then
        Set Bctl = Cbar.Controls.Add(msoControlPopup, , , 1)
        With Bctl
            .Caption = BtnSpecs(NcbEvaluate, NcbCap)
            .Tag = BtnSpecs(NcbEvaluate, NcbCap)
            .BeginGroup = True

            Fid = Array(NcbA, NcbR, NcbH, NcbRep)
            For i = NcbApprove To NcbReport
                With .Controls.Add(Type:=msoControlButton)
                    .Caption = BtnSpecs(i, NcbCap)
                    .FaceId = Fid(i - NcbApprove)
                    .OnAction = BtnSpecs(i, NcbCmd)
                End With
            Next i
        End With
    End If
End Sub

Private Function BtnSpecs(Bid As Ncb, _
                          Cid As Ncb) As String
    ' 27 Jul 2017

    Dim Specs As String

    Select Case Cid
        Case NcbCap
            Specs = "Evaluate Bios,Approve,Reject,Hold,Report"
        Case NcbCmd
            Specs = ",Approve,Reject,Hold,Report"
    End Select

    BtnSpecs = Split(Specs, ",")(Bid)
End Function

Sub Approve()
    ' 27 Jul 2017
    WriteComment NcbApprove
End Sub

Sub Hold()
    ' 27 Jul 2017
    WriteComment NcbHold
End Sub

Sub Reject()
    ' 27 Jul 2017
    WriteComment NcbReject
End Sub

Private Sub WriteComment(TxtId As Ncb)
    ' 27 Jul 2017
    ActiveDocument.Comments.Add Selection.Range, UCase(BtnSpecs(TxtId, NcbCap))
End Sub

Sub Report()
    ' 27 Jul 2017
    MsgBox "Create the report"
End Sub

现在运行程序TestSet(F5)。此过程只调用子SetContextControl。它是&#34;测试&#34;因为也许你会在未来找到更好的方法。我不喜欢使用ActiveDocument(如果在错误的文档上运行可能会造成很大的伤害),而且我不喜欢用户按F5跑来跑去。

此过程将向ActiveDocument的内容的上下文菜单添加一个控件,即其正文(不包括页眉和页脚)。如果出于任何原因想要删除控件,请运行子DelContextControl。请注意,该控件仅在安装它的文档中可用,而不是应用程序。如果您希望它保留在文档中,则必须保存它。

当您在其范围内时,右键单击上下文菜单,这意味着在文档正文中。当您在其他地方操作时右键单击时,您将拥有不同的上下文菜单。代码添加的控件是菜单中的第一个。它被称为&#34;评估Bios&#34;。请注意,有关此控件的所有内容都可以协商。一切都在代码中。所有这些都可以根据您的喜好或要求进行修改。

控件属于弹出窗口类型,这意味着它会在右侧打开一个下拉列表。在那里,您可以选择&#34;批准&#34;,&#34;拒绝&#34;,&#34;保持&#34;或&#34;报告&#34;。当您单击前三个选项中的任何一个时,将添加带有指示内容的注释。当您单击第四个按钮时,将提醒您下一个任务。

Word将评论附加到Range。代码使用Selection.Range来实现此目的。因此,您可以在插入评论之前选择生物标题或唯一ID。如果您不小心选择,可以将评论附加到错误的生物。这是一个可以改进的领域。

另一个领域涉及多个评论的问题。由于评论标识了评论者,您实际上可能希望有多个评论。如果没有,您可以确保每个生物只有一条评论。 StackOverflow处理了此问题:in VBA (word) how do I add a comment to a range only if no comments exist?

根据您的工作流程,您可能必须将文档实际拆分为多个部分,每个部分一个生物。我希望它不会被要求,但是如果是这样的话,那么在准备文档进行评论时可能会做一些事情,也许是在安装上下文控制的同时。

同样,上下文控件可能会被创建报表的相同代码删除。这涉及创建一个文档(可能来自模板,也许是从头开始),循环遍历测试文档中的所有注释,计算它们的性质并将结果写入新的报告文档。这并不困难,但这是另一天的工作。

顺便说一下,我记得你拒绝了使用评论的想法。如果易用性并不能说服您使用此系统,请查找Word提供的功能以隐藏和显示注释。但即使这并不能说服你,创建评论的同一个宏可以做一些完全不同的事情,这意味着可以保持上下文菜单提供的易用性。不乏可能性,但是要让评论者看到生物和评估之间的关联,就像Word评论所做的那样,需要比你上面看到的更多的编程。