Изменение данных

advertisement
Глава 9: Работа с наборами данных Recordset
Интерфейс пользователя Access Microsoft обеспечивает много гибких возможностей для
пользователей прикладной программы, чтобы отображать, управлять, и модифицировать данные.
Иногда, однако, ваша прикладная программа должна брать прямой контроль над данными, чтобы
выполнить определенную задачу.
VBA вместе с объектами доступа к данным обеспечивает полный язык манипулирования данными,
который используется для нахождения, отображения, модификации), удаления и добавления
данных. Эта глава представляет основные правила манипулирования данными с объектами доступа
к данным Recordset, QueryDef и TableDef.
Использование объекта Recordset
Вы используете объекты Recordset, чтобы управлять данными в базе данных. Три типа объектов
Recordset - table, dynaset, и snapshot - значительно отличаются от друг друга.
Х
Объект Recordset тип table обращается к локальной таблице в текущей базе данных или к
связанной таблице во внешней базе данных, созданной с Microsoft Access или Jet engine
Microsoft. Вы можете выполнять некоторые операции типа сортировки, индексации и
использования метод Seek( Установки) только на объектах Recordset типа table. Find методы
не могут использоваться в этом типе.
Х
Объект Recordset типа dynaset обращается к локальным или связанным таблицам или к
результатам запросов. С dynaset Вы можете извлекать данные для модификации из больше
чем одной таблицы, включая связанные таблицы из других баз данных.
Х
Объект Recordset типа snapshot подобен dynaset, за исключением того, что содержит
фиксированную копию данныхи не может модифицироваться. Snapshot содержит копию
выбранных записей в таблице или результате запроса, в то время как dynaset содержит только
набор косвенных ссылок к записям. Поэтому snapshot создает меньшее количество обработки
чем другие типы, он может открываться быстрее, особенно при работе с ODBC - данными.
Тип Recordset, который Вы используете, зависит от того, что Вы хотите делать и хотите ли Вы
изменять или просто рассматривать данные. Например, если Вы должны сортировать данные или
работать с индексами, используйте table. Поскольку данные индексированы, объекты Recordset типа
table обеспечивают самый быстрый способ поиска.
Если Вам необходимо модифицировать набор записей, выбранных запросом, используйте dynaset.
Если тип table недоступен в некоторой ситуации, и Вы только должны просмотреть набор записей,
использование snapshot значительно повысит эффективность.
Создание Переменной Recordset
OpenRecordset метод - основной метод создания объектной переменной Recordset. Для этого сначала
объявляете переменную типа Recordset, и затем устанавливаете переменную к объекту,
возвращенному из OpenRecordset метода.
OpenRecordset метод доступен для объектов Database, TableDef, и QueryDef. Также доступно для
объектов Recordset, чтобы новые объекты Recordset могли быть созданы на основе существующих.
Синтаксис OpenRecordset метода для объектов Database:
Set переменную = database.OpenRecordset (источник [, тип [, опции]])
Синтаксис OpenRecordset метода для всех других типов объектов:
Set переменную = object.OpenRecordset (тип [, опции])
Переменная параметр - имя нового объекта Recordset. Объектный параметр - Database, TableDef,
QueryDef, или существующий объект Recordset, из которого Вы создаете новый объект Recordset.
Microsoft Jet Engine использует параметр источник только для объектов Recordset, созданных из
объектов Database. Источник - существующий объект TableDef или QueryDef в базе данных или
строка запроса SQL. Объекты TableDef, QueryDef и Recordset автоматически используются как
источник.
Параметр типа - внутренняя константа, которая определяет вид Recordset, который Вы хотите
создать. Доступные константы типа:

DbOpenTable

DbOpenDynaset
 DbOpenSnapshot
