Access recordset примеры
Access recordset примеры
Замечания
Объект Recordset представляет набор записей в основной таблице или набор записей, который получается в результате выполнения запроса.
Объекты Recordset используются для обработки данных в базе данных на уровне записи. При работе с объектами доступа к данным (DAO) почти все операции выполняются с помощью объектов Recordset. Каждый объект Recordset состоит из записей (строк) и полей (столбцов). Существуют объекты Recordset пяти типов:
- Объект Recordset типа таблицы — программное представление основной таблицы; используется для добавления, изменения или удаления записей из отдельной таблицы базы данных (только в рабочей области Microsoft Jet).
- Объект Recordset типа динамического набора записей — набор обновляемых записей, полученный в результате выполнения запроса. Объект Recordset типа динамического набора записей позволяет добавлять, изменять или удалять записи в основной таблице или таблицах. В объекте Recordset этого типа динамического набора могут содержаться поля из одной или нескольких таблиц базы данных. Этот тип объектов соответствует указателю ключевого набора записей ODBC.
- Объект Recordset типа статического набора записей — статическая копия набора записей, используемая для поиска данных или создания отчетов. Объект Recordset типа статического набора записей может содержать поля из одной или нескольких таблиц базы данных, но не допускает обновления полей. Этот тип объектов соответствует указателю статического набора записей ODBC.
- Объект Recordset типа статического набора записей с последовательным доступом — аналогичен статическому набору записей с тем лишь исключением, что в нем отсутствует указатель. Пользователь имеет возможность прокручивать записи только вперед. Это повышает быстродействие в ситуациях, когда достаточен однократный проход по набору записей. Этот тип объектов соответствует указателю набора записей с последовательным доступом ODBC.
- Объект Recordset динамического типа результирующий набор записей запроса по одной или нескольким основным таблицам, в котором допускается добавление, изменение или удаление записей. В таком объекте Recordset отображаются записи, добавляемые, удаляемые или изменяемые в основных таблицах другими пользователями. Этот тип объектов соответствует динамическому указателю ODBC (только в рабочей области ODBCDirect).
При создании нового объекта Recordset тип объекта определяется с помощью аргумента тип метода OpenRecordset.
В рабочей области Microsoft Jet, если аргумент тип не задан, механизм DAO пытается создать тип объекта Recordset с максимально возможными функциональными характеристиками, начиная с таблицы. Если таблицу создать не удается, делается попытка создать динамический набор записей, затем статический набор записей и наконец, набор записей с последовательным доступом.
В рабочей области ODBCDirect, если аргумент тип не задан, механизм DAO пытается создать тип объекта Recordset, обеспечивающий максимально быстрое выполнение запроса, начиная с набора записей с последовательным доступом. Если объект этого типа создать невозможно, механизм DAO делает попытку создать статический набор записей, затем динамический набор записей, и наконец, объект Recordset динамического типа.
При создании объекта Recordset на основе неприсоединенного объекта TableDef в рабочей области Microsoft Jet создаются объекты Recordset типа таблицы. На основе присоединенных таблиц или таблиц в базах данных ODBC, подключенных к ядру Microsoft Jet, могут быть созданы только объекты Recordset типа динамического набора записей или статического набора записей.
Новый объект Recordset автоматически добавляется в семейство Recordsets при открытии объекта и автоматически удаляется из семейства при закрытии объекта.
При описании в программе объекта Recordset и содержащего его объекта Database с помощью объектных переменных необходимо обеспечить, чтобы эти переменные имели одинаковую область определения или одинаковое время жизни. Например, при описании общей переменной, представляющей объект Recordset, необходимо обеспечить, чтобы переменная, представляющая объект Database, содержащий объект Recordset, также была общей, либо описать эту переменную в процедуре Sub или Function с ключевым словом Static.
В приложении допускается определение произвольного числа объектных переменных, представляющих объект Recordset. Разные объекты Recordset могут иметь доступ к одним таблицам, запросам и полям без возникновения конфликтов.
Объекты Recordset типа динамического набора записей, статического набора записей и статического набора записей с последовательным доступом сохраняются в локальной оперативной памяти. Если в оперативной памяти не хватает места, ядро базы данных Microsoft Jet сохраняет избыточные данные в каталоге временных файлов на диске. Если и этот объем окажется недостаточным, возникает перехватываемая ошибка.
Объекты Recordset по умолчанию помещаются в семейство Fields. Используемым по умолчанию свойством объекта Field является свойство Value (значение). Эти используемые по умолчанию характеристики позволяют упростить программу.
Если созданный объект Recordset содержит записи, то текущей записью становится первая запись. Если записи в объекте отсутствуют, свойство RecordCount получает значение 0, а свойства BOF и EOF значение True.
Изменить положение указателя текущей записи позволяют методы MoveNext, MovePrevious, MoveFirst и MoveLast. Для объектов Recordset типа статического набора записей с последовательным доступом поддерживается только метод MoveNext. При выполнении цикла по всем записям с помощью методов Move («прохода» по объекту Recordset) свойства BOF и EOF используются для проверки начальной и конечной границы объекта Recordset.
Для объектов Recordset типа динамического статического набора записей в рабочей области Microsoft Jet допускается также использование методов группы Find, таких как FindFirst, позволяющих найти запись, удовлетворяющую определенным условиям. Если запись не обнаруживается, свойство NoMatch получает значение True. Для объектов Recordset типа таблицы допускается сканирование записей с помощью метода Seek.
Тип созданного объекта Recordset задается свойством Type, а возможность изменения записей в объекте определяется свойством Updatable.
Сведения о структуре основной таблицы, такие как имя и тип данных каждого поля (объект Field) и индекса (объект Index) сохраняются в объекте TableDef.
При ссылках на объект Recordset используют его порядковый номер в семействе или значение свойства Name (имя):
Для одного источника данных или базы данных допускается открытие нескольких объектов Recordset, что приводит к образованию повторяющихся имен в семействе Recordsets. В этом случае необходимо присваивать объекты Recordset объектным переменны
м и ссылаться на них по именам переменных.
Пример
Следующая программа открывает объект Recordset типа статического набора записей с последовательным доступом, демонстрирует его доступность только для чтения, а затем осуществляет проход по объекту Recordset с помощью метода MoveNext.
Базы данных и ADO Перемещение по Recordset в ADO/VBA
9.5.3 Перемещение по Recordset
Перемещение по Recordset в ADO/VBA, свойства BOF, EOF, Bookmark, методы Move(), MoveNext(), MovePrevious(), MoveFirst(), MoveLast(), Find(), Seek()
После того, как объект Recordset создан, нам необходимо выполнять с ним различные операции. Самое простое действие, с которого мы начнем — перемещение по объекту Recordset.
В Recordset всегда имеется ограниченное количество записей (столько, сколько мы получили с источника). Изначально курсор устанавливается на первую запись в Recordset (убедиться в этом можно при помощи свойства AbsolutePosition). Однако, если мы дадим команду MovePrevious() (один раз), ошибки не произойдет (если мы попробуем выполнить команду MovePrevious() второй раз, то возникнет ошибка). AbsolutePosition вернет загадочное значение (-2). Связано это с тем, в Recordset перед первой записью, полученной с источника помещается специальная запись BOF (от Begin Of File, хотя никаких файлов, конечно же, нет). Проверить, находимся ли мы на этой специальной записи, можно при помощи свойства BOF. Например, такой код:
вернет нам вначале False, а затем True.
Точно так же после последней записи в Recordset находится специальная запись EOF (End Of File). Проверить, не находится ли курсор на ней, можно при помощи аналогичного одноименного свойства EOF.
Иногда бывает так, что сразу после открытия Recordset и BOF, и EOF одновременно возвращают True. Объяснение такой ситуации очень простое — в Recordset с источника по каким-то причинам не вернулось ни одной записи. Рекомендуется во избежание неожиданностей предусматривать сразу после открытия Recordset проверку на наличие в нем записей.
После того, как мы определились с нашей текущей позицией в Recordset, необходимо разобраться с тем, как можно по нему перемещаться. Проще всего это делать при помощи методов Move…(). Вот их краткое описание:
- Move() — этот метод принимает два параметра: NumRecords — на сколько записей необходимо переместиться (это число может быть и отрицательным, что значит — переместиться назад) и второй параметр — необязательный — имя закладки, с которой нужно начать перемещение. Можно использовать три встроенные закладки: для текущей, первой и последней записи. Если имя закладки не указано, то перемещение начинается с текущей позиции.
- MoveFirst(), MoveLast(), MoveNext() и MovePrevious() — назначение этих методов понятно из названия: перемещение на первую, последнюю, следующую и предыдущую запись соответственно.
Необходимо отметить, что перемещение назад (при помощи MovePrevious() или Move() с отрицательным значением) для курсора, открытого как Forward-only, может привести к совершенно непредсказуемому результату (в зависимости от источника данных) — от ошибки до перехода на случайную запись.
Чаще всего для прохода по всем записям используется такой нехитрый алгоритм:
‘что-то делаем с каждой записью, например,
‘получаем значение нужного поля
Если нужно напрямую перепрыгнуть на нужную запись, можно использовать методы Find() и Seek().
Метод Find() предназначен для поиска по значению одного столбца. Он принимает в качестве параметра критерий поиска, насколько нужно отступить от исходной позиции, направление поиска и откуда нужно начать поиск. Очень удобно, что при определения критерия поиска можно использовать оператор Like с подстановочными символами. При обнаружении нужной записи метод Find() переставляет курсор на найденную запись, если же запись не обнаружена, то курсор устанавливается на EOF (или BOF, если поиск был назад). Например, чтобы найти все немецкие фирмы в нашем Recordset для таблицы Customers, можно использовать код вида
rs.Find «country = ‘Germany'»
Do While Not rs.EOF
Debug.Print «Название фирмы: «; rs.Fields(«CompanyName»)
rs.Find «country = ‘Germany'», 1, adSearchForward, mark
В этом примере используются еще незнакомые нам объекты Fields и Bookmark, но их назначение понятно: объект Field нужен нам, чтобы вывести название фирмы, а объект Bookmark — чтобы продолжить поиск позиции +1 от последней найденной записи.
Метод Seek() отличается от метода Find() тем, что они ищет значение по индексу (объект Index для Recordset создается либо программным способом, либо автоматически — если на таблицу, на основе который был создан Recordset, было наложено ограничение Primary Key). Этот метод работает только для серверных курсоров с типом команды TableDirect, и поэтому к использованию не рекомендуется.
Теперь — о еще одном свойстве, которое может сильно помочь в перемещении по Recordset (и которое уже встречалось в наших примерах) — свойстве Bookmark. Это свойство очень простое — достаточно присвоить его значение переменной типа Variable, когда указатель стоит в нужном месте Recordset, а затем присвоить этому свойству значение этой переменной, чтобы опять на него вернуться — как в нашем примере с поиском.
Вообще говоря, значение, которое возвращает это свойство, изначально совпадает с номером записи в Recordset, однако Microsoft честно предупреждает, что таким способом пользоваться закладкой очень не рекомендуется — если курсор стоит в одном и том же месте, свойство Bookmark может возвращать разные значения.
Использование объекта Recordset.
Recordset— это объект, который используется для выполнения операций с записями. Семейство Recordsets содержит все открытые объекты Recordset в открытой базе данных. При закрытии объекта Recordset он удаляется из памяти и из семейства Recordsets. Объекты Database, TableDef и QueryDef включает метод OpenRecordset.
Recordset можно открыть, указав в методе OpenRecordsetобъекта Database название соответствующей таблицы или воспользовавшись методом OpenRecordsetобъекта TableDef:
Dim dbsNorthwind As Database
Dim rstEmployees As Recordset
Set dbsNorthwind = OpenDatabase(«Northwind.mdb»)
Set rstEmployees = dbsNorthwind.OpenRecordset( «Employees», dbOpenDynaset)
После открытия объекта Recordset необходимо определить, какие записи доступны. Если в Recordset нет ни одной записи, то его свойства BOF(Beginning Of File — начало файла) и EOF(End Of File — конец файла) установлены в True. Если EOF установлено в False, то Recordset имеет хотя бы одну запись. Если записи существуют, то при открытии Recordset будет выполнено позиционирование на первой записи.
Используя метод Move, можно построить цикл, обращающийся к каждой следующей записи в объекте Recordset. Метод MoveLastиспользуется для позиционирования к последней записи Recordset. Для перемещения к предыдущей записи используется метод MovePrevious, пока свойство BOF не будет установлено в True. Метод MoveFirstможет быть использован для позиционирования к первой записи.
Метод Editинформирует Jet о том, что в текущей записи происходят изменения. При использовании метода Updateсделанные изменения вносятся в таблицу.
Для добавления записей используйте метод AddNew. Этот метод применяется в комплексе с методом Editпри добавлении новых записей. Как и в случае с методом Edit, записи будут присоединены к таблице после применения метода Update.
Для удаления текущей записи используйте метод Delete.
После того как обработка объекта Recordset будет завершена, закройте его, воспользовавшись методом Close. Этот метод удаляет объект Recordset из семейства Recordsets и делает объект Recordset недействительным.
Примеры использования методов DAO .
Sub Find ()
‘———————————————————
‘ Поиск записей в таблице » tblPeoples » Будем искать записи, у которых в поле LastName находиться значение «Иванова» и печатать в окне отладки ID _ People найденных записей и их количество Проход по всей таблице. ЭТОТ МЕТОД НЕ ЯВЛЯЕТСЯ ОПТИМАЛЬНЫМ.
‘———————————————————
Dim db As Database
Dim rs As Recordset
Dim str As String
Dim lngRecordCount As Long
‘Счетчик найденных записей
Set db = CurrentDb
Set rs = db . OpenRecordset (» tblPeoples «, dbOpenDynaset )
str = «»
lngRecordCount = 0
If rs . RecordCount <> 0 Then
rs . MoveFirst
Do Until rs . EOF
‘Если текущая запись удовлетворяет условию.
If rs ![ LastName ] = «Иванова» Then
‘Инкримируем счетчик найденных записей
lngRecordCount = lngRecordCount + 1
str = str & rs ![ ID _ People ] & «, »
End If
rs . MoveNext
Loop
str = str & vbCrLf & «Всего найдено записей: » & _
lngRecordCount
Else
str = «Таблица «» tblPeoples «» не содержит записей.»
End If
Debug . Print str
rs. Close
db. Close
End Sub
Option Compare Database
Option Explicit
Sub Cycle01_1()
‘———————————————————
‘ Цикл по записям таблицы «tblPeoples» от начала до конца
‘———————————————————
‘База данных
Dim db As Database
‘Набор записей
Dim rs As Recordset
‘Строка
Dim str As String
‘Количество записей в наборе записей
Dim lngRecordCount As Long
‘ db — текушая база данных
Set db = CurrentDb
Set rs = db.OpenRecordset(«tblPeoples», dbOpenDynaset)
‘ rs — набор записей на основе таблицы «tblPeoples»
‘ При инициализации набора записей мы можем точно определить, есть ли в этом наборе записи или нет.
‘ Свойство » RecordCount » набора записей посли его инициализации, по идее, должна сождержать количество записей набора, однако это не так. Если в наборе есть записи это свойство отлично от нуля, но не содержит их количество. Для определения количества записей необходимо перейти на последнюю запись набора, и после этого в свойстве » RecordCount » будет находиться количество записей набора. Если в наборе rs есть записи.
If rs . RecordCount <> 0 Then
rs . MoveLast
‘ Переходим на последнюю запись (чтобы » RecordCount » содержало верное значение)
lngRecordCount = rs . RecordCount
‘ Считываем количество записей в переменную
rs . MoveFirst ‘Переходим на первую запись набора
‘ Заполняем текстовую переменную str количеством записей
str = «Количество записей в таблице «» tblPeoples «»: » & lngRecordCount & vbCrLf
‘Свойство EOF ( End Of File ) набора записей становиться истинным ПОСЛЕ последней ‘записи набора,точно как и свойство BOF ( Begin Of File ) становиться истинным ПЕРЕД ‘первой записью набора. Цикл «Пока не кончатся записи в наборе rs »
Do Until rs . EOF
‘Добавляем в переменную str имнена полей, их
‘ значения и символ перевода строки
str = str & » ID _ People : » & rs ![ ID _ People ] & vbCrLf
str = str & » ID _ RecordStatus : » & rs ![ ID _ RecordStatus ] & vbCrLf
str = str & » LastName : » & rs ![ LastName ] & vbCrLf
str = str & » FirstName : » & rs ![ FirstName ] & vbCrLf
str = str & » MiddleName : » & rs ![ MiddleName ] & vbCrLf
str = str & » PeopleSex : » & rs ![ PeopleSex ] & vbCrLf
str = str & » BirthDate : » & rs ![ BirthDate ] & vbCrLf
str = str & «————» & vbCrLf
rs . MoveNext
‘Переходим на следующую запись
Loop
‘Конец цикла
Else
‘Если записей нет.
‘ Заполняем текстовую переменную str сообщением об отсутствии записей
str = «Таблица «» tblPeoples «» не содержит записей.»
End If
‘Печатаем содержимое переменной str в окне отладки
Debug . Print str
rs . Close
‘Закрываем переменную набора записей
db . Close
‘Закрываем переменную базы данных
End Sub
Программирование в формах.
Определяя имя для поля, элемента управления или объекта, полезно проверить, не совпадает ли это имя с именем свойства или другого элемента, используемого Microsoft Access; в противном случае иногда могут возникать неверные результаты. Например, при ссылке на значение поля «Name» в таблице «NameInfo» с использованием конструкции NameInfo.Name будет возвращаться значение свойства таблицы Имя (Name), а не значение поля «Name».
Простейшим способом обойти неопределенность в именах является использование оператора !вместо оператора .(точка) в ссылках на значения полей, элементов управления и объектов:
Пример запроса, созданного как текстовая строка плюс значения текстовых переменных. Запрос выбирает из таблицы «_ v 2 » в таблицу «_ v 4» те записи, значение поля nn в которых больше нуля и меньше значения переменной целого типа var _ numb .
Dim S As String
S = «SELECT * INTO [_v2] FROM [_v4] WHERE (([_v4].nn 0))»
Классическая фраза, которой приходится завершать функцию, если в результате ваших действий значения некоторых полей в форме должны измениться, а этого почему-то не видно:
Работа с элементом «поле со списком»(Элемент управления на странице доступа к данным, щелчок по кнопке-стрелке которого приводит к раскрытию списка, в котором можно выбрать значение или ввести его прямо в поле с клавиатуры).
Как в Access на VBA выгрузить Recordset в Excel?
Всем привет! Материал сегодня будет посвящен рассмотрению возможности Access выгружать Recordset в Excel на VBA. Данный способ достаточно простой и предполагает использование Recordset как формы, так и специально созданного объекта.
Ранее мы с Вами уже рассматривали возможность выгрузки данных из Access в Excel в материале «Выгрузка данных из Access в шаблон Word и Excel», но там мы использовали специально созданный шаблон, что не совсем удобно, если например, нам необходимо выгрузить просто набор данных с заголовками полей.
Также если кого интересует, недавно мы рассматривали возможность выгрузки данных из базы MS SQL Server в формат CSV (текстовый файл с разделителями) с помощью VBA Access в материале «Экспорт данных в CSV файл из Microsoft SQL Server, используя Access 2003».
Сейчас я покажу простой пример реализации возможности выгружать наборы данных с заголовками из базы MS SQL Server средствами VBA Access в Excel.
Весь смысл сводится в использование метода CopyFromRecordset, который позволяет переносить Recordset в Excel в том виде, какой он и есть, т.е. в виде таблицы. Единственное что нам необходимо будет сделать, это выгрузить заголовки, чтобы было понятней, что за данные содержатся в той или иной колонке.
Итак, давайте приступать и для начала рассмотрим исходные данные.
Примечание! В качестве примера источником данных у меня будет выступать MS SQL Server 2012 Express, а в качестве клиента ADP проект Access 2003. Также на компьютере клиенте установлен Microsoft Office 2010.
Исходные данные
Допустим, на сервере у нас есть таблица TestTable.
И она содержит следующие данные.
Также допустим, что в ADP проекте Access у нас есть форма, источником данных которой выступает наша тестовая таблица TestTable.
Код VBA для выгрузки Recordset формы в Excel
Сначала давайте рассмотрим пример выгрузки объекта Recordset формы в Excel. Для этого добавляем на форму кнопку, для примера я ее назвал RSExportInExcel. В обработку события нажатие кнопки вставляем следующий код, я его прокомментировал:
Сохраняем изменения и пробуем нажать на кнопку. В итоге у нас запустится Excel, а в нем будут необходимые нам данные.
Примечание! Свойства HorizontalAlignment и VerticalAlignment могут не работать, если на компьютере не установлен Microsoft Office 2010, поэтому в случае возникновения ошибок связанных с этими свойствами просто закомментируйте их.
Код VBA для выгрузки объекта Recordset в Excel
Теперь давайте напишем код, который позволяет выгружать объект Recordset, данные которого получены, скажем с помощью запроса к базе данных. Для этого добавьте еще одну кнопку (я ее назвал RSExportInExcel2) и вставьте немного модифицированный код:
Снова сохраняем и пробуем нажать на кнопку, в итоге у нас получится точно такая же выгрузка, как и чуть ранее, только сейчас в качестве источника данных Recordset у нас может выступать любой запрос, а не только данные формы.
На этом у меня все! Надеюсь, материал был Вам полезен, пока!
Свойство Recordset (Набор записей)
Применение
Возвращает или задает объект ADO Recordset или DAO Recordset, который представляет собой источник записей для указанной формы, отчета, списка или поля со списком. Значение данного свойства доступно для чтения и записи.
выражение (обязательно). Выражение, возвращающее один из объектов из списка «Применение».
Замечания
Свойство Recordset (Набор записей) возвращает объект набора записей, который является источником данных, просматриваемых в форме, отчете, списке или поле со списком. Если форма основана, например, на запросе, ссылка на свойство Recordset эквивалентна клонированию объекта Recordset с помощью того же запроса. Однако в отличие от использования свойства RecordsetClone (Копия набора записей), назначение в качестве текущей другой записи в наборе записей, возвращаемом свойством Recordset формы, также задает текущую запись этой формы.
Это свойство можно задать только с помощью кода Visual Basic для приложений (VBA).
Доступность для чтения и записи свойства Recordset определяется типом набора записей (ADO или DAO) и типом данных (Access или SQL), которые содержатся в нем.
Чтение и запись
Чтение и запись
Чтение и запись
В следующем примере выполняется открытие формы, открытие набора записей и привязка формы к набору записей путем указания для свойства Recordset только что созданного объекта Recordset.
Global rstSuppliers As ADODB.RecordsetSub MakeRW()DoCmd.OpenForm «Suppliers»Set rstSuppliers = New ADODB.RecordsetrstSuppliers.CursorLocation = adUseClientrstSuppliers.Open «Select * From Suppliers», _CurrentProject.Connection, adOpenKeyset, adLockOptimisticSet Forms(«Suppliers»).Recordset = rstSuppliersEnd Sub
Свойство Набор записей служит для следующих целей:
Связывание нескольких форм с общим набором данных. Это позволяет синхронизировать несколько форм. Например:
Set Me.Recordset = Forms!Form1.Recordset
Использование методов, не имеющих непосредственной поддержки в формах, вместе с объектом Recordset. Например, свойство Recordset можно использовать вместе с методами ADO Find или DAO Find в пользовательском диалоговом окне для поиска записи.
Добавление в транзакцию (для которой можно выполнить откат) набора изменений, влияющих на несколько форм.
Изменение свойства Recordset также может привести к изменению свойств RecordSource (Источник записей), RecordsetType (Тип набора записей) и RecordLocks (Блокировка записей). Кроме того, некоторые связанные с данными свойства могут быть переопределены, например свойства Filter (Фильтр), FilterOn (Фильтр включен), OrderBy (Порядок сортировки) и OrderByOn (Сортировка включена).
Вызов метода Requery набора записей формы (например, Forms(0).Recordset.Requery ) может привести к превращению формы в свободную. Чтобы обновить данные в форме, привязанной к набору записей, следует задать для свойства RecordSource (Источник записей) формы само это свойство ( Forms(0).RecordSource = Forms(0).RecordSource ).
Если форма привязана к набору записей, при использовании команды «Фильтр по форме» возникает ошибка.
Пример
В следующем примере свойство Recordset используется для создания копии объекта Recordset из текущей формы. Затем в окне отладки печатаются имена полей.
В следующем примере свойство Recordset и объект Recordset используются для синхронизации набора записей с текущей записью формы. При выборе в поле со списком названия организации для поиска ее записи используется метод FindFirst, вызывающий отображение найденной записи в форме.
Следующий код помогает определить, какой тип набора записей возвращается свойством Recordset при разных условиях.