Один из самых часто возникающих вопросов у новых пользователей Access (равно как и у ветеранов) это написание выражений для обращения к коллекциям (collections), объектам (objects) и свойствам (properties). Когда же всё-таки стоит использовать восклицательный знак ! (bang operator), а когда точку . (dot operator), и зачем всё это нужно?
Forms(“FormName”).Controls(“TextboxName”)
Forms(“FormName”)(“TextboxName”)
Forms(“FormName”)!TextboxName
Есть мнение, что точки надо использовать с элементами, созданными самим Access, а восклицательный знак - с элементами, созданными пользователем. Это совсем не стопроцентное правило и имеет много исключений. К примеру, восклицательный знак используется в параметрах запроса (query), обращающихся к полю формы (form field):
SELECT *
FROM MyTable
WHERE TableField = Forms!FormName!FieldName
Такой запрос будет брать значение параметра для WHERE прямо из поля FieldName формы FormName.
Самое лучшее правило - использовать восклицательный знак при обращении к элементам коллекции. FormName!ControlName это короткий вариант FormName.Controls!ControlName. При этом точку оставить для свойств и методов. Одно из явных преимуществ точки состоит в том, что при её использовании в редакторе VBA срабатывает технология Intellisense - та самая, которая показывает выпадающий список с предложениями свойств объекта. Вы просто можете написать Me. и дальше выбирать из списка. Это поможет немного ускорить процесс написания кода и избежать опечаток.
Использование восклицательного знака имеет одну особенность: в конечном счёте Access транслирует этот код в "скобочно-кавычечный" синтаксис, поэтому некоторые считают, что сэкономленное на написании кода время будет нивелировано дополнительными вычислениями интерпретатора. Вполне возможно, хотя мне пока не приходилось писать такой код на VBA, который требовал бы сколько-нибудь ощутимое время для интерпретации.
И, кстати, напоминаю, что имя объекта, содержащее пробелы, при использовании ! требует участия квадратных скобок []:
Forms("Form Name").Controls("Text box")
Forms![Form Name]![Text box]
Допустим, вы пишите код на VBA и и хотите обратиться к элементу управления (control) на открытой форме (form). Длинный вариант будет выглядеть так:
Forms(“FormName”).Controls(“TextboxName”)
А короткий так:
Forms!FormName!TextboxName
Сейчас я объясню, что тут на самом деле происходит. Восклицательный знак !, равно как и скобки с кавычками ("") отделяют объект от коллекции, к которой он принадлежит. В данном случае форма FormName принадлежит коллекции Forms, содержащей все открытые в настоящий момент формы. А элемент управления TextboxName входит в коллекцию Controls - все элементы управления формы FormName.
Восклицательный знак показывает, что следующий за ним объект это элемент коллекции. Он как бы говорит: "получи объект TextboxName из коллекции по умолчанию для родительского объекта". Родительским объектом в данном случае является FormName, а коллекцией по умолчанию - Controls. Коллекция по умолчанию это та коллекция, которая подразумевается в первую очередь, когда мы опускаем явное обращение к ней (т.е. не указываем, что это именно Controls, а просто ставим !). Это преимущественно делается для сокращения количества используемых слов в коде и времени кодирования.
Восклицательный знак показывает, что следующий за ним объект это элемент коллекции. Он как бы говорит: "получи объект TextboxName из коллекции по умолчанию для родительского объекта". Родительским объектом в данном случае является FormName, а коллекцией по умолчанию - Controls. Коллекция по умолчанию это та коллекция, которая подразумевается в первую очередь, когда мы опускаем явное обращение к ней (т.е. не указываем, что это именно Controls, а просто ставим !). Это преимущественно делается для сокращения количества используемых слов в коде и времени кодирования.
Можно было бы даже написать FormName.Controls!ControlName (просто используем ! вместо ("")), но восклицательный знак позволяет вообще избавиться от слова Controls, подразумевая его по умолчанию: FormName!ControlName
С другой стороны вы всегда можете использовать точку для обращения к свойству, коллекции или методу. Так как коллекция Controls является коллекцией по умолчанию, то точку тоже можно опустить. Сравните эти три варианта:
Forms(“FormName”).Controls(“TextboxName”)
Forms(“FormName”)(“TextboxName”)
Forms(“FormName”)!TextboxName
Есть мнение, что точки надо использовать с элементами, созданными самим Access, а восклицательный знак - с элементами, созданными пользователем. Это совсем не стопроцентное правило и имеет много исключений. К примеру, восклицательный знак используется в параметрах запроса (query), обращающихся к полю формы (form field):
SELECT *
FROM MyTable
WHERE TableField = Forms!FormName!FieldName
Такой запрос будет брать значение параметра для WHERE прямо из поля FieldName формы FormName.
Кстати говоря, у этого синтаксиса есть одна проблема: его можно использовать только явно прописывая обращение к форме в запросе, открыв запрос в окне Access в режиме редактирования SQL.
Обращение к полю формы из SQL
При создании запроса с таким же выражением в VBA, запрос не будет выполнен:
strSQL = "SELECT * " & _"FROM MyTable " & _"WHERE TableField = Forms!FormName!FieldName"DoCmd.RunSQL strSQL
Это связано с тем, что выражение SQL, сформированное в режиме SQL, проходит через интерпретатор, который преобразует его в традиционный Jet синтаксис, то есть просто подставляет значение поля вместо ссылки. При запуске из кода VBA выражение SQL передаётся в Jet-машину без изменений и не исполняется, т.к. происходит нарушение синтаксиса.
Самое лучшее правило - использовать восклицательный знак при обращении к элементам коллекции. FormName!ControlName это короткий вариант FormName.Controls!ControlName. При этом точку оставить для свойств и методов. Одно из явных преимуществ точки состоит в том, что при её использовании в редакторе VBA срабатывает технология Intellisense - та самая, которая показывает выпадающий список с предложениями свойств объекта. Вы просто можете написать Me. и дальше выбирать из списка. Это поможет немного ускорить процесс написания кода и избежать опечаток.
Intellisense в действии |
Использование восклицательного знака имеет одну особенность: в конечном счёте Access транслирует этот код в "скобочно-кавычечный" синтаксис, поэтому некоторые считают, что сэкономленное на написании кода время будет нивелировано дополнительными вычислениями интерпретатора. Вполне возможно, хотя мне пока не приходилось писать такой код на VBA, который требовал бы сколько-нибудь ощутимое время для интерпретации.
И, кстати, напоминаю, что имя объекта, содержащее пробелы, при использовании ! требует участия квадратных скобок []:
Forms("Form Name").Controls("Text box")
Forms![Form Name]![Text box]