Vba 将33个复选框代码子项改进为少数?(书签中自动日期的复选框)

Vba 将33个复选框代码子项改进为少数?(书签中自动日期的复选框),vba,ms-word,activex,Vba,Ms Word,Activex,:) 我是VBA新手! 我有一个工作代码,用于在使用复选框(ActiveX)时插入带有书签的日期。问题是我有33个复选框(实际上我希望是33x2,一个表示是,一个表示否)。所以我最终得到了33个sub和33个书签。我打赌这个代码可以更有效地将它制动到几个潜艇。Annyone有一个奇怪的想法,如果它可以做到? 下面的代码是33个重复Sub中的第一个,其中Sub和bookmark名称为agi1、agi2和agi3 Private Sub agi1_Click() Dim rngFormat As

:) 我是VBA新手! 我有一个工作代码,用于在使用复选框(ActiveX)时插入带有书签的日期。问题是我有33个复选框(实际上我希望是33x2,一个表示是,一个表示否)。所以我最终得到了33个sub和33个书签。我打赌这个代码可以更有效地将它制动到几个潜艇。Annyone有一个奇怪的想法,如果它可以做到? 下面的代码是33个重复Sub中的第一个,其中Sub和bookmark名称为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

ActiveX控件始终按如下方式注册其事件处理程序:

Private Sub NameOfTheControl_NameOfTheEvent({args})
如果重命名处理程序,控件将停止工作,因为处理程序的名称必须如上所述,并用下划线分隔控件名称和已处理事件的名称

所以,如果您的控件必须在编译时存在,就没有办法了:对于33个控件,您需要33个处理程序

这并不意味着你需要重复33次这个巨大的过程

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

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

Private Sub HandleCheckBoxClick(ByVal controlName As String)

End Sub
然后把尸体贴在里面。然后将硬编码的“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
控件,但是,您需要一个可以为您执行此操作的函数:

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

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

你可以使用事件下沉,也许可以

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

在这段代码中,这需要在打开文档时运行,这是文档生命早期填充集合的事情

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\u单击
,而不是它自己的

那你呢

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
.......

除了书签等,代码是否相同?有事件下沉,我相信
应用程序。如果您的按钮名称与书签一致,调用者
可能会有所帮助。是的。唯一的区别是复选框和书签的名称(我对两者使用了相同的名称)。每个邮箱一个书签。谢谢,我会“检查一下”。)非常感谢。我正在努力让它工作。(我是新手)但我似乎不太明白。函数,我把它放在HandleCheckBoxClick子后面?函数后面的部分。它是在函数内部还是在HandleCheckBoxClick子函数内部?我将发布我所掌握的与我所理解的相去甚远的代码。@HerlandBjørnsbr或函数本身,VBA中不能有嵌套的过程作用域。
HandleCheckBoxClick
过程需要包含33个处理程序中当前包含的所有代码,但已参数化。我的错误是:对于它在中要求的每个sh ThisDocument.InlineShapes。所以我添加了它:对于这个document.inlineshapest中的每个sh,这将是最好的方法。虽然我不想进入带有事件和类模块的
,但OP绝对应该关注这一点。酷。我会的。比你Nathan_Sav