2

ControlSource をサポートするコントロールの ControlSource プロパティを表示するために、フォーム上のコントロールを反復処理しようとしています。

ControlSource プロパティを持つコントロールを識別するのは比較的簡単であることがわかりました。問題は、これらのコントロールのプロパティにアクセスすることです。ジェネリック コントロール オブジェクトには ControlSource プロパティがありません。別の言語を使用している場合は、たとえば ControlSource プロパティにアクセスするために、リストボックスであるコントロールを ListBox オブジェクトにキャストするだけです。しかし、私の理解では、VBA には型の継承がないため、ある型のオブジェクトを別の型にキャストすることはできません。

では、プロパティをサポートするコントロールの ControlSource プロパティにアクセスするにはどうすればよいでしょうか。

これまでの私のコードは次のとおりです。

Private Sub IterateControlsOnForm()
Dim frm As Form, formName As String
' The only controls that have a ControlSource property are either
'   BoundObjectFrame controls or ListBox controls.
Dim ctrl As Control
Dim boundObjectFrame As boundObjectFrame, listBoxCtrl As listBox
Dim boundObjectFrameTypes() As String, listBoxTypes() As String
Dim ctrlType As String

    formName = "MAINFORM"

    ' Useful way of populating a string array - use Split function.
    '   Array function only works with Variants.
    boundObjectFrameTypes = _
        Split("CheckBox,ComboBox,CustomControl,GroupLevel", ",")
    listBoxTypes = Split("OptionButton,OptionGroup,TextBox,TextBox", ",")

    ' Assumes form is open.
    Set frm = Forms(formName)
    For Each ctrl In frm.Controls
        ' Ignore controls that do not have a ControlSource property.
        ctrlType = TypeName(ctrl)
        If IsStringInArray(ctrlType, boundObjectFrameTypes) Then
            ' **** FOLLOWING LINE FAILS ****
            Set boundObjectFrame = ctrl
            Debug.Print boundObjectFrame.Name & "(" & ctrlType & ") " & _
                "ControlSource Property: " & boundObjectFrame.ControlSource
        ElseIf IsStringInArray(ctrlType, listBoxTypes) Then
            ' **** FOLLOWING LINE FAILS ****
            Set listBoxCtrl = frm.Controls(ctrl.Name)
            Debug.Print listBoxCtrl.Name & "(" & ctrlType & ") " & _
                "ControlSource Property: " & listBoxCtrl.ControlSource
        End If
    Next ctrl
End Sub

ジェネリック Control オブジェクトを、ControlSource プロパティを持つより具体的なコントロールに変換する 2 つの方法を試しました。2 つのコメント " ** FOLLOWING LINE FAILS ** " を参照してください。

4

1 に答える 1

2

オブジェクトを使用するのはどうですか?

Private Sub IterateControlsOnForm()
Dim frm As Form, formName As String
' The only controls that have a ControlSource property are either
'   BoundObjectFrame controls or ListBox controls.
Dim ctrl As Control
Dim boundObjectFrame As Object, listBoxCtrl As Object
Dim boundObjectFrameTypes As String, listBoxTypes As String
Dim ctrlType As String

    formName = "MAINFORM"

    ' Useful way of populating a string array - use Split function.
    '   Array function only works with Variants.
    boundObjectFrameTypes = _
        ",CheckBox,ComboBox,CustomControl,GroupLevel"
    listBoxTypes = ",OptionButton,OptionGroup,TextBox,TextBox"

    ' Assumes form is open.
    Set frm = Forms(formName)
    For Each ctrl In frm.Controls
        ' Ignore controls that do not have a ControlSource property.
        ctrlType = TypeName(ctrl)
        If InStr(boundObjectFrameTypes, "," & ctrlType) Then
            Set boundObjectFrame = ctrl
            Debug.Print boundObjectFrame.Name & "(" & ctrlType & ") " & _
                "ControlSource Property: " & boundObjectFrame.ControlSource
        ElseIf InStr(listBoxTypes, "," & ctrlType) Then
            Set listBoxCtrl = frm.Controls(ctrl.Name)
            Debug.Print listBoxCtrl.Name & "(" & ctrlType & ") " & _
                "ControlSource Property: " & listBoxCtrl.ControlSource
        End If
    Next ctrl
End Sub

VBA では、On Error Resume Next を使用することもできますが、一般的にはエラーを回避するのが最善であることに同意します。

formName = "MAINFORM"

Set frm = Forms(formName)
For Each ctrl In frm.Controls
On Error Resume Next
    Debug.Print ctrl.Name _
        & " ControlSource Property: " & ctrl.ControlSource
    If Err.Number = 438 Then
        Err.Clear
    End If
Next
于 2012-10-25T22:22:35.410 に答える