【问题标题】:Improve 33 checkbox code subs to few? (Checkbox for auto-date in bookmarks)将 33 个复选框代码替换为几个? (书签中自动日期的复选框)
【发布时间】:2019-06-15 03:56:34
【问题描述】:

:) 我是 VBA 新手! 我有一个工作代码,用于在使用复选框(ActiveX)时在我有书签的地方插入日期。问题是我有 33 个复选框(我实际上希望 33x2。一个代表是,一个代表否)。所以我最终得到了 33 个订阅和 33 个书签。我敢打赌,这段代码可以更有效地将其减少到几个潜艇。任何人都知道是否可以做到吗? 下面的代码是 33 个重复 subs 中的第一个,其中 Sub 和书签名称是 agi1, agi2 agi3.....

Private Sub agi1_Click()

Dim rngFormat As Range
 Set rngFormat = ActiveDocument.Range( _
 Start:=ActiveDocument.Bookmarks("agi1").Range.Start, _
 End:=ActiveDocument.Bookmarks("agi1").Range.End)
 With rngFormat
 .Font.Size = 8
 End With

   Dim v
   Dim BMRange As Range
   v = ThisDocument.agi1.Value

'Sjekke om boks er sjekket eller ikke
   If v = True Then

'Sett inn dato i bokmerke
Set BMRange = ActiveDocument.Bookmarks("agi1").Range
With Selection.Font
 .Size = 9
End With
BMRange.Text = (Format(Date, "dd.mm.yyyy"))

Else

'Erstatte dato med tom tekst hvis boks ikke er sjekket
Set BMRange = ActiveDocument.Bookmarks("agi1").Range
BMRange.Text = " "

End If
'Sett inn bokmerke på nytt
ActiveDocument.Bookmarks.Add "agi1", BMRange

End Sub

【问题讨论】:

  • 除了书签等之外,代码是否相同?有事件下沉,如果您的按钮名称与书签一致,我相信 application.caller 会有所帮助。
  • 是的。唯一的区别是复选框和书签的名称(我使用相同的名称)。每个复选框一个书签。谢谢,我会“检查一下”。 :)

标签: vba ms-word activex


【解决方案1】:

你可以使用事件接收,也许是。

在普通模块中,创建一个集合并填充它以保存将控制复选框事件的类。

这里有代码,这将需要在打开文档时运行,在它生命的早期填充集合。

Public col As Collection

Public Sub SETUP()

Dim o As InlineShape
Dim c As MSForms.CheckBox
Dim cust As clsCustomCheckBox

Set col = New Collection

For Each o In ActiveDocument.InlineShapes

    Set c = o.OLEFormat.Object
    Set cust = New clsCustomCheckBox
    cust.INIT c
    col.Add cust

Next o

End Sub

然后有一个名为 clsCustomCheckBox 的类模块并将其代码作为

Private WithEvents c As MSForms.CheckBox

Public Function INIT(cmdIN As MSForms.CheckBox)
    Set c = cmdIN
End Function

Private Sub c_Click()
    MsgBox "Here you can get the name " & c.Name
End Sub

这会将每个复选框的点击转移到 c_click 类而不是它自己的类。

所以对你来说

Dim rngFormat As Range
 Set rngFormat = ActiveDocument.Range( _
 Start:=ActiveDocument.Bookmarks(c.name).Range.Start, _
 End:=ActiveDocument.Bookmarks(c.name).Range.End)
 With rngFormat
 .Font.Size = 8
 End With
.......

【讨论】:

  • 这将是首选的方法。虽然不想进入 WithEvents 和类模块,但 OP 绝对应该研究一下。
  • 酷。我一定会的。比你 Nathan_Sav
【解决方案2】:

ActiveX 控件总是像这样注册它们的事件处理程序:

Private Sub NameOfTheControl_NameOfTheEvent({args})

如果您重命名处理程序,控件将停止工作 - 因为处理程序的 name 必须 如上所述形成,用下划线分隔控件的名称和处理的事件的名称。

因此,如果您的控件必须在编译时存在,则无法绕过它:对于 33 个控件,您需要 33 个处理程序。

这并不意味着您需要将这个庞大的过程重复 33 次!

提取过程。选择该处理程序的整个主体,剪切它。

现在制作一个新的程序原型:

Private Sub HandleCheckBoxClick(ByVal controlName As String)

End Sub

然后将身体粘贴在那里。然后用引用这个controlName参数替换所有你有硬编码"agi1"的地方:

Dim rngFormat As Range
Set rngFormat = ActiveDocument.Range( _
    Start:=ActiveDocument.Bookmarks(controlName).Range.Start, _
    End:=ActiveDocument.Bookmarks(controlName).Range.End)
With rngFormat
    .Font.Size = 8
End With

'...

您使用其程序名称引用控件的地方会有点困难:

v = ThisDocument.agi1.Value

你可以通过ThisDocument.InlineShapes集合获取MSForms.CheckBox控件,但是that won't let you find a checkbox by its name,所以你需要一个可以为你做的函数:

Private Function FindCheckBoxByName(ByVal controlName As String) As MSForms.CheckBox
    Dim sh As InlineShape
    For Each sh In ThisDocument.InlineShapes
        If TypeOf sh.OLEFormat.Object Is MSForms.CheckBox Then
            If sh.OLEFormat.Object.Name = controlName Then
                'return the MSForms control:
                Set FindControlByName = sh.OLEFormat.Object
            End If
        End If
    Next

现在你可以这样做了:

Dim cb As MSForms.ChecBox
Set cb = FindCheckBoxByName(controlName)
If cb Is Nothing Then
    MsgBox "No ActiveX CheckBox control named '" & controlName & "' was found in ThisDocument."
    Exit Sub
End If
v = cb.Value

一旦对 ActiveX 控件的所有引用都进行了参数化,您的 33 个处理程序现在可以如下所示:

Private Sub agi1_Click()
    HandleCheckBoxClick "agi1"
End Sub

Private Sub agi2_Click()
    HandleCheckBoxClick "agi2"
End Sub

'...

Private Sub agi33_Click()
    HandleCheckBoxClick "agi33"
End Sub

或者,您可以在运行时创建复选框,然后在专用的类模块中处理它们的 Click 事件,但这有点复杂 ;-)

【讨论】:

  • 谢谢。我试图让它工作。 (我是新手)但我似乎不太明白。该功能,我把它放在 HandleCheckBoxClick 子之后?以及函数之后的部分。它是在函数内部还是在 HandleCheckBoxClick 子内部?我将发布到目前为止我所理解的代码。
  • @HerlandBjørnsbror 该函数是独立的,您不能在 VBA 中拥有嵌套的过程范围。 HandleCheckBoxClick 过程需要包含您当前在 33 个处理程序中的所有代码,但已参数化。
  • 我有一个错误:对于每个 sh ThisDocument.InlineShapes 它要求输入。所以我添加了它: For Each sh In ThisDocument.InlineShapes
猜你喜欢
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
相关资源
最近更新 更多