Access vba закрыть форму
12.5 Работа с формами Access из VBA (объект Form )
Объект Access.Form, работа с формами Access средствами VBA, открытие формы Access, работа с элементами управления на форме Access
Один из важнейших элементов Access, который широко используется в приложениях — это формы. Формы Access предназначены для того же, для чего и обычные формы VBA — это прежде всего контейнеры для графических элементов управления. Но устройство форм Access, их функциональные возможности, приемы работы с ними и даже наборы элементов управления, которые на них можно размещать, сильно отличаются от привычных нам форм VBA, которые можно использовать в Word и Excel.
Формы Access используются:
- Для редактирования записей в таблицах базы данных Access и внешних источников данных. Для того, чтобы создать такие формы, вообще не нужно никакого программирования — достаточно создать форму в режиме конструктора или воспользоваться мастером создания форм. Подключиться к внешнему источнику данных (например, базе данных SQL Server или Oracle) можно, воспользовавшись в Access меню Файл ->Внешние данные ->Связь с таблицами.
- Как панели управления вашего приложения. Очень часто в приложении на основе Access создается начальная форма, которая открывается при запуске этого приложения. На этой формы предусмотрены кнопки и другие элементы управления для вызова других форм, отчетов, макросов, выхода из приложения и выполнения прочих операций. После закрытия других форм управления опять передается начальной форме.
- Просто для предоставления пользователю возможности выполнения любых действий. Например, форму можно использовать для выбора пользователем параметров отчета, выгрузки данных во внешнее приложение (например, Excel) и т.п.
Как работать с формами Access из VBA?
Первое, что необходимо сказать — для работы с формами во многих ситуациях нам придется использовать общий объект AccessObject, который представляет в Access не только формы, но и таблицы, макросы, модули, отчеты и множество других элементов. Поскольку этот объект — универсальный, то, конечно, большой помощи от Intellisense — подсказки в редакторе VBA у нас не будет. Обратиться к объекту формы можно через коллекцию AllForms, которая доступна через объекты CodeProject и CurrentProject. Например, получить информацию о всех формах в базе данных Access можно так:
Dim oA As AccessObject
For Each oA In CurrentProject.AllForms
Если вы будете обращаться к формам в коллекции AllForms по индексу, обратите внимание, что нумерация форм в этой коллекции начинается с 0. Обращаться к элементам в этой коллекции можно и по имени:
Специальное свойство IsLoaded определяет, открыта ли эта форма (то есть загружена ли она в оперативную память).
Программным образом формы можно найти и другим способом. Все открытые формы Access автоматически помещаются в коллекцию Application.Forms и представляются в виде объекта Form. Это — уже нормальный объект, свойства которого соответствуют свойствам формы, доступным через графический интерфейс. Например, если форма Форма1 открыта, получить информацию о ее ширине можно так:
Debug.Print Application.Forms(«Форма 1»).Width
Это свойство можно использовать и для изменения ширины формы, но для этой цели рекомендуется использовать метод DoCmd.MoveSize(), который изменяет размеры активного объекта (например, нашей формы, если она активна):
DoCmd.MoveSize Width :=10000
Еще одна возможность: если вы работаете с кодом самой формы или ее элементов управления (например, события Click кнопки, которая расположена на форме), то обратиться к объекту самой этой формы можно совсем просто. Для этого используется ключевое слово Form.
Как можно открыть форму?
Первое, что нужно сказать — если в Word или Excel нам обязательно потребуется открыть форму программным способом, то в Access это совсем необязательно. Можно открыть форму и вручную из окна базы данных (см. рис. 12.1). Из этого же окна обычно производится создание новых форм или изменение существующих.
Рис. 12.1 Окно для работы с формами в Access
Еще один часто используемый способ — просто запускать форму при открытии базы данных Access. Для этого в меню Сервис нужно выбрать Параметры запуска и выбрать нужную форму в списке Вывод формы/страницы. Если при этом вы уберете все остальные флажки, то приложение при открытии приложение может выглядеть так, как показано на рис. 12.2:
Рис. 12.2 Все лишние возможности Access спрятаны от пользователя
Окно базы данных будет скрыто от пользователя, а это значит, что пользователь не сможет получить информацию ни о таблицах нашей базы данных, ни о других формах, ни о модулях — все служебные элементы базы данных будут от него спрятаны. В принципе, пользователь может обойти такую защиту, держа нажатой при запуске Access кнопку , но программным способом можно закрыть и такую возможность.
Если все-таки нужно открыть форму программным способом (например, из другой формы), то для этой цели можно использовать метод DoCmd.OpenForm(). В самом простом варианте этот метод просто принимает параметр с именем формы:
Если же форма уже открыта, то этот метод, конечно, не открывает форму заново, а просто активизирует ее. Метод DoCmd.OpenForm() принимает также несколько необязательных параметров, при помощи которых вы можете настроить фильтр на отображение записей в форме, режим открытия формы (например, модальность) и т.п. Закрытие формы производится при помощи метода DoCmd.Close(). Если же вам нужно просто спрятать форму, чтобы сохранить введенные на ней пользователем значения и отобразить их при следующем показе, можно просто сделать форму невидимой, назначив ее свойству Visible значение False.
Форма нам обычно нужна не сама по себе, а как контейнер для расположенных на ней элементов управления. Обычно элементы управления программным способом создавать не требуется — намного проще и удобнее поместить их на форму в режиме конструктора для формы. В наборе элементов управления для формы предусмотрены как знакомые нам элементы управления — текстовые поля, надписи, кнопки, флажки и переключатели, так и новые элементы — свободная и присоединенная рамки объектов, разрывы страниц, подчиненные формы/отчеты и т.п. В верхнем правом углу Toolbox в конструкторе формы Microsoft Access находится специальная кнопка Мастера. Если она нажата, то добавление на форму привычных элементов управления (например, кнопки) приведет к появлению окна мастера, который попытается помочь вам автоматически сгенерировать нужный код VBA для этого элемента управления (см. рис. 12.3)
Рис. 12.3 Мастер создания кнопок
Можно использовать генерируемый мастером код как заменитель макрорекордера (которого в Access нет), чтобы понять, как можно выполнить те или иные действия.
Для чего используются нестандартные (по отношению к обычным формам VBA) элементы управления:
- Свободная рамка объекта — возможность разместить на форме OLE-объект (например, документ Word, лист Excel, презентация PowerPoint, рисунок, звукозапись или видеоклип), который может быть встроен в базу данных Access (но не помещен в таблицу!) или находиться во внешнем по отношению к базе данных Access файлу.
- Присоединенная рамка объекта — то же самое, за исключением того, что он применяется для работы с объектами OLE, которые хранятся в таблицах внутри баз данных Access или внешнего источника данных. Это — самый удобный способ генерации отчетов в Word.
Например, предположим, что в нашей базе данных Access находится таблица с тремя столбцами, как показано на рис. 12.4.
Рис. 12.4 Таблица для хранения шаблонов Word
В столбце File у нас хранятся шаблоны Word, которые используются для генерации отчетов. Мы помещаем на форму элемент управления Присоединенная рамка объекта с именем WordTemplate. После этого все, что нужно для создания файла Word на основе шаблона из базы данных, у нас уже есть. Для кнопки, по нажатию на которой будет формироваться отчет, можно использовать следующий код:
‘Получаем ссылку oFrame на объект присоединенной рамки на форме
Dim oFrame As BoundObjectFrame
Set oFrame = oForm.Controls(«WordTemplate»)
‘При помощи метода DLookup () скачиваем в него значение столбца File из таблицы
‘Templates, где номер строки (значение столбца Num ) равно 1
oFrame = Application.DLookup(«[File]», «Templates», «[Num] = 1»)
‘Открываем объект в отдельном окне приложения — то есть создаем
‘документ Word на основе шаблон, загруженного в рамку объекта на форме
‘Активизируем объект приложения
‘Получаем ссылку на Word в переменную oWord
Dim oWord As Word.Application
Set oWord = GetObject(, «Word.Application»)
‘Получаем ссылку на созданный нами документ
Dim oDoc As Word.Document
Set oDoc = oWord.ActiveDocument
‘Дальше работаем средствами Word, например, вставляем нужный текст
‘в места, отмеченные закладками
Конечно же, правильнее будет при этом сделать эту присоединенную рамку объекта на форме изначально невидимой — чтобы пользователь не мог этот объект активизировать по собственной инициативе.
- Элемент управления Разрыв страницы — определяет начало нового экрана формы.
- Подчиненная форма/отчет — используется для размещения на форме подчиненных форм, таблиц или отчетов.
Как уже говорилось, программным способом элементы управления в форме Access приходится создавать редко. Если на форме вам нужен переменный набор элементов управления, то правильнее будет с самого начала создать все нужные элементы управления и по необходимости делать их то видимыми, то невидимыми. Тем не менее создать программным способом элементы управления на форме тоже можно. Эта операция выполняется при помощи метода Application.CreateControl(), который принимает множество параметров — имя формы, на которой создается элемент управления, тип элемента управления, его месторасположение на форме и т.п.
Обращение к значениям элементов управления на форме производится через коллекцию Controls, которая умеет работать с именами элементов управления:
Access vba закрыть форму
Есть процедурка, она открывает (docmd.openform) формочку на которой пользователь может нажать одну из трёх кнопочек, допустим: «да», «нет», «отмена».
Нажатие на одну из кнопочек приводит к закрытию формы (docmd.close)
Как же узнать какую кнопочку нажал пользователь и использовать эту информацию в открывшей форму процедуре?
Как передать из закрывающейся формы эти данные?
Не засовывать же какое-нибудь значение соответствующее конкретной кнопке в таблицу из которой потом и брать его для процедуры. Как-то это не то.
Да и процедура, вызвавшая форму, не будет ждать закрытия формы, дабы получить от неё результат, а побежит себе далее прямо к end sub.
П.С. Форма создана штатными средствами акцесса, т.к. не умею сделать её программно. Точнее не могу сообразить как мне вновь созданную форму на экран-то вывести? Ни метода activate, ни show ничего у неё нет.
Вызвавшую процедуру можно «завесить», например так:
————————————————
Sub DelayForm(FNam As String)
‘ Процедура приостанавливает выполнение модуля формы
‘ на время работы другой формы
Dim F As Form
Dim L As Long
Dim B As Boolean
Do
‘ Пауза в 1 сек для работы другой формы
L = Timer
Do While Timer код: Теперь пусть есть форма, откуда надо открыть первую форму, передать в неё параметр(-ы), получить обратно. На форме есть надпись Label0 и кнопка Command1. Модуль формы: код:
selfexile
передать массив — не желает кушать массив, только строки, говорит, люблю. А вот это плохо!
массив строк?
по идее должен «кушать»
Lucy
А вдруг мне 2 биллиона символов не хватит?
На счёт «кушать», в справке указано, что только строку и можно передать в openargs. Или я чего со своим недоанглийским плохо понимаю? А то мне несколько строк (массив) нужно передать в форму, так, что я их через за. через таблицу передаю пока что. А это как-то некрасиво выходит. Функция получает массив, запихивает его в таблицу sql-запросом, запускает форму, та работает с полями этой таблицы, затем форма закрывается и функция, продолжая работу, запихивает данные из таблицы обратно в массив (переданный в эту функцию byref) при помощи ado.recordset. Качмар!
Бенедикт
Примем к сведению. Распечатаем и попробуем вникнуть/разобраться.
————————————-
У меня вот теперь какая-то ерунда с формой появилась. Открывается она с where condition nomer=1, а ей по барабану! Она УПОРНО создаёт мне новую запись в таблице к которой привязана, чтоб её разворотило, а мне нужно редактировать ЕДИНСТВЕННУЮ запись в таблице и чтобы никаких новых записей не появлялось ни в коем случае. Эта единственная запись и имеет поле nomer = 1. Ничего не пойму!
Добавление от 25.11.2008 07:39:
Сделал для этой формы набор записей «статический»
Фильтр сработал. Открылась нужная запись, а не новая. Только теперь поля для ввода не дают изменять данные — булькают, типа поле недоступно для редактирования.
Добавление от 25.11.2008 08:13:
Тьфу! Тьфу! Тьфу! Тьфу! Тьфу!
Пардон, я сейчас вытру страничку.
В свойствах формы было указано «ввод данных — да», оказывается это означает, что форма будет открываться ИМЕННО для новой записи. А я думал, что это означает разрешение на ввод данных вообще в поля формы.
П.С. Ненавижу изучать языки-среды разработки! Люблю пользоваться уже имеющимися данными. Сколько времени уходит на какую-нибудь ерундень вроде этой.
Даёшь загрузку знаний прямо в мозг!
selfexile
в справке указано, что только строку и можно передать в openargs
читаем справку (http://www.datawright.com.au/access_resources/access_docmd.openform_arguments.htm) :
«OpenArgs — type Variant.
A string expression. This expression is used to set the form’s OpenArgs property. This setting can then be used by code in a form module , such as the Open event procedure . «
с другой стороны, тип Variant — структура, которая может содержать различные типы данных, в том числе и массив:
Value Variant type
0 Empty (unitialized)
1 Null (no valid data)
2 Integer
3 Long Integer
4 Single
5 Double
6 Currency
7 Date
8 String
9 Object
10 Error value
11 Boolean
12 Variant (only used with arrays of variants)
13 Data access object
14 Decimal value
17 Byte
36 User Defined Type
8192 Array
код: VarType(arr) должна возвратить 8192.
поэтому, что-то вроде
код: может работать
Lucy
А зачем мне проверять массив ли получила форма через openargs?
Я, находясь в трезвом уме и твёрдой памяти, ответственно заявляю, что МОЯ форма посредством openargs НИКОГДА ничего кроме массива определённой мною размерности и типа НЕ получит.
А массив я пытался передать. Не получается. По-моему на несоответствие типов и ругается, не помню сейчас.
selfexile
Я, находясь в трезвом уме и твёрдой памяти, ответственно заявляю, что
пройдет время, кто-то захочет что-то поменять, что у Вас было/есть в памяти ему будет неинтересно. etc.
Access vba закрыть форму
193 просмотра
2 ответа
66 Репутация автора
У меня есть основная форма с именем Calling. У него есть кнопка с названием Travel. Эта кнопка Travel делает:
Форма Информация о путешествии работает правильно. Эта форма Путешествия имеет кнопку Закрыть с кодом:
При нажатии код закрытия генерирует «Ошибка во время выполнения« 361 »: невозможно загрузить или выгрузить этот объект.
Ваша помощь очень ценится.
Ответы (2)
2 плюса
1382 Репутация автора
Вам не нужны запятые с пустыми строками, а также вам не нужно, так acFormEdit как при открытии формы вы в любом случае сможете редактировать и добавлять новые записи.
Если оставить этот аргумент пустым, форма откроется в режиме данных, установленном разрешениями AllowEdits, AllowDeletions, AllowAdditions и DataEntry (в свойствах формы).
Что касается следующей подпрограммы, я бы использовал docmd.close вместо выгрузки.
me.undo Не является обязательным, если вы не хотите , чтобы сохранить, и если вы хотите сохранить форму изменить acSaveNo к acSaveYes .
Я только что перечитал ваш вопрос и заметил в заголовке, без чего вы хотите docmd .
Я думал об этом, и docmd это стандартный способ закрытия форм в доступе с использованием VBA. Я не уверен, если вы унаследовали unload от использования VB, но я бы придерживался docmd.close при использовании доступа.
Автор: LiamH Размещён: 19.05.2016 02:32
0 плюса
11 Репутация автора
«Unolad me» просто не работает в объектах формы доступа. Access хочет, чтобы вы использовали DoCmd.Open/DoCmd.Close, но вы умны и можете использовать объект формы доступа в качестве объекта. Имена доступа, которым классы форм ставят префикс имени, которое вы им даете с помощью «Form_». Вы создаете форму с именем «YourForm», Access создает класс «Form_YourForm». Используйте этот класс как реальный объект:
Кроме того, вы можете использовать Form_YourForm непосредственно как переменную объекта, потому что VBA Access просто «неявно» создает этот объект из класса Form_YourForm при первом его использовании или при использовании DoCmd.Open. (Да, это немного сбивает с толку, но Access был создан для пользователей, у которых не обязательно были навыки программиста). Однако вы будете получать разные экземпляры класса Form_YourForm каждый раз, когда будете использовать переменный объект, типизированный как любой из классов форм, существующих в вашем проекте. Это означает, что вы можете открыть столько экземпляров формы, сколько захотите . или пока она умещается в памяти вашего компьютера. Вы не можете сделать это, используя DoCmd.Open.
Основными «недостатками» является то, что вам приходится обрабатывать объект формы из другого модуля. Вы по-прежнему можете использовать коллекцию «Формы», но, поскольку вы не знаете заданный ключ, вы не можете легко получить доступ к экземпляру формы. Кроме того, вы не можете закрыть форму из ее собственного кода, а только располагать типизированную переменную (Set f = nothing).
Макрокоманда «закрытьокно»
Примечание: Мы стараемся как можно оперативнее обеспечивать вас актуальными справочными материалами на вашем языке. Эта страница переведена автоматически, поэтому ее текст может содержать неточности и грамматические ошибки. Для нас важно, чтобы эта статья была вам полезна. Просим вас уделить пару секунд и сообщить, помогла ли она вам, с помощью кнопок внизу страницы. Для удобства также приводим ссылку на оригинал (на английском языке).
С помощью макрокоманды закрытьокно можно закрыть вкладку указанного Access документа или вкладку активного документа, если не указан.
Примечание: Начиная с Access 2010 макрокоманда Закрыть переименована закрытьокно.
Примечание: Макрокоманда «ЗакрытьОкно» недоступна в веб-приложениях Access.
Настройка
Макрокоманды закрытьокно аргументы описаны ниже.
Тип объекта, которого вы хотите закрыть вкладку документа. Выберите таблицы, запроса, формы, отчета, макроса, модуля, страницы доступа к данным, представление сервера, схемы, хранимая процедура или функцию в поле Тип объекта поле в разделе Аргументы макрокоманды окна конструктора макроса. Выберите вкладку активного документа, этот аргумент оставлен пустым.
Примечание: При закрытии модуля в редакторе Visual Basic необходимо использовать элемент Модуль в аргументе Тип объекта.
Имя объекта, который нужно закрыть. В поле Имя объекта указаны все объекты базы данных, относящиеся к типу, заданному аргументом Тип объекта. Щелкните объект, который нужно закрыть. Если аргумент Тип объекта оставлен пустым, этот аргумент тоже должен быть пустым.
Определяет, нужно ли сохранять изменения в объекте при закрытии. Выберите вариант Да (сохранить объект), Нет (закрыть объект без сохранения) или По выбору (запрашивать у пользователя, нужно ли сохранить объект). По умолчанию задан вариант По выбору.
Заметки
Макрокоманды закрытьокно работает на всех объектов базы данных, которые пользователь явным образом можно открыть или закрыть. Это действие действует так же, как при выборе объекта и его закрытия, щелкните правой кнопкой мыши вкладку документа объекта и затем нажмите кнопку Закрыть в контекстном меню или щелкните Закрыть кнопка объекта.
Если для аргумента Сохранение задано значение По выбору и объект не был сохранен перед выполнением макрокоманды Закрыть, открывается диалоговое окно, в котором пользователю предлагается сохранить объект перед закрытием. Если в макрокоманде УстановитьСообщения для аргумента Включить сообщения задано значение Нет, диалоговое окно не появляется и объект сохраняется автоматически.
Для запуска макрокоманды закрытьокно в модуле Visual Basic для приложений (VBA), используйте метод Закрыть объекта DoCmd .
Access VBA: закрытие формы приводит к дублированию записи в таблице
Позвольте мне объяснить, что я установил, чтобы легко описать мою проблему. Я создал дочернюю форму на основе таблицы, которая для иллюстрации выглядит следующим образом:
Каждая Text Box ограничена, т. е. ее Control Source указывает на соответствующее имя поля из таблицы.
В нижней части есть save Command Button , где я добавил некоторый код vba, чтобы вставить 4 значения полей в таблицу.
После нажатия кнопки Сохранить я делаю следующее, чтобы вставить в таблицу и закрыть форму:
Проблема заключается в том, что после закрытия формы она создает дублирующую запись в таблице.
Из-за моего незнания программирования vba на данный момент я знаю, что это связано с ограниченными текстовыми полями в таблице, потому что если я удаляю поля Control Source из текстовых полей, оставляя их пустыми, и вручную извлекаю значения в текстовых полях вместо этого , т. е. Me.textBox_OtherNumber , а затем вставляю эти значения в таблицу при нажатии кнопки сохранения, я не получаю дублирующую запись в таблице, когда форма закрыта.
Однако я бы предпочел, чтобы текстовые поля были ограничены таблицей, поскольку это облегчает открытие формы либо в режиме acFormAdd , где значения полей пусты и ждут добавления в качестве новой записи ,либо в режиме acFormEdit , где значения полей уже заполнены значениями из выбранной строки таблицы с помощью параметра WHERE criteries clause в DoCmd.OpenForm .
Например, у меня есть родительская форма, которая содержит Command Button и subform . Подформа Source Object связана с Datasheet , чья Record Source связана с той же таблицей, что и дочерняя форма.
В поле OtherNumber из Datasheet я создал hyperlink и запрограммировал его команду On Click , чтобы она была такой:
При щелчке по конкретному hyperlink определенной строки поля в frmTest заполняются данными на основе criteria , которые будут использоваться для обновления текущей записи.
Однако, если Command Button нажата в родительской форме, я делаю следующее:
Форма открыта, но значения полей пусты, что указывает на то, что новая запись будет добавлена на основе значений полей.
Мне кажется, что это намного проще, чем не иметь текстовых полей в frmTest , связанных с чем-либо, и если бы это не было ограничено, мне пришлось бы найти способ ссылаться на значения полей в Datasheet и передавать дочернюю форму frmTest .
Видите ли вы мою дилемму? Каков лучший способ решить эту проблему?
1 Ответ
Существует очень много способов решить эту проблему:
Используя связанную форму, на кнопке Сохранить просто опустите строку для сохранения записи (так как доступ автоматически сохраняет ее):
Или, если вы не доверяете доступу, чтобы сохранить его:
Обратите внимание, что acSaveNo относится к отсутствию сохранения каких-либо изменений в дизайне формы и никоим образом не связано с сохранением записей.
Если вы хотите задать значения для несвязанной формы из другой формы:
(конечно, есть много альтернатив и этому. Наиболее важным является то , что вы можете передавать аргументы между формами, используя параметр OpenArgs из DoCmd.OpenForm , и вы можете обрабатывать их при загрузке формы).
Похожие вопросы:
Мой доступ 2000 DB вызывает у меня проблемы-иногда (не определил причину) форма book не закрывается. Нажатие его кнопки закрытия ничего не делает, File -> Close ничего не делает, даже закрытие.
Можно ли Просмотреть код создания формы в Access VBA? Я не имею в виду код прослушивателя событий, который можно просмотреть в коде VBE from View>в представлении конструктора формы. Я имею в виду.
У меня есть код в событии Before_Update, для сохранения изменений. Для этого я использую Msgbox с подсказкой YesNoCancel, но я не могу предотвратить закрытие формы, когда я нажимаю кнопку отмены.
Как показано на рисунке ниже, одно изображение плохо совмещается с другим, что приводит к дублированию сосудов. Как мне избавиться от дублирования? В настоящее время я занимаюсь сшиванием, сначала я.
Я работаю над преобразованием устаревшего приложения из MS Access / VBA в C#. мягко говоря, есть некоторые проблемы с качеством устаревшего кода. Есть по крайней мере одно место в коде VBA, которое.
Я уверен, что это очень просто, но я не могу найти его. В случае закрытия формы доступа, как я могу отменить закрытие формы? У меня есть тест, который подсчитывает записи в таблице. Если в этой.
У меня есть мое приложение, где есть тысячи страниц. Я нашел проблему, когда я размещаю некоторые значения через форму и делаю их записи в базе данных. Но когда я обновляю страницу, это приводит к.
Мое приложение предназначено для открытия нескольких экземпляров одной и той же формы ‘Request’. На графике при нажатии на определенную кнопку в форме может произойти ряд действий по обновлению, за.
Я вроде как новичок в программировании MS-Access & VBA. Я разработал многопользовательское приложение в MS-Access 2016 и VBA и преобразовал его в accdb. Мне нужно получить значение, которое я.
У меня есть форма в Access, где у меня есть 2 несвязанных списка множественного выбора, с некоторым кодом для перемещения элементов между ними. Каждое из полей в таблице, которые отображаются в.