@Astander dostarczył poprawną odpowiedź, ale należy pamiętać, że nie wszystkie kontrolki mają tego samego rodzaju kolekcje Kontroli.
Pola tekstowe, pola kombi, pola listy, pola kontrolne mają maksymalnie 1 pozycję w kolekcji kontrolnej (dołączona etykieta), ale jeśli etykieta nie jest dołączona, nie będą jej nawet miały, więc .Controls (0) rzuci błąd.
Grupa opcji ma wiele elementów sterujących, etykietę i przycisk opcji lub przyciski przełączania wewnątrz ramki. Po upuszczeniu grupy opcji na formularzu z paska narzędziowego formularza ramka jest tworzona z dołączoną etykietą, więc będzie to kontrolka z indeksem 0. Ale jeśli na przykład usuniesz domyślną etykietę, dodaj przyciski opcji i następnie dodaj etykietę, nie będzie ona indeksem 0, ale indeksem .Controls.Count - 1.
W przypadku napisu dotyczącego etykiety grupy opcji, należy zachować ostrożność, aby usunąć domyślną etykietę , usuwasz również kontrolki wewnątrz ramki po dodaniu etykiety z powrotem. Jeśli tak nie jest, musisz nazwać etykietę i odnosić się do niej po nazwie, ponieważ etykiety przycisków opcji/przełączników są częścią kolekcji Kontrolki grupy opcji (to mnie zaskoczyło - spodziewałem się, że będą one tylko w kontrolkach kolekcja przycisku opcji/przełącznika, do którego zostały dołączone).
Aby uniknąć tego problemu, mogę sobie wyobrazić skomplikowany kod, w którym przeszukiwałeś kolekcję kontrolek grupy opcji, szukając etykiet dołączonych do przycisków opcji/przełączania, a następnie przepuszczono ponownie kolekcję Kontrolki grupy opcji po raz drugi, tym razem patrząc tylko na etykiety.Coś takiego:
Public Function FindOptionGroupLabel(ctlOptionGroup As Control) As Control
Dim ctl As Control
Dim strOptionToggleLabels As String
If ctlOptionGroup.ControlType <> acOptionGroup Then
MsgBox ctlOptionGroup.Name & " is not an option group!", _
vbExclamation, "Not an option group"
Exit Function
End If
For Each ctl In ctlOptionGroup.Controls
Select Case ctl.ControlType
Case acOptionButton, acToggleButton
If ctl.Controls.Count = 1 Then
strOptionToggleLabels = strOptionToggleLabels & " " & ctl.Controls(0).Name
End If
End Select
Next ctl
strOptionToggleLabels = strOptionToggleLabels & " "
For Each ctl In ctlOptionGroup.Controls
Select Case ctl.ControlType
Case acLabel
If InStr(" " & strOptionToggleLabels & " ", ctl.Name) = 0 Then
Set FindOptionGroupLabel = ctl
End If
End Select
Next ctl
Set ctl = Nothing
End Function
Teraz, to łamie jeśli nie ma etykieta przymocowana, więc będzie to prawdopodobnie więcej sensu za to, aby powrócić nazwę etykiety, niż referencyjne:
Public Function FindOptionGroupLabel(ctlOptionGroup As Control) As String
Dim ctl As Control
Dim strOptionToggleLabels As String
If ctlOptionGroup.ControlType <> acOptionGroup Then
MsgBox ctlOptionGroup.Name & " is not an option group!", _
vbExclamation, "Not an option group"
Exit Function
End If
For Each ctl In ctlOptionGroup.Controls
Select Case ctl.ControlType
Case acOptionButton, acToggleButton
If ctl.Controls.Count = 1 Then
strOptionToggleLabels = strOptionToggleLabels & " " & ctl.Controls(0).Name
End If
End Select
Next ctl
strOptionToggleLabels = strOptionToggleLabels & " "
For Each ctl In ctlOptionGroup.Controls
Select Case ctl.ControlType
Case acLabel
If InStr(" " & strOptionToggleLabels & " ", ctl.Name) = 0 Then
FindOptionGroupLabel = ctl.Name
End If
End Select
Next ctl
Set ctl = Nothing
End Function
Można to prawdopodobnie zrobić za pomocą pojedynczej pętli w zbiorze Kontrolki grupy opcji, ale jest późno! To, co tam jest, wydaje się dość bliskie kuloodporności, nie, żeby ktokolwiek dawał osioł szczura, oczywiście! :)
Tak, to jest to. Dziękujemy! – Markus