2017-03-05 91 views
0

當用戶在PPT幻燈片上運行GUI時,它會顯示一個用戶窗體,如下圖所示。 The userform that pops up when run使用VBA循環瀏覽Powerpoint中的用戶窗體中的複選框

他們最多可以在複選框中選擇3個危險。我試圖找到一種方法來遍歷所有的複選框,看看哪些被選中(如果沒有,那麼它將只是退出子)。然後,基於哪個(哪些)被選擇,它將在PPT幻燈片中將對應的圖像輸入到形狀中。形狀從左到右排列。 「最高排名」選擇將以左側形式出現,三名選手的「最低排名」將進入右側框。如果只選擇了兩個選項,則只會填充第一個和第二個形狀。我不確定爲每個選項分配值(即1,2,3等)的重要性順序的最簡單方法。我寧願不必用If - > Then語句覆蓋每個組合,因爲這將是乏味且相當耗時的。我認爲有更好的方法來做到這一點?

我能夠遍歷組合框列表輕鬆地使用下面的代碼:

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 

我想弄清楚,這樣在其標籤的最低數量的複選框進入「Hazard1」,與第二標籤我將如何編寫代碼最低數量(最多可選3個)進入Hazard2,而排在第三位的Tag進入Hazard3。有任何想法嗎?謝謝!

回答

1

您可以通過用戶窗體Controls收集迭代,並檢查那些「複選框」 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 
+0

完美的工作。謝謝!我還有最後一個問題。我修改了我原來的問題。你可以看到修改過的代碼和我的問題。再次感謝! – hunter21188

+1

不客氣。請注意,在收到_original_ one解決方案後更改問題會導致所謂的「chamaleon」問題,這是不允許的。所以,如果我的答案解決了你的_original_問題,那麼將其標記爲已接受。雖然您可能想爲_new_問題創建一個_new_帖子。謝謝 – user3598756