Если Вы не определяете константу типа, engine базы данных выбирает самый эффективный
доступный тип, в зависимости от источника данных. Параметр опций состоит из одной или более
внутренних констант, которые определяют многопользовательскую достижимость данных.
Создание Recordset из Таблицы
Метод, который Вы используете, чтобы создать объект Recordset из основной таблицы, зависит на
том, ли таблица является локальной для текущей(актуальной) базы данных или - связанная таблица
в другой базе данных. Следующее обсуждение объясняет различия и обеспечивает примеры для
каждого типа основной таблицы.
Из Local Таблицы
Следующий пример использует OpenRecordset метод создать объект Recordset типа таблицы для
таблицы в текущей базе данных.
Dim dbsCurrent As Database, rstCustomer As Recordset
Set dbsCurrent = CurrentDB()
Set rstCustomer = dbsCurrent.OpenRecordset("Customer")
Обратите внимание, что Вы не должны использовать dbOpenTable константу, чтобы создать
Recordset типf table. Если Вы опускаете константу типа, engine базы данных выбирает, самый
высоко эффективный доступный тип Recordset, в зависимости от объекта, внутри которого
Recordset создан источник данных. Поскольку тип table доступен, когда Вы открываете Recordset из
локальной таблицы, engine базы данных использует его.
Из Связанной Таблицы отличного формата
Следующий пример создает объект Recordset типа dynaset для связанной таблицы Paradox версии
3.x. Поскольку тип таблицы не доступен, когда Вы открываете Recordset из связанной таблицы в
базе данных не- Access, engine базы данных выбирает следующий наиболее эффективный тип,
открывая Recordset dynaset-тип.
Dim dbsCurrent As Database
Dim tdfNonJetLinked As TableDef, rstTableData As Recordset
' Get current database.
Set dbsCurrent = CurrentDB()
Set tdfNonJetLinked = dbsCurrent.CreateTableDef("PDXAuthor")
' Connect to Paradox table Author in database C:\PDX\Publish.
tdfNonJetLinked.Connect = "Paradox 3.X;DATABASE=C:\PDX\Publish"
tdfNonJetLinked.SourceTableName = "Author"
' Attach table.
dbsCurrent.TableDefs.Append tdfNonJetLinked
' Create a dynaset-type Recordset for the table.
Set rstTableData = tdfNonJetLinked.OpenRecordset()
Использование Индекса в Recordset типа table
Вы можете рассматривать записи в объекте Recordset типа таблицы, устанавливая Index свойство.
Объект Index в семействе Index объекта Recordset основной таблицы может быть определен в Index
свойстве.
2
Следующий пример иллюстрирует тип таблицы Recordset основанный на таблице Customers,
используя существующий Index с именем City.
Dim dbsCurrent As Database, rstTableData As Recordset
Set dbsCurrent = CurrentDB()
Set rstTableData = dbsCurrent.OpenRecordset("Customers", dbOpenTable)
rstTableData.MoveFirst
' Move to first record.
MsgBox rstTableData!CompanyName
' First record with no index set.
rstTableData.Index = "City"
' Select City index.
rstTableData.MoveFirst
' Move to first record.
MsgBox rstTableData!CompanyName
Вы должны установить Index свойство перед некоторыми операциями, типа метода Seek. Если Вы
устанавливаете Index свойство, который не существует, происходит ошибка во время выполнения
программы. Если Вы хотите сортировать записи согласно индекса, который не существуют, то
создайте сначала индекс, или создайте dynaset- или тип snapshot Recordset, который возвращает
записи в определенной последовательности сортировки.
Создание Recordset на основе Запроса
Вы можете также создавать объект Recordset, основанный на запросе выбора. В следующем
примере, Customer List - существующий запрос выбора в текущей базе данных.
Dim dbsCurrent As Database, rstCustomers As Recordset
Set dbsCurrent = CurrentDB()
Set rstCustomers = dbsCurrent.OpenRecordset("Customer List")
Примечание Вы не может создавать Recordset тип table основанный на запросе выбора.
Если подходящий запрос выбора еще не существует, OpenRecordset метод также принимает строку
SQL вместо имени запроса. Предыдущий пример может быть переделан следующим образом:
Dim dbsCurrent As Database, rstCustomers As Recordset
Dim strQuerySQL As String
Set dbsCurrent = CurrentDB()
strQuerySQL = "SELECT * FROM Customers ORDER BY CustomerID;"
Set rstCustomers = dbsCurrent.OpenRecordset(strQuerySQL)
Обратите внимание, когда Вы создаете объект Recordset использование запроса выбора или строки
SQL, ваш код не продолжается, пока запрос не возвращает первую строку в Recordset.
Создание Recordset на основе формы
Чтобы создавать объект Recordset, основанный на форме Microsoft Access, Вы не должны
использовать OpenRecordset метод. но можете использовать RecordsetClone свойство формы.
RecordsetClone свойство - dynaset-тип Recordset, который обращается к тому же самому основному
запросу или данным как форма. Если форма основана на запросе, то RecordsetClone свойство эквивалент создания dynaset с тем же самым запросом. Вы можете использовать RecordsetClone
свойство, когда Вы хотите применять метод, который не может использоваться с формами, типа
FindFirst метода. RecordsetClone свойство обеспечивает доступ к всем методам и свойствам,
которые Вы можете использовать с dynaset. Синтаксис для RecordsetClone свойство:
Set recordsetname = form.RecordsetClone
Параметр form - имя формы Access Microsoft. Следующий пример показывает, как назначить объект
Recordset к записям в форме Orders.
Dim rstOrders As Recordset
Set rstOrders = Forms!Orders.RecordsetClone
Поскольку Microsoft Jet engine базы данных выбирает заданный по умолчанию тип для источника
данных, Вы не должны определить тип Recordset. Вы можете указывать различный тип, определяя
параметр типа в OpenRecordset методе.
3
Следующий список описывает доступные типы и заданный по умолчанию тип, в зависимости от
того, как Вы открываете объект Recordset:
Х
OpenRecordset метод из объекта Database:
Set rstNew = dbsCurrent.OpenRecordset (" Источник Данных ")
Все три типа доступны. Заданный по умолчанию тип - table только, если Источник Данных основная таблица, локальная для базы данных. Иначе, доступен только dynaset и snapshot, и
dynaset - заданный по умолчанию тип.
Х
OpenRecordset метод из объекта TableDef:
Set rstNew = tdfTableData.OpenRecordset
Все три типа доступны. Заданный по умолчанию тип - table, если tdfTableData обращается к
таблице в базе данных Jet Microsoft или к ISAM datatabse открытый непосредственно. Если
tdfTableData находится в базе данных ODBC или - связанная таблица во внешней базе
данных, заданный по умолчанию тип - dynaset; и dynaset и snapshot доступен.
Х
OpenRecordset метод из объекта QueryDef:
Set rstNew = qdfQueryData.OpenRecordset
Только dynaset и snapshot доступен, и dynaset - заданный по умолчанию тип.
Х
OpenRecordset метод из существующего объекта Recordset:
Set rstNew = rstExisting.OpenRecordset
Только dynaset и snapshot доступен. Заданный по умолчанию тип - тип существующего
Recordset.
Х
RecordsetClone свойство формы Access Microsoft:
Set rstNew = Forms! FrmAccessForm.RecordsetClone
Будет всегда создаваться тип имитируемого Recordset; никакие другие типы не доступны.
Сортировка и Фильтрация Записей
Если Вы не определяете, что сортировка выполняется для объекта Recordset, Вы не можете быть
уверены, что записи появятся в определенном порядке. Большую чась времени, однако, Вы
необходимо отыскивать записи. Например, Вы можете рассматривать счета, размещаемые по
увеличению номера счета или отыскивать записи служащих в алфавитном порядке.
Самые быстрые и самые простые способы сортировки и фильтрации данных в Recordset при
открытии Recordset из объекта QueryDef или сохраненного запроса выполняются при
использовании утверждения SQL как источника Recordset при использовании SQL Where и
предложения ORDER BY в запросе.
Следующий пример открывает объект Recordset, который использует утверждение SQL, чтобы
отыскивать и сортировать записи, используя Where и предложения ORDER BY.
Dim dbsCurrent As Database, rstManagers As Recordset
Set dbsCurrent = CurrentDB()
Set rstManagers = dbsCurrent.OpenRecordset("SELECT FirstName, " & _
"LastName FROM Employees WHERE Title = 'Manager' " & _
"ORDER BY LastName")
Один недостаток этого типа запроса состоит в том, что он должен быть перетранслирован, каждый
раз выполнении. Если этот запрос должен использоваться часто, Вы можете улучшать
эффективность, создавая сохраненный запрос, использующий то же самое утверждение SQL, и
затем открывать объект Recordset вместо запроса, как показано в следующем примере.
Dim dbsCurrent As Database, rstManagers As Recordset
4
Set dbsCurrent = CurrentDB()
Set rstManagers = dbsCurrent.OpenRecordset("Managers")
Сортировка Записей в Существующем Recordset
В некоторых случаях необходимо сортировать записи в существующем Recordset, без вторичного
использования первоначального источника данных. Например, Вы можете захотеть, чтобы
конечные пользователи были способны сами сортировать записи, возвращенные из сохраненного
запроса без изменения сохраненного запроса. Вы не можете изменять порядок сортировки
существующего dynaset или snapshot. В место этого, Вы должны создать второй объект Recordset с
записями в необходимом порядке. Чтобы создавать dynaset основанный на таблице Orders, которая
отсортирована согласно полю ShipCountry, используют свойство Sort, как показано в следующем
примере.
Dim dbsCurrent As Database
Dim rstOrders As Recordset, rstSorted As Recordset
Dim strSortOrder As String
Set dbsCurrent = CurrentDB()
' Create dynaset.
Set rstOrders = dbsCurrent.OpenRecordset("", dbOpenDynaset)
' Prompt user for order by expression.
strSortOrder = InputBox("Enter an SQL ORDER BY expression")
rstOrders.Sort = strSortOrder
' Set sort order.
Set rstSorted = rstOrders.OpenRecordset()
' Create new dynaset.
Выражение, которое Вы назначаете к свойству Sort, должно быть имеющее силу выражение SQL
ORDER BY, без SORT слова - обычно одиночное имя поля, типа PostalCode в следующем примере.
Если Вы хотите сортировать по выражению, состоящему из более чем одно поле, вносите в список
поля по через запятую.
RstOrders.Sort = " Contry, PostalCode "
Заданная по умолчанию последовательность сортировки для свойства Sort –по возрастанию, но Вы
можете сортировать по убыванию, добавляя DESC.
RstOrders.Sort = " OrderDate DESC "
Хотя Вы не можете изменять порядок сортировки для существующего dynaset- или типа snapshot
Recordset, Вы можете создавать новый Recordset и назначать его к первоначальной переменной.
Set rstOrders = dbsCurrent.OpenRecordset("Employees", dbOpenDynaset)
rstOrders.Sort = "LastName, FirstName"
Set rstOrders = rstOrders.OpenRecordset()
Если Вы сортируете Recordset, используя эту методику, единственый способ ввести эффект
сортировки - освежить оригинал Recordset.
Может быть более эффективно создать второй объект Recordset с условиями в одном шаге. Как
правило, когда Вы знаете, кокие данные Вы хотите выбирать, обычно лучше создать второй
Recordset использование строки SQL. Следующий пример показывает Вам, как создать только один
объект Recordset.
Dim dbsCurrent As Database, rstOrders As Recordset
Set dbsCurrent = CurrentDB()
Set rstOrders = dbsCurrent.OpenRecordset("SELECT * FROM Orders " & _
"ORDER BY ShipCountry")
Фильтрация существующего Recordset
Аналогично, для существущего Recordset может быть установлено свойство Filter для
фильтрации сзаписей. Например, можно фильтровать записи, содержащий все записи, так что
второй набор данных будет содержать записи из United Kingdom.
Dim dbsCurrent As Database
Dim rstOrders As Recordset, rstFiltered As Recordset
5
Dim strFilterCriteria As String
Set dbsCurrent = CurrentDB()
' Create dynaset.
Set rstOrders = dbsCurrent.OpenRecordset("Orders", dbOpenDynaset)
' Prompt user for
' filter criteria.
strFilterCriteria = InputBox("Enter an SQL WHERE expression")
rstOrders.Filter = strFilterCriteria
' Set filter
' condition.
Set rstFiltered = rstOrders.OpenRecordset()
' Create filtered
' dynaset.
Обратите внимание, чтобы изменить содержание rstOrders dynaset, Вы должны установить свойство
Filter и затем открывать второй объект Recordset из rstOrders.
Выражение, которое Вы используете, чтобы установить свойство Filter, может быть сложное
выражение, содержащее сложные условия.
rstOrders.Filter = "Region = 'WA' And Status = 'A'"
Следующий пример иллюстрирует, как Вы можете фильтровать результаты запроса, именованного
Sales в течение 1994 так, чтобы только продукты в категории 'Beverages' (Напитков) были
включены.
Dim dbsCurrent As Database, rst1994Sales As Recordset
Set dbsCurrent = CurrentDB()
Set rst1994Sales = dbsCurrent.OpenRecordset("Sales for 1994")
rst1994Sales.Filter = "CategoryName = 'Beverages'"
Set rst1994Sales = rst1994Sales.OpenRecordset()
Предшествующий пример показывает методику использования существующего объекта Recordset,
чтобы создать второй, отфильтронный dynaset. Чтобы освежать нефильтрованную версию dynaset,
Вы должны освежить оригинал Recordset и повторно выполнять запрос.
Вы можете объединять сортировку и просачивание одна операция, как показано в следующем
примере.
rstOrders.Sort = "OrderDate DESC"
rstOrders.Filter = "CategoryName = 'Beverages'"
Set rstOrders = rstOrders.OpenRecordset()
Здесь, оригинал Recordset (основанный на запросе, возможно) сортируется в порядке по убыванию
OrderDate и фильтруется так, чтобы только продажа напитка была включена.
Вы не можете фильтровать Recordset тип таблицы. Если Вы хотите ограничивать записи,
восстановленные(отысканные) из таблицы, создайте тип dynaset- или snapshot Recordset.
Использование переменной QueryDef
OpenRecordset метод, используя константы dbOpenDynaset или dbOpenSnapshot, может принимать
строку SQL как параметр. Вы можете также создавать Recordset типа dynaset- или snapshot,
создавая объект QueryDef на существующем запросе и с использованием этого объекта QueryDef
метода OpenRecordset.
Set qdfTexasCustomers = dbsCurrent.QueryDefs("Texas Customers")
Set rstTexasCustomers = qdfTexasCustomers.OpenRecordset()
Преимущество использования строки SQL - то, что Вы не должны создать запрос, чье имя
появляется в окне Database. Если Вы используете много запросов, чтобы создать dynasets, Вы
можете ограничивать число имен запроса в окне Database, используя утверждения SQL в коде. Хотя
этот тип запроса выполняется более медленно, может оказаться важным, чтобы пользователи вашей
прикладной программы способны рассмотривать окно Database.
Dim dbsCurrent As Database, qdfCustomers As QueryDef
Set dbsCurrent = CurrentDB()
6
' Create QueryDef.
Set qdfCustomers = dbsCurrent.CreateQueryDef ("UpdateCustomers")
' Set SQL property.
qdfCustomers.SQL = "UPDATE DISTINCTROW Products " & _
"SET Products!SupplierID = 2 WHERE Products!SupplierID = 1;"
qdfCustomers.Execute
' Invoke query.
Обратите внимание, что утверждение UPDATE не возвращает строки, и Вы не используете
OpenRecordset метод. Взамен, Вы используете Execute метод объекта QueryDef.
Перемещение через Recordset
Recordsets обычно имеют текущую позицию. Когда Вы обращаетесь к полям в Recordset, Вы
получаете значения из текущей записи. Однако, текущая позиция может также быть
непосредственно перед первой записью в Recordset или непосредственно после последней записи. В
некоторых обстоятельствах, текущая позиция неопределена.
Вы можете использовать методы Move для цикла через записи в Recordset:
MoveFirst метод перемещается в первую запись.
MoveLast метод перемещается в последнюю запись.
MoveNext метод перемещается в следующую запись.
MovePrevious метод перемещается в предыдущую запись.
Move метод [0] перемещает вперед или назад определенное число записей.
Следующий пример изменяет заголовок работы всех Sales Representative (коммерческих
представителей) в таблице c именtv Employees. После открытия таблицы устанавливается индекс,
после чего необходимо использовать MoveFirst метод для размещения на первой записи. Для
каждой записи, удовлетворяющей условие заголовка, изменяется заголовок и сохраняет изменение
методом Update. Здесь используется MoveNext метод для перемещения на следующую запись.
Dim dbsCurrent As Database, rstEmployees As Recordset
Set dbsCurrent = CurrentDB()
Set rstEmployees = dbsCurrent.OpenRecordset("", dbOpenTable)
rstEmployees.Index = "LastName"
' Set current index.
rstEmployees.MoveFirst
' Locate first record.
Do Until rstEmployees.EOF
' Begin loop.
' Check title.
If rstEmployees!Title = "Sales Representative" Then
rstEmployees.Edit
' Enable editing.
rstEmployees!Title = "Account Executive"
' Change title.
rstEmployees.Update
' Save changes.
End If
rstEmployees.MoveNext
' Locate next record.
Loop
' End of loop.
rstEmployees.Close
' Close table.
Обнаружение границ Recordset
7
В Recordset, если Вы пытаетесь двигаться слишком далеко в одном направлении происходит
ошибка во время выполнения программы,. Например, если Вы пробуете использовать MoveNext
метод, когда вы - уже в конце Recordset, ошибка происходит. По этой причине, полезно знать
границы объекта Recordset.
BOF свойство указывает является ли текущая позиция в начале Recordset. Если BOF True, текущая
позиция - перед первой записью в Recordset. BOF свойство - также True, если нет записей в
Recordset, когда он открытвается. Аналогично, EOF свойство True, если текущая позиция - после
последней записи в Recordset или если нет записей.
Следующий пример показывает Вам, как использовать BOF и EOF свойства, чтобы обнаружить
начало и конец Recordset. Этот фрагмент кода создает тип таблицы Recordset основанный на
таблице Orders из текущей базы данных. Происходит перемещени через записи, с начала файла к
концу, и затем от конца файла к началу.
Dim dbsCurrent As Database, rstOrders As Recordset
Set dbsCurrent = CurrentDB()
' Open Recordset from TableDef.
Set rstOrders = dbsCurrent.OpenRecordset("", dbOpenTable)
Do Until rstOrders.EOF
.
.
.
rstOrders.MoveNext
Loop
rstOrders.MoveLast
Do Until rstOrders.BOF
.
.
.
rstOrders.MovePrevious
Loop
' Until end of table.
' Move to next record.
' MoveLast since now past the
' last record.
' Move to last record.
' Until beginning of file.
' Move to previous record.
rstOrders.Close
' Close Recordset.
Обратите внимание, что не имеется текущей записи сразу после первого цикла. BOF и EOF свойства
имеют следующие характеристики:
если Recordset не содержит никакие записи, когда Вы открываете его BOF и EOF True.
когда BOF и EOF True, они остаются True, пока Вы не двигаетесь в существующую запись,
когда BOF и EOF станут.
, когда BOF и EOF - и единственая запись в Recordset удалена, BOF и EOF остаются False,
пока Вы не пытаетесь двигаться в другую запись, при которой BOF и EOF станет True.
В настоящее время Вы создаете или открываете Recordset, который содержит по крайней
мере одну запись, первая запись - текущая запись и BOFи EOF False.
если первая запись – текущая и Вы используете MovePrevious, в то время как BOF True,
происходит ошибка во время выполнения программы. Когда это случается, BOF остается True
и не имеется текущей записи.
Аналогично, при перемещении после последней записи в Recordset изменяет значение EOF
свойствои к True. Если Вы используете MoveNext метод, в то время как EOF True, происходит
8
ошибка во время выполнения программы. Когда это случается, EOF остается True не имеется
никакая текущая(актуальная) запись.
Подсчет числа Записей в Recordset
Вы можете узнать количество записей в объекте Recordset. Например, Вы можете создать форму,
которая показывает информацию для каждой из таблиц в базе данных. Или Вы можете изменять вид
формы или отчета, основанного на записях, которые они включает.
RecordCount свойство содержит число записей, доступных в определенном Recordset. Recordset без
записей имеет значение RecordCount 0.
Замечание Значение RecordCount равняется числу записей фактически доступных. Например,
когда Вы сначала создаете dynaset или snapshot, Вы "посетили" только одну запись. Если Вы
считаете записи сразу после создания dynaset или snapshot (предполагается по крайней мере одна
запись), значение RecordCount 1. Когда Вы создаете объект Recordset типа table, Вы действительно
"посетили" все записи в основной таблице, и RecordCount отразит это количество.
Чтобы определять общее количество записей в Recordset, используйте MoveLast метод двигаться
на последнюю запись и затем проверять значение RecordCount.
Следующий пример создает Recordset основанный на таблице Employees, и затем определяет число
записей в Recordset.
Dim dbsCurrent As Database, rstEmployees As Recordset, _
lngTotal As Long
Set dbsCurrent = CurrentDB()
Set rstEmployees = dbsCurrent.OpenRecordset("Employees")
rstEmployees.MoveLast
lngTotal = rstEmployees.RecordCount
If lngTotal = -1 Then
Debug.Print "Count not available."
End If
Когда записи в dynaset-типе Recordset удаляются программой, значение RecordCount свойств
уменьшается. Однако, в многопользовательской среде, записи, удаленные другими пользователями
не отражаются в значении RecordCount, пока текущая запись установлена в удаленную запись. В
это время, установка RecordCount свойств уменьшается на один. Использование метода Requery на
Recordset, сопровождаемом MoveLast методом, устанавливает RecordCount свойство к текущему
общему количеству записей в Recordset.
Recordset тип snapshot - статический и значение RecordCount, не изменяется, когда Вы добавляете
или удаляете записи в основной таблице snapshot.
Поиск текущей позиции в Recordset
9
В некоторых ситуациях необходимо определить, как далеко в Recordset Вы переместили текущую
позицию. Вы можете указывать текущую позицию в программе. Два свойства доступны, чтобы
указать текущую позицию: AbsolutePosition свойство и PercentPosition свойство.
Значение свойства AbsolutePosition - позиция текущей записи относительно 0. Однако это не номер
записи; если текущая запись неопределена, то AbsolutePosition возвращает -1. Кроме того, не
имеется никакой гарантии, что записи появятся в том же самом порядке, каждый раз когда
обращаются к Recordset.
PercentPosition свойство показывает текущую позицию, выраженную как процент от общего
количества записей, обозначенных в RecordCount свойстве. Поскольку RecordCount свойство не
отражает общее количество записей в Recordset, пока Recordset не полностью заполнился,
PercentPosition свойство только отражает текущую позицию записи как процент от числа записей, к
которым обратились, с тех пор как Recordset был открыт. Чтобы удостовериться, что
PercentPosition свойство отражает текущую позицию записи относительно всего Recordset,
использует MoveLast и MoveFirst методы немедленно после открытия Recordset. Это полностью
заполнит Recordset прежде, чем Вы пытаетесь использовать PercentPosition свойство.
Следующий пример открывает Recordset на таблице с именем Employees и полностью заполняет
его. Программа затем вносит в список содержание каждого поля каждой записи в таблице, нумеруя
записи, как они введены. Когда половина записей введена, появляется сообщение, указывая, что Вы
на полпути в таблице.
Dim dbsCurrent As Database, rstEmployees As Recordset
Set dbsCurrent = CurrentDB()
Set rstEmployees = dbsCurrent.OpenRecordset("Employees", _
dbOpenDynaset)
rstEmployees.MoveLast
rstEmployees.MoveFirst
' The Recordset is now fully populated.
While rstEmployees.EOF = False
Debug.Print "Record No. " & rstEmployees.AbsolutePosition
Debug.Print rstEmployees!LastName
Debug.Print rstEmployees!FirstName
If rstEmployees.PercentPosition > 50.0 Then
Debug.Print "Over half way!"
End If
rstEmployees.MoveNext
Wend
rstEmployees.Close
dbsCurrent.Close
Поиск определенной записи
Предыдущий раздел, " Перемещение через Recordset, " исследует пути, которыми Вы можете
использовать методы Move - MoveFirst, MoveLast, MovePrevious, и MoveNext - для цикла по
записям Recordset. В большинстве случаев, однако, более эффективно искать определенного
запись.
Например, Вы можете находить служащего по номеру служащего, или Вы можете найти все записи,
которые принадлежат определенному заказу. В этих случаях, цикл через всех служащих или
записей заказа требуют много времени. Взамен, чтобы найти записи Вы можете использовать метод
Seek с объектами Recordset типа table и Find методами с dynaset- и объектами Recordset типа
snapshot.
Использование Метода Seek
10
Метод Seek используется для указания записи в Recordset типа table. Чтобы найти запись в dynaset
или snapshot, используйте один из Find методов, описанных в следующем разделе. Когда Вы
используете метод Seek для указания записи, engine базы данных использует текущий индекс
таблицы, который определен в Index свойстве.
Table.Seek сравнение, key1, key2 ...
Параметр Table - объект Recordset типа table ,в которой Вы ищете. Метод Seek принимает ряд
параметров, первых из которого является сравнение, которое является строкой, которая определяет
вид сравнения, которое выполняется. Следующая таблица представляет список строк сравнения,
которые Вы можете использовать с методом Seek.
Comparison string
Description
"="
Equal to the specified key values
">="
Greater than or equal to the specified key values
">"
Greater than the specified key values
"<="
Less than or equal to the specified key values
"<"
Less than the specified key values
Параметры keyn - ряд значений, которые соответствуют полю или полям, которые делают текущий
индекс Recordset. Engine базы данных сравнивает эти значения со значениями в соответствующих
полях записей объекта Recordset.
Следующий пример открывает Recordset тип table с именем Products, и использует метод Seek
найти первую запись, содержащую значение 1 в SupplierID поле (который является неуникальным
индексным полем). Он изменяется с 1 на 2 и сохраняет изменение методом Update. Последующие
переходы в цикле устанавливаются на следующую запись, которые удовлетворяющую условию.
Dim dbsCurrent As Database, rstProducts As Recordset
Set dbsCurrent = CurrentDB()
Set rstProducts = dbsCurrent.OpenRecordset("Products", dbOpenTable)
rstProducts.Index = "SupplierID"
' Define current index.
rstProducts.Seek "=", 1
' Seek record.
Do Until rstProducts.NoMatch
rstProducts.Edit
rstProducts("SupplierID") = 2
rstProducts.Update
rstProducts.Seek "=", 1
Loop
'
'
'
'
'
'
Until no record is found.
Enable editing.
Change SupplierID.
Save changes.
Seek next record.
End of loop.
rstProducts.Close
' Close Recordset.
Если Вы используете метод Seek с объектом Recordset типа таблицы без первой установки текущего
индекса, происходит ошибка во время выполнения программы.
Следующий пример иллюстрирует, как Вы можете создать функцию, которая использует метод
Seek для установки на запись, использующую сложный индекс.
Function GetFirstPrice(ByVal lngOrderID As Long, _
ByVal lngProductID As Long) As Variant
Dim dbsCurrent As Database, rstOrderDetail As Recordset
Set dbsCurrent = CurrentDB()
Set rstOrderDetail = dbsCurrent.OpenRecordset("Order Details", _
dbOpenTable)
rstOrderDetail.Index = "PrimaryKey"
rstOrderDetail.Seek "=", lngOrderID, lngProductID
If rstOrderDetail.NoMatch Then
11
GetFirstPrice = Null
MsgBox "Couldn't find order detail record."
Else
GetFirstPrice = rstOrderDetail!UnitPrice
End If
rstOrderDetail.Close
dbsCurrent.Close
End Function
В этом примере, первичный ключ таблицы состоит из двух полей: OrderID и ProductID. Когда Вы
вызываете функцию GetFirstPrice с допустиой комбинацией OrderID и ProductID значений полей,
функция возвращает цену из найденной записи. Если комбинация поля не может быть найдена в
таблице, функция возвращает Null.
Если текущий индекс – множественное поле, хвост может быть опущен и обрабатывается как Null.
То есть Вы можете отбрасывать от любого числа значений ключа с конца параметра ключа метода
Seek, но не из начала или середины. Однако, если Вы не определяете все значения в индексе, Вы
можете использовать только " > "или" < " оператор сравнения с методом Seek.
Использование Find методов
Вы можете использовать следующие методы для поиска записи в Recordset типа dynaset- или
snapshot. (Чтобы найти запись в Recordset типе таблицы, используйте метод Seek, который описан в
предыдущем разделе.) Microsoft Jet базы данных engine поддерживает четыре Find метода:
Х
FindFirst метод находит первую запись, удовлетворяющую определенному критерию.
Х
FindLast метод находит последнюю запись, удовлетворяющую определенному критерию.
Х
FindNext метод находит следующую запись, удовлетворяющую определенному критерию.
Х
FindPrevious метод находит предыдущую запись, удовлетворяющую определенному
критерию.
Когда Вы используете Find методы, Вы определяете критерии поиска, обычно выражение,
сравнивающее имя поля со определенным значением. Следующий пример иллюстрирует, как
изменить Title работы всех коммерческих представителей в таблице с именем Employees. Создается
объект Recordset и затем использует FindFirst и FindNext методы для поиска всех записей,
удовлетворяющих условию:
"Title = 'Sales Representative'"
Подготовка каждой записи для редактирования, изменения Title и сохранение изменения методом
Update.
Dim strCriterion As String
Dim dbsCurrent As Database, rstEmployees As Recordset
' Define search criterion.
strCriterion = "Title = 'Sales Representative'"
Set dbsCurrent = CurrentDB()
' Create dynaset.
Set rstEmployees = dbsCurrent.OpenRecordset("Employees", dbOpenDynaset)
' Locate first occurrence.
rstEmployees.FindFirst strCriterion
' Loop until no matching records.
Do Until rstEmployees.NoMatch
rstEmployees.Edit
12
' Enable editing.
rstEmployees!Title = "Account Executive"
' Change title.
rstEmployees.Update
' Save changes.
rstEmployees.FindNext strCriterion
' Locate next record.
Loop
' End of loop.
Вы можете искать соответствующие записи в обратном порядке, находя последнюю с FindLast
методом и затем используя FindPrevious метод вместо FindNext метода.
Совет, Используюя запрос модификации для замены Title более эффективно.
Engine базы данных устанавливает NoMatch свойство к True всякий раз, когда Find метода дает
сбой и текущая позиция записи неопределена. Может иметься текущая запись, но Вы не имеете
никакого способа сообщить, которая запись это может быть. Если Вы хотите быть способными
возвратиться предыдущей текущей записи после неудачного использования Find метода,
используйте (BookMark) закладку.
NoMatch False всякий раз, когда операция успешна. В этом случае текущая позиция записи,
найдена одним из Find методов.
Следующий пример иллюстрирует, как Вы можете использовать FindNext метод найти все записи,
которые содержат Null в поле Phone в таблице, именованной Customers. Затем запрашивает
пользователя вводить номер телефона для заказчика.
Dim dbsCurrent As Database, rstCustomers As Recordset
Dim strCriterion As String, strNumber As String
Set dbsCurrent = CurrentDB()
Set rstCustomers = dbsCurrent.OpenRecordset("Customers", _
dbOpenDynaset)
strCriterion = "Phone Is Null"
rstCustomers.FindFirst strCriterion
Do Until rstCustomers.NoMatch
strNumber = InputBox(rstCustomers!CompanyName & _
" is missing a phone number.")
rstCustomers.Edit
rstCustomers!Phone = strNumber
rstCustomers.Update
rstCustomers.FindNext strCriterion
Loop
Совет Может быть более эффективно использовать утверждение SQL SELECT, чтобы отыскать все
необходимые записи, затем модифицировать их как набор.
Использование Bookmarks вместо номера записи
Если Вы использовали другую базу данных или среду программирования, Вы можете быть
привыкли к использованию номера записи. Например, Вы можете написать код, который открывает
текстовый файл и затем обращаеться к определенным записям по относительной позициии в файле.
Первая запись в файле была бы запись 1, вторая будет запись 2, и так далее.
В Microsoft Access, ваше представление записей - Recordset - является обычно подмножеством
записей во всей таблице. Поскольку фактическое число записей в Recordset может изменяться в
любое время, особенно в многопользовательской среде, нет никакого абсолютного номера записи,
который Вы можете всегда использовать, чтобы обратиться к определенной записи.
AbsolutePosition свойство изменится, если предыдущая запись удалена. Взамен, Вы можете
использовать bookmarks, чтобы идентифицировать, и затем возвратиться на специфическую запись.
Записи, возвращенные в объект Recordset не находятся ни в каком определенном порядке, если
Recordset не был создан с запросом, который включает предложение ORDER BY, или - тип
таблицы Recordset с Index. Номера записей были бы обычно бессмысленны в объекте Recordset.
Bookmark - сгенерированный системой массив Byte, который однозначно идентифицирует каждую
запись. Свойство Bookmark объекта Recordset изменяется каждый раз при перемещении на новую
запись. Чтобы идентифицировать запись, перемещайтесь на нее, и затем назначьте значение
13
свойства Bookmark переменной типа Variant. Чтобы возвратиться к записи, установите свойство
Bookmark значению переменной.
Следующий пример иллюстрирует, как можно использовать закладку, чтобы сохранить текущую
позицию записи и затем быстро возвращаться к той позиции записи, если Find или Seek методы
терпят неудачу. Если методы неудачны, текущая позиция записи неопределены.
Dim dbsCurrent As Database, rstCustomers As Recordset
Dim varOrigin As Variant
Set dbsCurrent = CurrentDB()
Set rstCustomers = dbsCurrent.OpenRecordset("Customers", _
dbOpenTable)
rstCustomers.Index = "CompanyName"
.
.
.
varOrigin = rstCustomers.Bookmark
rstCustomers.Seek ">=", "Z"
If rstCustomers.NoMatch Then
MsgBox "Can't find a company name starting with 'Z'."
rstCustomers.Bookmark = varOrigin
End If
rstCustomers.Close
dbsCurrent.Close
В этом примере, сохраняя свойство Bookmark, и затем сбрасывая свойство Bookmark к
предыдущему значению, когда сбой метода Seek, заставляют предварительно текущую запись быть
текущей записью вновь.
Вы можете также использовать свойство Bookmark в Recordset лежащий в основе формы. С этим
свойством, ваш код может отмечать, которая запись в настоящее время отображается в форме, и
затем изменять отображаемую запись. Например, в форме, содержащей информацию служащего,
Вы можете иметь кнопку, которую пользователь может нажимать, чтобы показать запись для
руководителя служащего. Следующий пример иллюстрирует процедуру обработки события,
которую Вы использовали бы для Click события кнопки.
Sub ShowSuper_Click ()
Dim frmEmployees As Form, rstEmployees As Recordset
Dim varOrigin As String, strEmployee As String, strSuper As String
Set frmEmployees = Screen.ActiveForm
' Create Recordset from form.
Set rstEmployees = frmEmployees.RecordsetClone
' Save current record information.
varOrigin = frmEmployees.Bookmark
strEmployee = frmEmployees!FirstName & " " &frmEmployees!LastName
rstEmployees.FindFirst "EmployeeID = " & frmEmployees!ReportsTo
If rstEmployees.NoMatch Then
MsgBox "Couldn't find " & strEmployee & "'s supervisor."
Else
frmEmployees.Bookmark = rstEmployees.Bookmark
Super = frmEmployees!FirstName & " " & _
frmEmployees!LastName
MsgBox strEmployee & "'s supervisor is " & strSuper
frmEmployees.Bookmark = varOrigin
End If
14
rstEmployees.Close
End Sub
Некоторые связанные таблицы, типа таблиц Paradox, которые не имеют никакого первичного
ключа, не могут поддерживать закладки. Следовательно, Вы не можете также использовать
закладки ни на таких таблицах, ни на объектах Recordset или запросах, основанных на этих
таблицах. Однако, все snapshot поддерживают закладки, независимо от их основных таблиц. Вы
можете определять, поддерживает ли таблица Bookmark, проверяя значение Bookmarkable
свойство, как в следующем примере.
If rstLinkedTable.Bookmarkable Then
MsgBox "The underlying table supports bookmarks."
Else
MsgBox "The underlying table doesn't support bookmarks."
End If
Если Вы пробуете использовать закладки в Recordset, который не поддерживает закладки,
происходит ошибка во время выполнения программы.
Когда Вы закрываете Recordset, любые закладки, которые Вы сохранили, станут недопустимым. Вы
не можете использовать закладку, полученную из одного Recordset в другом Recordset, даже если
оба объекта Recordset основаны на той же самой основной таблице или запросе. Однако, Вы можете
использовать закладку на двойнике (аналоге) Recordset, как показано в следующем примере.
Dim dbsCurrent As Database
Dim rstOriginal As Recordset, rstDuplicate As Recordset
Dim varPlaceholder As String
Set dbsCurrent = CurrentDB()
' Create first Recordset.
Set rstOriginal = dbsCurrent.OpenRecordset("Orders", dbOpenDynaset)
varPlaceholder = rstOriginal.Bookmark ' Save current record position.
Set rstDuplicate = rstOriginal.Clone() ' Create duplicate Recordset.
rstDuplicate.Bookmark = varPlaceholder ' Go to same record.
Изменение данных
Как только вы создали объект Recordset типа table или dynaset, Вы можете изменять, удалять или
добавлять новые записи. Вы не можете изменять, удалять или добавлять записи в объекте snapshottype Recordset. Этот раздел представляет методы и процедуры для измения данных в объектах
Recordset таблице - и dynaset-типа.
Использование Queries Parameter
В многих ситуациях необходимо для пользователя или другой программы обеспечить параметры
для ваших сохраненных запросов и объектов Recordset. Microsoft Jet Engine базы данных
обеспечивает средства, чтобы сделать это. Вы сначала создаете сохраненный запрос, определяя,
какие параметры должны обеспечиваться конечным пользователем. Когда Вы открываете Recordset
одного из этих запросов, прикладная программа открывает диалоговое окно, которое запрашивает
пользователя вводить значение такие как критерий для предложения WHERE или поля для
сортировки выбранных записей.
Следующий пример использует код Visual Basic, чтобы создать новый параметический запрос,
именованный Seniority, который возвращает фамилию каждого служащего, нанятого после
некоторой даты. Перед выполнением запроса, программа вызывает функцию InputBox$, чтобы
запросить пользователя относительно пороговой даты. Имена затем показываются в окне Отладки,
начиная с самого недавнего найма.
Sub Param_Query ()
Dim dbsCurrent As Database, rstEmployees As Recordset
15
Dim qdfEmployees As QueryDef
Dim strSQLQuery As String, strHireDate As String
Set dbsCurrent = CurrentDB()
strSQLQuery = "PARAMETERS BeginningDate DateTime; " & _
"SELECT LastName FROM Employees " & _
"WHERE HireDate >= BeginningDate " & _
"ORDER BY HireDate DESC;"
Set qdfEmployees = dbsCurrent.CreateQueryDef("Seniority",strSQLQuery)
strHireDate = InputBox$("Enter the earliest hire date")
qdfEmployees.Parameters("BeginningDate") = strHireDate
Set rstEmployees = qdfEmployees.OpenRecordset()
rstEmployees.MoveFirst
While rstEmployees.EOF = False
Debug.Print rstEmployees!LastName
rstEmployees.MoveNext
Wend
End Sub
Большинство задач сопровождения базы данных, описанных в остальной части этой главы может
быть выполнено, используя сохраненные запросы параметра.
Выполнение массовых изменений
Многие из изменений, которые Вы могли бы выполнять в цикле, могут быть выполнены более
эффективно запросом модификациии или удаления. Например, задача изменения всех заголовков
работы для коммерческих представителей, иллюстрируемая в нескольких предыдущих примерах в
цикле по записям каждого служащего и проверку существующего заголовка работы, может быть
выполнена быстро запросом модификации.
Dim dbsCurrent As Database, qdfChangeTitles As QueryDef
Set dbsCurrent = CurrentDB()
Set qdfChangeTitles = dbsCurrent.CreateQueryDef()
qdfChangeTitles.Name = "Change Job Titles"
' Create query.
qdfChangeTitles.SQL = "UPDATE DISTINCTROW Employees " & _
"SET Employees!Title = 'Account Executive' " & _
"WHERE Employees!Title = 'Sales Representative';"
dbsCurrent.QueryDefs.Append qdfChangeTitles
' Append query.
qdfChangeTitles.Execute
' Invoke query.
dbsCurrent.QueryDefs.Delete "Change Job Titles"
' Delete query.
Конечно, вся строка SQL может быть заменена в сохраненном запрос параметра, в котором
программа запросила бы пользователя относительно значений параметра. Следующий пример
показывает, как предыдущий пример может быть изменен на сохраненный запрос параметра.
Dim dbsCurrent As Database, qdfChangeTitles As QueryDef
Dim strSQLUpdate As String, strOld As String, strNew As String
Set dbsCurrent = CurrentDB()
' Define the parameters and
' the SQL update query.
strSQLUpdate = "PARAMETERS [Old Title] Text, [New Title] Text; " & _
"UPDATE DISTINCTROW Employees " & _
"SET Employees!Title = [New Title] " & _
"WHERE Employees!Title = [Old Title]; "
Set qdfChangeTitles = dbsCurrent.CreateQueryDef("Change Job Titles", _
16
strSQLUpdate)
strOld = InputBox$("Enter old job title")
strNew = InputBox$("Enter new job title")
qdfChangeTitles.Parameters("Old Title") = strOld
qdfChangeTitles.Parameters("New Title") = strNew
'
'
'
'
'
'
'
Create the
QueryDef object.
Prompt for old
title.
Prompt for new
title.
Set parameters.
qdfChangeTitles.Execute
' Invoke query.
dbsCurrent.QueryDefs.Delete "Change Job Titles"
' Delete query.
В зависимости от вашей задачи, Вы можете также находить, что удаляющийся запрос более
эффективен чем код цикла по записям для их удаления.
Изменение существующей Записи
Изменение существующей записи в объекте Recordset - процесс из четырех шагов:
1.
Переход к записи, которую Вы хотите изменять.
2.
Использовать метод Edit для подготовки текущую записи для редактирования.
3.
Сделать необходимые изменения в записи.
4. Использовать метод Update для сохранения изменений для текущей записи.
Следующий пример иллюстрирует, как изменить заголовки работы для всех коммерческих
представителей в таблице, именованной Employees.
Set dbsCurrent = CurrentDB()
Set rstEmployees = dbsCurrent.OpenRecordset("Employees")
rstEmployees.MoveFirst
Do Until rstEmployees.EOF
If rstEmployees!Title = "Sales Representative" Then
rstEmployees.Edit
rstEmployees!Title = "Account Executive"
rstEmployees.Update
End If
rstEmployees.MoveNext
Loop
rstEmployees.Close
dbsCurrent.Close
Если Вы не используете метод Edit до изменения значения в текущей записи, происходит ошибка
во время выполнения программы.
Важно . Если Вы изменяете текущую запись, и затем двигаетесь в другую запись или закрываете
Recordset без предварительного использования метод Update, ваши изменения потеряются без
предупреждения. Например, опущение метода Update из предшествующего примера не имеет
результата ни в каких изменениях, сделанных к таблице Employees.
Объекты Recordset типа dynaset- могут быть основаны на запросе многих таблиц с запросом, часто
выполняющим one-to-many связь. Например, предположим, что Вы хотите создать запрос к многим
таблицам, который объединяет поля из таблиц Orders и Order Details. Обычно, Вы не можете
изменять значения в таблице Orders, потому что она находится на "один" стороне связи. В
зависимости от вашей прикладной программы, однако, Вы можете быть способны делать изменения
для таблицы Orders. Чтобы делать возможным свободно изменить значения на "одной" стороне oneto-many связи, используйте dbInconsistent константу OpenRecordset метода для создания
противоречивого dynaset.
17
Set rstTotalSales = dbsCurrent.OpenRecordset("Sales Totals",, _
dbInconsistent)
Важно, Когда Вы модифицируете противоречивый dynaset, Вы можете легко уничтожить
реляционную целостность данных в dynaset. Вы должны быть осторожны, чтобы понять, как данные
связаны one-to-many связью и модифицировать значения с обеих сторон для сохранения
целостности данных.
DbInconsistent константа доступна только для объектов dynaset-type Recordset. Она игнорируется
для таблицы - и Snapshot - типов, но не возвращается ошибка компиляции или выполнения
программы , если dbInconsistent используется с указанными типами объектов Recordset.
Даже с непротиворечивым Recordset, некоторые поля не могут быть замещаемы. Например, Вы не
можете изменять значение поля AutoNumber, и Recordset основанный на некоторых связанных
таблицах не может быть замещаемым.
Удаление существующей записи
Вы можете удалять существующую запись в table - или dynaset-типе Recordset используя Delete
метод. Вы не можете удалять записи из Recordset типа snapshot. Следующий пример удаляет все
записи для стажеров в таблице, именованной Employees.
Dim dbsCurrent As Database, rstEmployees As Recordset
Set dbsCurrent = CurrentDB()
Set rstEmployees = dbsCurrent.OpenRecordset("Employees")
rstEmployees.MoveFirst
Do Until rstEmployees.EOF
If rstEmployees!Title = "Trainee" Then
rstEmployees.Delete
End If
rstEmployees.MoveNext
Loop
rstEmployees.Close
dbsCurrent.Close
Когда Вы используете Delete метод, engine базы данных немедленно удаляет текущую запись, без
предупреждения или подсказки. Удаление записи автоматически не заставляет следующую запись
стать текущей записью; чтобы перейти на следующую запись, Вы должны использовать MoveNext
метод.
Добавление новой записи
Добавление новой записи на dynaset- или тип таблицы Recordset - процесс из трех шагов:
1.
Использовать AddNew метод для подготовки новой записи для редактирования.
2.
Присвоить значения каждому из полей записи.
3. Использовать метод Update для сохранения новой записи.
Следующий пример добавляет новую запись на таблицу, именованную Shippers.
Dim dbsCurrent As Database, rstShippers As Recordset
Set dbsCurrent = CurrentDB()
Set rstShippers = dbsCurrent.OpenRecordset("Shippers")
rstShippers.AddNew
rstShippers!CompanyName = "Global Parcel Service"
.
.
' Set remaining fields.
18
.
rstShippers.Update
rstShippers.Close
dbsCurrent.Close
Когда Вы используете AddNew метод, engine базы данных готовит новую, пустую запись и делает
это текущей записью. Когда Вы используете метод Update для сохранения новой записи, запись,
которая была текущая прежде, чем Вы использовали AddNew метод, становится текущей записью
снова. Позиция новой записи в Recordset зависит от того, добавили Вы запись на dynaset- или тип
table Recordset.
Если Вы добавляете запись в Recordset dynaset-тип, новая запись появляется в конце Recordset,
независимо от того как Recordset сортируется. Чтобы заставить новую запись появляться в
правильно сортируемой позиции, Вы можете использовать метод Requery для воссоздания объекта
Recordset, или создать новый Recordset основанный на оригинале.
Если Вы добавляете запись в Recordset типа таблицы, запись появляется установленной согласно
текущему индексу, или в конце таблицы, если нет первичного ключа и текущего индекса.
Важно Если Вы используете AddNew метод для добавления новой записи, затем двигаетесь в
другую запись, или закрываете Recordset без использования метод Update, ваши изменения
потеряются без предупреждения. Например, опущение метода Update из предшествующего
примера не кончается изменениями, сделанными к таблице Shippers.
Извлечение данных из записи
После того, как вы разместили специфическую запись или записи, Вы можете извлекать данные,
чтобы использовать в вашей прикладной программе вместо того, чтобы изменить основную таблицу
источника.
Копирование одиночного поля
Одиночное поле записи может быть скопировано переменной соответствующего типа данных.
Следующий пример извлекает три поля из каждой записи в объекте Recordset.
Dim dbsCurrent As Database, rstEmployees As Recordset
Dim strFirstName As String, strLastName As String, strTitle As String
Set dbsCurrent = CurrentDB()
Set rstEmployees = dbsCurrent.OpenRecordset("Employees")
rstEmployees.MoveFirst
strFirstName = rstEmployees!FirstName
strLastName = rstEmployees!LastName
strTitle = rstEmployees!Title
Копирование всех записей в массив
Чтобы копировать одну или все записи, Вы можете создать двумерный массив и копировать записи
по одной. Увеличивайте первый индекс для каждого поля и второй индекс для каждой записи.
Быстрый способ делать то же самое - с GetRows методом. GetRows метод возвращает массив с
двумя размерностями. Первый индекс идентифицирует поле, а второй идентифицирует номер
строки, следующим образом:
VarRecords (intField, intRecord)
Следующий пример использует утверждение SQL, чтобы восстановить(отыскать) три поля из
таблицы называемой Employees в объект Recordset. Затем используется GetRows метод для запроса
первых трех записей Recordset, и сохраняет выбранные записи в массиве с размерностью два.
Каждая запись затем печатается по одному полю с использованием двух индексов для выбора
специфического поля и записи.
19
Чтобы ясно иллюстрировать, как индексы массива используются, пример использует отдельное
утверждение, чтобы идентифицировать и выводить каждое поле каждой записи. Практически более
реально использовать два вложенных цикла.
Sub GetRows_Test()
Dim dbsCurrent As Database, rstEmployees As Recordset
Dim varRecords As Variant
Set dbsCurrent = CurrentDB()
Set rstEmployees = dbsCurrent.OpenRecordset("SELECT FirstName, " & _
"LastName, Title FROM Employees", dbOpenSnapshot)
varRecords = rstEmployees.GetRows(3)
Debug.Print "First Name", "Last Name", "Title"
Debug.Print varRecords(0, 0),
Debug.Print varRecords(1, 0),
Debug.Print varRecords(2, 0)
Debug.Print varRecords(0, 1),
Debug.Print varRecords(1, 1),
Debug.Print varRecords(2, 1)
Debug.Print varRecords(0, 2),
Debug.Print varRecords(1, 2),
Debug.Print varRecords(2, 2)
End Sub
Вы можете использовать последующие обращения для GetRows метода, если большое количество
записей доступно. Поскольку массив заполняется, как только Вы вызываете GetRows метод, Вы
можете видеть, почему этот подход - намного быстрее чем использование утверждений назначения,
для копирования по одному полю как в первом примере.
Обратите внимание также, что Вы не должны описывать Variant как массив, потому что это
выполняется автоматически, когда GetRows метод возвращает записи. Это позволяет Вам
использовать массив фиксированной длины без того, чтобы знать, сколько записей или полей будут
возвращены, вместо переменной длины, которые требуют большего количества памяти.
20
Download