使用VBA在Powerpoint中的Userform中循环检查复选框

时间:2017-03-05 19:39:12

标签: vba powerpoint

当用户在PPT幻灯片上运行GUI时,它会显示一个用户表单,如下图所示。 The userform that pops up when run

他们可以在复选框中选择最多3个危险。我试图找到一种循环所有复选框的方法,看看哪些被选中(如果没有,那么它将只退出子)。然后,基于选择哪个(一个或多个),它将相应的图像输入PPT幻灯片内的形状。形状从左到右排列。排名最高的"选择将采用左侧形状,排名最低"三个进入右侧框。如果仅选择了两个选项,则仅填充第一和第二形状。我不确定将值(即1,2,3等)分配给每个选项的重要性顺序的最简单方法。我宁愿不用If - >覆盖每一个组合。然后这些陈述将是乏味且非常耗时的。我认为有更好的方法可以做到这一点吗?

我可以使用以下代码轻松遍历组合框列表:

Private Sub MainImage()
Call Dictionary.MainImageDict

'References the Dictionary for the Main Image options.

ComboBoxList = Array(CStr(ComboBox2)) 'ComboBox2 is the Main Image dropdown.

    For Each Ky In ComboBoxList
    On Error Resume Next
    'If nothing is selected in the Main Image dropdown, do nothing and exit this sub.
    If Ky = "" Then
    Exit Sub
    'Otherwise, if anything is selected in the Main Image dropdown, insert image and remove placeholder text.
    ElseIf Ky <> "" Then
    ActiveWindow.Selection.SlideRange.Shapes("MainImage").Fill.UserPicture (dict3.Item(Ky)(0))

    End If

    Next

Set dict3 = Nothing

End Sub

上面引用的字典如下:

Public dict, dict2, dict3, dict4, dict5 As Object, Key, val 'Makes the dictionaries public so they can be accessed by other Modules.

Sub MainImageDict()

'This is the dictionary for the Main Image portion of the slides.

Set dict3 = CreateObject("Scripting.Dictionary")

Key = "Day 1 High Temperatures": val = Array("URL_to_Image")
dict3.Add Key, val
Key = "Day 2 High Temperatures": val = Array("URL_to_Image")
dict3.Add Key, val

End Sub

如果可能的话,我想用复选框做类似的事情。由于它们都是独立的,而不是组合成一个(如组合框),我不知道该如何去做。任何帮助将不胜感激!如果我说的话没有意义,请告诉我。谢谢!

更新后的代码

使用建议的代码非常有效。现在我有一个最后的问题。我已将代码修改为以下内容:

    Private Sub Hazards()
    Call Dictionary.HazardsDict

   'References the Dictionary for the Hazard Image options.

    Dim chkboxes As Variant
    Dim iCtrl As Long

    Select Case CountSelectedCheckBoxes(chkboxes)
        Case Is > 3
            MsgBox "Too many selected checkboxes!" & vbCrLf & vbCrLf & "please select three checkboxes only!", vbCritical
        Case Is = 1 'If only one checkbox is selected
            For iCtrl = LBound(chkboxes) To UBound(chkboxes)
              HazardList = Array(chkboxes(iCtrl).Caption)
              Debug.Print chkboxes(iCtrl).Caption
              Next
                'MsgBox chkboxes(iCtrl).Tag '<--| here you output each selected checkbox Tag. you can use this "number"
            For Each Ky In HazardList
                ActiveWindow.Selection.SlideRange.Shapes("Hazard1").Fill.UserPicture (dict5.Item(Ky)(0))
                ActiveWindow.Selection.SlideRange.Shapes("Hazard1Text").TextFrame.TextRange.Text = dict5.Item(Ky)(1)
            Next
        Case Is = 2 'If exactly 2 checkboxes are selected
            For iCtrl = LBound(chkboxes) To UBound(chkboxes)
              HazardList = Array(chkboxes(iCtrl).Caption)
              Debug.Print chkboxes(iCtrl).Caption
            Next
            For Each Ky In HazardList
                ActiveWindow.Selection.SlideRange.Shapes("Hazard1").Fill.UserPicture (dict5.Item(Ky)(0)) 'The checkbox with the lowest number in its Tag would go here.
                ActiveWindow.Selection.SlideRange.Shapes("Hazard1Text").TextFrame.TextRange.Text = dict5.Item(Ky)(1)
                ActiveWindow.Selection.SlideRange.Shapes("Hazard2").Fill.UserPicture (dict5.Item(Ky)(0)) 'The checkbox with the second lowest tag number would go here
                ActiveWindow.Selection.SlideRange.Shapes("Hazard2Text").TextFrame.TextRange.Text = dict5.Item(Ky)(1)
            Next
    End Select

    Set dict5 = Nothing

End Sub

我正在试图弄清楚如何编写代码,以便其标签中编号最小的复选框进入&#34; Hazard1&#34;,标记的编号为第二低(最多3个)可以选择)进入Hazard2,具有第三低数字的标签进入Hazard3。有任何想法吗?谢谢!

1 个答案:

答案 0 :(得分:1)

您可以遍历UserForm Controls集合并检查那些带有“CheckBox”的TypeName

虽然您可以在复选框控件的Tag属性中存储一些“重要性评级”(在VBA IDE中按F4弹出属性窗口,选择用户窗体中的每个复选框并在其中键入正确的“重要性评级”) Tag条目)

以上所有可以利用的内容如下:

Private Sub InsertBtn_Click()
    Dim chkboxes As Variant
    Dim iCtrl As Long

    Select Case CountSelectedCheckBoxes(chkboxes)
        Case Is > 3
            MsgBox "Too many selected checkboxes!" & vbCrLf & vbCrLf & "please select three checkboxes only!", vbCritical
        Case Is < 3
            MsgBox "Too few selected checkboxes!" & vbCrLf & vbCrLf & "please select three checkboxes!", vbCritical            
        Case Else
            For iCtrl = LBound(chkboxes) To UBound(chkboxes)
                MsgBox chkboxes(iCtrl).Tag '<--| here you output each selected checkbox Tag. you can use this "number"
            Next
    End Select
End Sub

Function CountSelectedCheckBoxes(chkboxes As Variant) As Long
    Dim ctrl As Control
    ReDim chkboxes(1 To Me.Controls.count)

    For Each ctrl In Me.Controls '<--| loop through userform controls
        If TypeName(ctrl) = "CheckBox" Then '<--| check if current control is a "checkbox" one
            If ctrl Then '<--| check if it's "checked"
                CountSelectedCheckBoxes = CountSelectedCheckBoxes + 1 '<--| update checked checkboxes counter
                Set chkboxes(CountSelectedCheckBoxes) = ctrl '<--| store it in the array
            End If
        End If
    Next
    If CountSelectedCheckBoxes > 0 Then ReDim Preserve chkboxes(1 To CountSelectedCheckBoxes) '<--|size checkboxes array to actual checked checkboxes found
End Function