Возможно, вы захотите изучить создание пользовательских коллекций, а затем передать их своим функциям. Я широко использую их в формах для проверки контроля. Скажем, на уровне модуля формы вы определили эту коллекцию:
Dim mcolDateFields As New Collection
Тогда в событии OnLoad вашей формы вы можете сделать это:
mcolDateFields.Add Me!txtDateEntered, "txtDateEntered"
mcolDateFields.Add Me!txtDatePrinted, "txtDatePrinted"
mcolDateFields.Add Me!txtDateArchived, "txtDateArchived"
Чтобы просмотреть эту коллекцию, вы должны сделать что-то вроде этого:
Dim varItem As Variant
Dim ctl As Control
For Each varItem In mcolDateFields
Set ctl = varItem
Debug.Print ctl.Name & ": " & ctl.Value
Next varItem
Set ctl = Nothing
... где вы бы заменили Debug.Print чем-то действительно полезным.
Затем вы также можете передать элемент управления другим подпрограммам кода, которые принимают коллекцию в качестве параметра и что-то с ней делают:
Public Sub (mcolCollection As Collection)
Dim varItem As Variant
Dim ctl As Control
For Each varItem In mcolCollection
Set ctl = varItem
Debug.Print ctl.Name & ": " & ctl.Value
Next varItem
Set ctl = Nothing
End Sub
Это может позволить вам передать коллекцию элементов управления, которые вы хотите проверить. Поскольку в вашей коллекции хранятся контрольные ссылки, а не контрольные имена или контрольные значения, нет необходимости передавать имя родительской формы. Если вам это нужно, вы можете получить это с помощью:
Dim varItem As Variant
Dim ctl As Control
For Each varItem In mcolCollection
Set ctl = varItem
Debug.Print ctl.Parent.Name & "!" & ctl.Name & ": " & ctl.Value
Next varItem
Set ctl = Nothing
Аналогичным образом, если вы хотите использовать форму таким же образом, как и ключевое слово Me в собственном модуле формы, просто используйте ctl.Parent, который возвращает ссылку на форму, если элемент управления находится в самой форме ( а не, скажем, на вкладке управления).
Некоторые комментарии к вашим примерам кода - ваш первый выглядит так:
Private Sub ExampleProc1()
Dim intCancel as Integer
intCancel = False
Me.Controls("Date1").Value=Null
Me.Controls("Textfield1").Value=Null
Call Date1_BeforeUpdate(intCancel)
Call Textfield1_BeforeUpdate(intCancel)
End Sub
Хотя оно определяется как целое число при создании отменяемого события, на самом деле это совсем не так - это логическое значение, и для отмены события вы должны установить его равным True (-1). Я думаю, что это на самом деле удержание в Access VBA со времен Access до VBA, когда в Access Basic отсутствовал логический тип данных. В общем случае я использую логические значения только для переменных, используемых с параметром Cancel.
Me.Controls("Date1").Value=Null
Я не знаю, почему ты так поступил. Я бы написал это так:
Me!Date1 = Null
Ваш код слишком многословен, так как вы дважды указали значения по умолчанию: коллекция Controls является коллекцией формы по умолчанию. На самом деле коллекция по умолчанию представляет собой конкатенацию коллекций Controls и Fields, поэтому могут быть веские причины для указания того, что вы хотите использовать элемент управления, например, если вы используете свойство элемента управления, которого нет в соответствующем поле. Но для манипулирования значениями, если есть элемент управления с тем же именем, что и у поля, не имеет значения, какое значение вы используете, поскольку они будут идентичны, за исключением крайне маловероятного события, когда элемент управления фактически не привязан к полю с таким же именем.
Аналогично, .Value является свойством по умолчанию для элементов управления, поэтому нет никаких оснований указывать его. Единственные обстоятельства, при которых вы можете захотеть это сделать, - это если вы используете его в качестве параметра для вызова другой подпрограммы, где параметром является ByRef, а не ByVal. Но в целом, просто присвоить значение элементу управления, это пустая трата ввода.
Чтобы сделать то, что вы пытаетесь достичь, сбор контрольных ссылок кажется мне хорошим решением. Я не знаю, должны ли события для этих элементов управления быть публичными или нет.