Доступ к VBA - Как бы я имел цикл в VBA, который позволяет мне циклически просматривать имена элементов управления - PullRequest
7 голосов
/ 12 октября 2010

У меня около 10 текстовых полей в форме, которые фактически используются для отображения, а не для ввода. Они называются txt_001_Name, txt_002_Title и т. Д. Какой тип цикла используется для этого.

Какой тип VBA мне следует использовать для того, чтобы фактически проходить по именам текстовых полей? Так что, если бы я был debug.print, он бы выглядел так:

txt_001_Title
txt_002_Title
txt_003_Title

Это, вероятно, довольно просто сделать - тем более я должен научиться тому, как!

РЕДАКТИРОВАТЬ: Извините, я должен был быть более информативным об этом.

Из-за вышеуказанного соглашения об именах я собираюсь перебрать эти текстовые поля, чтобы я мог что-то выполнить с каждым. Каждое из этих 10 текстовых полей на самом деле представляет собой числовые значения, каждое из которых имеет SQL-оператор в событии onload формы. У меня также есть другой набор из десяти, которые содержат числовые значения, которые являются гораздо более статичными, и, наконец, еще десять, которые используют выражение, чтобы просто разделить каждое из первых десяти, на относительное «второе» десять, и значение заканчивается в относительном 3. Таким образом, в основном это выглядит как таблица приборной панели.

'first ten'       'second ten'     'resulting ten'
---------------------------------------------------
txt_001_value      txt_001_calc     txt_001_result
txt_002_value      txt_002_calc     txt_002_result

и т.д.

Так что я действительно хочу использовать это для «результирующих» текстовых полей. Я хочу просмотреть первую десятку и выполнить простой расчет:

 me.txt_001_result = me.txt_001_value / me.txt_001_calc     

Все соглашения об именах "совпадают", поэтому я могу вручную набрать 10 строк выше для этого, но я уверен, что есть лучший способ (цикл через это), и я, вероятно, должен изучить его.

Ответы [ 3 ]

8 голосов
/ 12 октября 2010

Вы можете перечислить имена элементов управления текстовым полем с помощью простой процедуры, подобной этой:

Public Sub TextBoxNames(ByRef pfrm As Form)
    Dim ctl As Control
    For Each ctl In pfrm.Controls
        If ctl.ControlType = acTextBox Then
            Debug.Print ctl.Name
        End If
    Next ctl
    Set ctl = Nothing
End Sub

Вы можете вызвать его из события Load формы:

Private Sub Form_Load()
    TextBoxNames Me
End Sub

Однако я не понимаю, чего вы пытаетесь достичь. Я понимаю, что вы хотите что-то сделать с ctl.Name , отличным от Debug.Print, но я не знаю, что это такое.

Вместо вычисления результата для me.txt_001_result и последующего присвоения этого значения текстовому полю рассмотрите возможность установки источника управления для txt_001_result на txt_001_value / txt_001_calc и пусть Access поместит правильное значение в txt_001_result для вас.

В ответ на ваши комментарии я предложу эту процедуру в качестве отправной точки, на которой вы должны опираться:

Public Sub MyTextBoxValues()
    Const cintLastTextBoxNum As Integer = 10
    Dim i As Integer
    Dim strValueControl As String
    Dim strCalcControl As String
    Dim strResultControl As String
    Dim strPrefix As String

    For i = 1 To cintLastTextBoxNum
        strPrefix = "txt_" & Format(i, "000")
        'txt_001_value      txt_001_calc     txt_001_result '
        strValueControl = strPrefix & "_value"
        strCalcControl = strPrefix & "_calc"
        strResultControl = strPrefix & "_result"
        'me.txt_001_result = me.txt_001_value / me.txt_001_calc '
        'Debug.Print strResultControl, strValueControl, strCalcControl '
        Me.Controls(strResultControl) = Me.Controls(strValueControl) / _
            Me.Controls(strCalcControl)
    Next i
End Sub
4 голосов
/ 12 октября 2010

Я предпочитаю использовать FOR EACH для перебора коллекции элементов управления независимо от того, включены ли текстовые поля (либо сама форма, либо элемент управления панели)

dim myBox as Textbox
For each myBox in myForm
    myBox.Text = "hello"
Next

Также означает, что вы можете создавать собственные группы (помещая их все в один контейнер). Обратите внимание, что если у вас есть другие элементы управления, вам может понадобиться проверка типов (IF TYPEOF(myBox) = "TextBox" THEN ...)

Вы также можете сделать это как:

dim i as integer
For i = 1 to 10
     myForm.Controls("txt_00" & i & "_Title").Text = "hello"
Next i

Я определенно предпочитаю For Each, хотя.

2 голосов
/ 13 октября 2010

Я не могу полностью понять, почему вам нужно делать то, что вы делаете, но у меня были такие формы, где у меня была несвязанная форма, я хотел отобразить произвольное количество полей, поэтому я могу видеть это , Если вы просматриваете коллекцию элементов управления только в событии OnOpen формы, это нормально. Но если вы делаете это в OnCurrent связанной формы или несколько раз в несвязанной форме, вы можете рассмотреть мой длинный пост на с использованием пользовательских коллекций для управления группами элементов управления .

...