Как сделать базу access многопользовательской?

База данных, как правило, содержит данные, необходимые многим пользователям. Создание многопользовательской базы данных Access и получение одновременного доступа нескольких пользователей к общей БД возможно в одноранговой сети персональных компьютеров или в сети с файловым сервером.

Под одноранговой понимается сеть, каждый компьютер которой может предоставлять остальным подключенным к сети компьютерам доступ ко всем или некоторым своим ресурсам, т.е. являться сервером и клиентом одновременно. Одноранговая сеть может управляться встроенными компонентами настольных операционных систем Windows XP/Vista/ Windows 7/ Windows 8.

Сети больших масштабов используют выделенные файловые серверы. В сети, поддерживающей концепцию файлового сервера, база данных Access размещается на компьютере, выделенном в качестве файлового сервера. СУБД Access, как правило, устанавливается на каждый компьютер пользователя. Обработка БД осуществляется на компьютерах пользователей. Поэтому по сети передаются с сервера на компьютер клиента большие объемы данных, что сильно загружает ее и делает невозможным одновременное обслуживание большого числа пользователей.

Работа локальной сети с файловым сервером обеспечивается рядом сетевых операционных систем. Наиболее популярными являются Microsoft Windows Server и Novell NetWare.

Сеть предоставляет аппаратную и программную поддержку обмена данными между компьютерами. Сетевая ОС обеспечивает защиту БД, размещенной в сети, предоставляя пользователям доступ к определенным сетевым ресурсам – например, папкам, файлам, только по предъявлении имени и пароля. Кроме того, для пользователя папки или отдельного файла могут назначаться права доступа, ограничивающие их использование, например, только чтением.

Access не следит за разграничением доступа разных пользователей к БД, но автоматически обеспечивает защиту данных от одновременной их корректировки несколькими пользователями. Для обеспечения защиты данных от одновременной их корректировки несколькими пользователями в Access предусматривается блокировка на уровне страниц, при которой блокируются все записи одной страницы. Дополнительно к блокировке страничного уровня Access поддерживает блокировку на уровне записи. Блокирование не допускает изменения записи другими пользователями, пока текущее изменение не будет закончено.

Выбор режима блокировки на уровне записей по умолчанию в текущей БД производится параметром Открывать базу данных с использованием блокировки на уровне записей в окне Параметры Access на вкладке Параметры клиента в группе Дополнительно. Если флажок этого параметра сброшен, по умолчанию будет использована блокировка на уровне страницы. Выбранный вариант применяется к данным в формах, таблицах и программах, использующих объект Recordset для перебора записей. Этот параметр не применяется к запросам на изменение или программам, выполняющим массовые операции с использованием SQL.

Прежде чем начать работу нескольких пользователей с общей базой данных, необходимо выполнить разделение локальной базы данных. Разделение БД предполагает выделение таблиц текущей БД в новую базу. При этом текущая база становиться интерфейсной БД, а БД с таблицами помещается в сетевое расположение, указанное при выполнении процедуры разделения.

После разделения БД нужно распространить интерфейсную БД среди пользователей, чтобы они могли начать работу с ней.

Для разделения БД откройте ее и выполните команду База данных Access из группы Перемещение данных на вкладке Работа с базами данных. Появится первое окно соответствующего мастера. Для выполнения процедуры разделения достаточно в следующем окне Создание базы данных с таблицами указать имя, местоположение новой БД с таблицами и нажать кнопку Разделение. Поскольку разделяемая база данных преобразуется в интерфейсную, целесообразно предварительно сделать ее копию.

Для БД с таблицами рекомендуется использовать имя, предложенное программой Access. Оно представляет собой исходное имя файла, к которому добавлены символы _be, указывающие, что БД с таблицами.

Чтобы путь к файлу, находящемуся на каком-либо компьютере, был одинаковым при доступе с любого компьютера этой сети, используйте для указания его местоположения путь UNC. Например, \Сервер\Общая_папка\ИмяБД_be.accdb. Выбирайте такое расположение, к которому можно предоставить доступ всем пользователям БД.

Т.к. пользователи, работая в интерфейсной БД, получают доступ к общей БД с таблицами через связанные таблицы, нельзя произвольно менять ее имя и местоположение. Переместить БД с таблицами или заменить ее на другую можно с помощью Диспетчера связанных таблиц, который расположен на вкладке Внешние данные в группе Импорт и связывание.

Блокировка на уровне записей действует только при доступе к данным через формы, страницы таблиц и запросов или с помощью объекта Recordset. Данный режим не влияет на выполнение запросов и инструкций SQL.

Следующие четыре параметра помогают избежать конфликтов при блокировке записей в сети:

Значения этих параметров устанавливаются в диалоговом окне Параметры (Options) на вкладке Другие (Advanced). Подробное описание этих параметров есть в справочной системе Access.

Существует несколько способов отображения на экране обновленных данных, полученных из источника данных, совместно используемого в сети несколькими пользователями. Эти способы позволяют увидеть изменения, которые были выполнены другими пользователями, после того как отображенные на экране данные получены из источника.

Обновление данных можно выполнить следующими способами.

Внесение изменений в объекты базы данных при работе в сети характеризуется следующими особенностями.

Например, при добавлении полей в форму следует до обновления формы добавить поля в базовый запрос.

Со страницами доступа к данным могут работать несколько пользователей в сети. Страницы могут быть отображены с помощью программы просмотра Интернета или в сообщении электронной почты. Для этого источник данных для страницы — базу данных Access или SQL Server — требуется поместить в общую папку на рабочей станции или на сервере сети.

В приложении «Игра в доминирование» для отображения текущего состояния игрового поля в момент инициализации новой игры создается страница доступа к данным «Игровое поле», которая сохраняется в той же папке, что и приложение «Сервер игры». Эта папка должна быть доступна в сети, чтобы игроки — пользователи приложения «Клиент игры» — могли подключиться к игре и просмотреть страницу «Игровое поле» с помощью программы Internet Explorer.

Если база данных, являющаяся источником данных для страницы, будет перемещена в другое место, необходимо соответствующим образом изменить параметры соединения страницы с источником данных. Для этого при работе со страницей в режиме Конструктора в окне Список полей (Field List) нажмите кнопку Свойства подключения для страницы (Page connection properties). В появившемся диалоговом окне на вкладке Соединение (Connection) введите в поле ввода, предназначенное для указания источника данных, имя и полный путь к базе данных в соответствии с соглашением об именах UNC. Укажите имя сетевого ресурса, а не имя подключенного сетевого диска, поскольку оно может измениться.

Имя ресурса в формате UNC состоит из четырех частей: имени сервера ресурсов, имени общей папки на сервере, пути к ресурсу и имени ресурса:

Чтобы изменить путь к странице доступа к данным, указанный в ярлыке страницы в базе данных Access, в окне базы данных щелкните по ярлыку страницы доступа к данным правой кнопкой мыши и в контекстном меню выберите команду Сцойства (Properties). Откроется окно свойств ярлыка, введите в поле ввода путь к файлу страницы (файлу HTML). Рекомендуем указывать относительные пути в таких случаях. Например, для страниц, хранящихся в той же папке, что и база данных, укажите только имя файла страницы без абсолютного пути к ней. Например: Обзор товapoв.htm

Хотя источником данных для страницы может быть только база данных Access или SQL Server, можно организовать доступ через страницу к данным других форматов, используя связанные таблицы в базах данных Access.

Замечание

Защита совместно используемых страниц доступа к данным описана в справочной системе Access. Для максимальной защиты страницы доступа к данным поместите базу данных, которая является источником данных для нее, на тот же Web-сервер, на котором хранится эта страница.

Существует несколько способов обмена данными между компонентами приложения по сети:

  • с помощью связанных таблиц;
  • с помощью запросов;
  • с помощью программирования на VBA.

Использование запросов и связанных таблиц подробно рассмотрено в других главах этой книги. Мы остановимся на программном доступе к базам данных с использованием интерфейса DАО. (Об установлении связи с таблицами см. гл. 3, об использовании запросов см. гл. 8.)

Объекты доступа к данным (DАО, Data Access Object) — это иерархия объектов, обеспечивающая доступ к структуре базы данных и ее содержимому. В программах Visual Basic пользователь имеет возможность использовать объектный интерфейс DАО для выполнения следующих задач:

  • осуществления доступа к данным в локальных и удаленных базах данных Access и внешних источниках;
  • управления базой данных и ее объектами;
  • изменения структуры таблиц и схемы данных;
  • управления системой защиты;
  • создания, настройки и синхронизации реплик.

Интерфейс DАО использует рабочие области двух видов:

  • Рабочая область ядра Jet. Обеспечивает доступ к базам данных процессора обработки данных Jet, источникам данных ODBC и источникам данных ISAM для % доступа к базам данных в других форматах (например, к базам данных Lotus 1-2-3). Рабочая область Jet используется для доступа к источникам данных с помощью процессора Jet.
  • Рабочая область ODBCDirect. Обеспечивает доступ к источникам данных ODBC напрямую, не используя процессор Jet.

Для рабочей области Jet и для рабочей области ODBCDirect существуют две разные объектные модели DАО. Они приведены в гл. 13.

Реализация модулей VBA для обмена данными между компонентами приложения «Игра в доминирование» основана на применении интерфейса DАО с использованием рабочей области ядра Jet. Поэтому в дальнейших примерах основное внимание уделено приемам программирования на DАО, применимым в рабочей области ядра Jet. Сведения о рабочей области ODBCDirect можно найти в справочной системе Access 2002.

В следующих разделах мы рассмотрим некоторые аспекты программирования с использованием DАО. Подробную информацию об интерфейсе DАО можно найти в справочной системе Access.

Внимание

В Access 2002 по умолчанию к программному проекту базы данных подключена библиотека Microsoft ActiveX Data Objects 2.1 Library. Чтобы использовать в процедурах VBA объекты доступа к данным, нужно обязательно отключить эту библиотеку и подключить библиотеку Microsoft DАО 3.6 Object Library. О подключении библиотек к программному проекту рассказано в гл. 13.

Обе иерархии объектов DАО: для рабочей области Jet и для рабочей области ODBCDirect — начинаются с объекта DBEngine. Этот объект содержит свойства и методы, позволяющие управлять рабочими областями. Свойство DefaultType объекта DBEngine позволяет определять или устанавливать тип рабочей области, создаваемой по умолчанию.

Объект DBEngine в качестве свойства содержит семейство Workspaces всех открытых рабочих областей. Можно выбрать элемент этого семейства, указав индекс или имя, чтобы получить доступ к конкретной рабочей области (программа 16.1).

Чтобы создать новую рабочую область ядра Jet или рабочую область ODBCDirect, используют метод CreateWorkspace (программа 16.2) объекта DBEngine с соответствующим параметром. Метод CreateWorkspace возвращает ссылку на объект типа workspace и имеет следующие параметры (табл. 16.2):

 Workspace CreateWorkspace(, , , )
Параметр  Тип  Описание 
String Имя пользователя, который будет владельцем создаваемой рабочей области. Определяет значение свойства UserName объекта Workspace
String Пароль пользователя. Он необходим для создания рабочей области. Пароль может включать до 14 символов. Это могут быть любые символы, кроме символа ASCII с кодом 0 (Null). Определяет значение свойства Password объекта Workspace
Необязательный параметр. Задает тип создаваемой рабочей области. В качестве значения можно использовать константу dbUseJet для создания рабочей области ядра Jet или константу dbUseODBC для создания рабочей области ODBCDirect. По умолчанию создается рабочая область того типа, который задан значением свойства DefaultType объекта DBEngine
String Уникальное имя создаваемой рабочей области. Определяет значение свойства Name объекта Workspace

Таблица 16.2. Параметры метода CreateWorkspace

Несколько рабочих областей разных типов могут быть открыты одновременно. В момент создания рабочей области начинается сеанс работы с ней. После выполнения всех необходимых действий в рабочей области нужно завершить сеанс, закрыв рабочую область с помощью метода Close объекта Workspace.

Программа 16.1. Использование рабочей области Jet, открытой по умолчанию

 Dim ws As Workspace Dim db As Database Set ws = DBEngine.Workspaces(0) ' Выбрали рабочую область ' Открываем базу данных: Set db = ws.OpenDatabase ("DominationGameServer.mdb") ' Код использования базы данных ... db.Close ' Закрыли базу данных Set db = Nothing ' Очистили объектную переменную ' (!) Плохой код: ' рабочая область, открытая по умолчанию, будет закрыта ' ws.Close ' Set ws = Nothing

Программа 16.2. Создание рабочей области Jet

 Dim ws As Workspace Dim db As Database ' Создаем рабочую область: Set ws = CreateWorkspace("", "Флинт", "пиастры", dbUseJet) ' Открываем базу данных: Set db = ws.OpenDatabase("DominationGameServer.mdb") ' Код использования базы данных ... db.Close ' Закрыли базу данных ws. Close "' ' Закрыли рабочую область Set db = Nothing " ' Очищаем объектные Set ws = Nothing ' переменные

Чтобы открыть базу данных, используйте существующий объект Database или создайте новый. Объект Database представляет собой базу данных Jet (файл MDB), базу данных ISAM или источник данных ODBC, подключенный через Jet.

Доступ к текущей базе данных осуществляется с помощью объекта типа Database, возвращаемого методом CurrentDb объекта Application (который представляет приложение Access). Метод CurrentDb входит в набор глобальных методов, поэтому для его вызова можно использовать сокращенную ссылку без префикса Application с точкой (программа 16.3).

Открыть существующую базу данных можно двумя способами:

  • с помощью метода OpenDatabase объекта Workspace. В этом случае база данных будет открыта в заданной рабочей области;
  • с помощью метода OpenDatabase объекта DBEngine. В этом случае база данных будет открыта в рабочей области, используемой по умолчанию.

Метод OpenDatabase объекта DBEngine входит в набор глобальных методов, поэтому при использовании сокращенной ссылки на этот метод без явного указания объекта (DBEngine или Workspace) используется метод объекта DBEngine. Метод OpenDatabase возвращает ссылку на созданный объект Database и имеет следующие параметры (табл. 16.3): Database OpenDatabase(, , , )

Параметр  Тип  Обязательный или нет  Описание 
String Обязательный Имя файла существующей базы данных (возможно, включая полный путь с указанием имени диска или сетевого ресурса) или имя источника данных ODBC (DSN)
Variant Необязательный Используется для задания специальных параметров базы данных. Например, в рабочей области Jet применяется значение True, если нужно открыть базу данных в режиме монопольного доступа, или значение False, если нужно открыть базу данных в режиме общего доступа. Значение False устанавливается по умолчанию. Параметры, используемые в рабочей области ODBCDirect, описаны в справочной системе Access
Variant (подтип Boolean) Необязательный Задается значение True, если нужно открыть базу данных только для чтения, или значение False, если нужно открыть базу данных для чтения и записи. По умолчанию используется значение False
Variant (подтип String) Необязательный Строка соединения (connection string). Используется для указания параметров соединения с источником данных, включая пароль

Таблица 16.3. Параметры метода OpenDatabase

Аналогично создать и открыть новую базу данных можно: D с помощью метода CreateDatabase объекта Workspace; П с помощью метода CreateDatabase объекта DBEngine. Глобальным является метод CreateDatabase объекта DBEngine.

Метод CreateDatabase создает новый объект Database, добавляет его в семейство Databases открытых баз данных в рабочей области, сохраняет базу данных на диске и возвращает открытый объект Database. Этот метод используется только в рабочей области ядра Microsoft Jet. Метод CreateDatabase имеет следующие параметры (табл. 16.4):

 Database CreateDatabase (, , )

Замечание

В программе на VBA для ссылки на метод CreateDatabase объекта DBEngine можно использовать сокращенную ссылку или указать префикс DBEngine с точкой. А для ссылки на метод объекта Workspace необходимо указать конкретную рабочую область, например:

 ' Использование метода объекта DBEngine: Set dbl = CreateDatabase(...) Set db2 = DBEngine.CreateDatabase(...) ' Использование метода объекта Workspace: Set db3 = Workspaces(0).CreateDatabase(...)
Параметр  Тип  Обязательный или нет  Описание 
Variant Обязательный Строковое выражение, опреде-(подтип ляющее порядок символов, кото-String) рый будет использоваться в операциях сравнения и сортировки в создаваемой базе данных. Допускается также создание пароля для нового объекта Database путем слияния строки пароля (начинающейся с символов «;pwd=») с константой в аргументе , например: DbLangCyrillic & » ; р»го>=МойПароль «
Необязательный Константа или комбинация констант, которая определяет один или несколько параметров: версию формата данных и режим шифрования или дешифрования базы данных во время сжатия. Константы приведены в справке Access
String Обязательный Имя файла создаваемой базы данных. Следует указать полный путь и имя файла, например «С: dbl .mdb» или «\serverlshareldirldbl». Если пользователь не указывает расширение имени, автоматически добавляется расширение mdb. Данный метод позволяет создавать только файлы mdb.

Таблица 16.4. Параметры метода CreateDatabase

Чтобы получить доступ к данным в открытой одним из перечисленных способов базе данных, необходимо открыть набор записей. Набор записей может представлять собой все записи таблицы или часть записей таблицы, удовлетворяющих указанному условию, или результат выборки из нескольких таблиц. Чтобы открыть набор записей в базе данных, используйте метод OpenRecordset объекта Database (см. программу 16.3). Этот метод возвращает ссылку на созданный объект Recordset и имеет следующие параметры (табл. 16.5):

 Recordset OpenRecordset(,, , )

Замечание

С помощью метода OpenRecordset в базе данных можно открыть связанную таблицу (точно так же, как и таблицу, хранящуюся в базе данных), указав ее имя.

Параметр  Тип  Обязательный или нет  Описание 
String Обязательный Источник записей для нового объекта Recordset. В качестве источника записей можно указать имя таблицы или запроса, а также инструкцию SQL, которая возвращает записи.
Необязательный Константа, указывающая тип открываемого объекта Recordset. Эти константы приведены в табл. 16.6.
Необязательный Произвольная комбинация определенных констант, задающих характеристики нового объекта Recordset. Эти константы приведены в справочной системе Access.
Необязательный Константа, определяющая тип блокировки объекта Recordset. Возможные константы перечислены в справке Access.

Таблица 16.5. Параметры метода OpenRecordset

Константа  Тип набора записей 
DbOpenTable Открытие табличного обьекта Recordset (только в рабочей области ядра Microsoft Jet)
DbOpenDynaset Открытие объекта Recordset типа динамического набора записей, аналогичного указателю ключевого набора записей ODBC
DbOpenDynamic Открытие обьекта Recordset динамического типа, аналогичного динамическому указателю ODBC (только в рабочей области ODBCDirect)
DbOpenSnapshot Открытие объекта Recordset типа статического набора записей, аналогичного указателю статического набора записей ODBC
DbOpenForwardOnly Открытие объекта Recordset типа статического набора записей с последовательным доступом

Таблица 16.6. Константы, определяющие тип набора записей

Далее приведен пример открытия таблицы, взятый из программного кода сервера приложения «Игра в доминирование» (программа 16.3).

Программа 16.3. Открытие таблицы в текущей базе данных

Dim db As Database Dim rs As Recordset ' Получаем доступ к текущей базе данных: Set db = CurrentDb ' Открываем таблицу сообщений для игрока (это связанная таблица): Set rs = db.OpenRecordset("Сообщения", dbOpenDynaset) ' Код использования таблицы ... . rs.Close ' Закрыли таблицу Set rs = Nothing ' Очистили объектные переменные Set db = Nothing

Для изменения схемы данных создан язык определения данных (DDL, Data-Definition Language). Инструкции на языке DDL позволяют выполнять действия по изменению схемы данных и структуры объектов данных, например:

  • создавать и удалять таблицы;
  • добавлять и удалять из таблиц поля и индексы;
  • создавать и удалять связи между таблицами.

В интерфейсе DАО имеется набор специальных объектов, который является интерфейсом для доступа к средствам DDL. Таким образом, с помощью объектов DАО можно управлять структурой таблиц и схемой данных, не составляя самих инструкций на языке DDL.

Следующий пример программного кода (программа 16.4) взят из процедуры initGame сервера приложения «Игра в доминирование». Этот пример иллюстрирует использование инструкций на языке DDL для удаления таблицы со старой структурой и создания новой таблицы с заданной структурой. Аналогичные действия можно выполнить, пользуясь объектно-ориентированным интерфейсом DАО. Целью этой процедуры является изменение структуры таблицы «ПолеИгрок», поэтому, вообще говоря, можно было бы изменить набор полей этой таблицы с помощью инструкции DDL ALTER TABLE. Эта инструкция позволяет удалить или добавить в таблицу поле или составной индекс. Удаление и добавление полей в таблицу средствами DDL через интерфейс DАО представлено в программе 16.5.

Замечание

Необходимо помнить о том, что изменение структуры связанных таблиц запрещено. Поэтому в примере (программы 16.4 и 16.5) для доступа к таблице «ПолеИгрок» открывается база данных DominationGame.mdb, в которой сохранена эта таблица, а не используется текущая база данных DominationGameServer.mdb, в которой установлена связь с этой таблицей.

Программа 16.4. Удаление и создание таблицы с помощью инструкций DDL

 Dim db As Database Dim fieldSize As Long, i As Long Dim strDDL As String ' Узнаем линейный размер игрового поля, выраженный в клетках fieldSize = CLng(get_parameter("РазмерПоля")) ' Открываем базу данных, в которой хранится нужная таблица Set db = OpenDatabase(CurrentProject.Path & "DominationGame.mdb")  '  Удалить старую таблицу "ПолеИгрок" strDDL = "DROP TABLE ПолеИгрок;" ' Если таблица не существует, удаление вызовет ошибку On Error GoTo the_next_2 db.Execute strDDL the_next_2: On Error GoTo 0 ' Создать новую таблицу "ПолеИгрок" strDDL = "CREATE TABLE ПолеИгрок (" For i = 1 To fieldSize - 1 strDDL = strDDL & get_column_name(i) & " TEXT(20), " Next i strDDL = strDDL & get_column_name(fieldSize)  & "  TEXT(20) );" db.Execute strDDL ' Прочие действия ... db.Close

Программа 16.5. Изменение структуры таблицы с помощью интерфейса DАО

 Dim db As Database Dim fieldSize As Long, i As Long Dim strSQL As String Dim fid As Field  '  Узнаем линейный размер игрового поля, выраженный в клетках fieldSize = CLng(get_parameter("РазмерПоля")) ' Открываем базу данных, в которой хранится нужная таблица Set db = OpenDatabase(CurrentProject.Path & "DominationGame.mdb") ' Удалить старые записи в таблице "ПолеИгрок" StrSQL = "DELETE * FROM ПолеИгрок;" db.Execute strSQL ' Удалить старые поля в таблице "ПолеИгрок" For i = 1 То db.TableDefs("ПолеИгрок").Fields.Count db.TableDefs("ПолеИгрок").Fields.Delete get_column_name(i) Next i ' 'Создать новые поля в таблице "ПолеИгрок" For i = 1 То fieldSize Set fid = db.TableDefs("ПолеИгрок").CreateField( _ get_column_name(i), dbText, 20) db.TableDefs("ПолеИгрок").Fields.Append fid Next I ' Прочие действия ... db.Close

В программе 16.5 проиллюстрировано удаление и добавление полей в таблицу «ПолеИгрок» средствами DDL с использованием интерфейса DАО. Удаление поля производится с помощью метода Delete, в качестве параметра которого указывается имя удаляемого поля. Добавление нового поля производится следующим образом. Создается новый объект Field, обладающий необходимыми характеристиками — заданным именем поля, типом и размером данных. После этого с помощью метода Append созданный объект Field добавляется в семейство Fields объекта TableDef, содержащее все поля таблицы «ПолеИгрок». Аналогично (с помощью DАО) можно выполнить создание и удаление таблиц и индексов.

Для изменения данных в источнике создан язык структурированных запросов (SQL, Structure Query Language). Инструкции на языке SQL позволяют выполнять действия по изменению данных, например — добавлять, изменять или удалять записи в таблице или запросе, выбирать набор записей из источника, удовлетворяющий заданному условию.

C помощью объектов DАО можно осуществлять всевозможные манипуляции с данными. Например, такие как:

  • получение набора записей из таблицы;
  • выполнение запроса SQL для получения набора записей;
  • использование запроса, сохраненного в базе данных в виде объекта;
  • использование набора методов объекта Recordset, предоставляющего широкие возможности по обработке данных: чтение, анализ и изменение данных без составления инструкций на языке SQL.

В следующих примерах приведены приемы программного изменения данных в открытом наборе записей (программы 16.6—16.8). Переменная rs соответствует открытому набору записей — объекту типа Recordset.

Программа 16.6. Добавление записи в таблицу

 ' Добавляем сообщение в таблицу сообщений клиента rs.AddNew ' Создание новой записи rs!ИмяИгрока = playerName ' Запись значения в поле ИмяИгрока rs!Сообщение = message ' Запись значения в поле Сообщение rs.Update ' Сохранение изменений в источнике rs.Bookmark = rs.LastModified ' Перемещение курсора на новую запись

Программа 16.7. Изменение текущей записи в таблице

 ' Увеличиваем счет игрока, сделавшего ход ' Делаем текущей запись, содержащую данные для нужного игрока rs.FindFirst " = '" & newPlayer & "'" rs.Edit ' Переводим запись в режим правки rs!Счет = rs!Счет + newCount ' Изменяем значение поля Счет rs.Update ' Сохраняем изменения rs.Bookmark = rs.LastModified ' Делаем измененную запись текущей

Программа 16.8. Удаление текущей записи в таблице

 playerQueryCode = rs!КодЗаявки ' Сохраняем параметры заявки playerTrial = rs!Значение ' во временных переменных rs.Delete ' и удаляем заявку из таблицы

Для перемещения по записям используются методы Move, MoveFirst, MoveNext, MovePrev, MoveLast объекта Recordset. Метод MoveLast перемещает курсор на последнюю запись в наборе, что приводит к загрузке в набор всех записей. После этого можно прочитать значение свойства Count объекта Recordset. Оно будет соответствовать общему количеству записей в наборе.

Замечание

Удаление записей и объектов из базы данных приводит к тому, что файл базы данных становится фрагментированным и место, занимаемое им на диске, используется нерационально. Чтобы дефрагментировать файл базы данных, используют процедуру сжатия. Ее можно выполнить с помощью команды Сервис, Служебные программы, Сжать и восстановить базу данных (Tools, Database Utilities, Compact and Repair Database) или программно — с помощью метода CompactDatabase объекта DBEngine. Можно также установить флажок Сжимать при закрытии (Compact on Close) в диалоговом окне Параметры (Options) (команда Сервис, Параметры (Tools, Options), вкладка Общие (General)), чтобы сжатие базы данных проводилось автоматически при ее закрытии. Подробнее процедура сжатия описана в гл. 20.

При одновременном доступе нескольких пользователей к одной и той же записи в источнике данных могут возникнуть конфликты. Например, конфликты могут возникать при выполнении метода Update или Delete объекта Recordset и метода OpenDatabase объекта Workspace или DBEngine. Предотвращение конфликтов зависит от настройки Access, касающейся методов блокировки записей, режима доступа к базе данных, периодов обновления данных. Об установке этих параметров мы уже говорили в разд. «Организация совместного доступа к данным и объектам» этой главы. Более подробную информацию можно найти в справочной системе Access.

При программном доступе к совместно используемым базам данных необходимо организовать собственную обработку ошибок, появляющихся при попытке выполнить операции, которые могут привести к возникновению конфликтов. В приложении «Игра в доминирование» используется метод блокировки на уровне записей, блокируются изменяемые записи. В этом случае при возникновении конфликта самым простым решением является ожидание момента, когда заблокированная запись будет освобождена другим пользователем. Этот подход достаточно просто реализовать в процедуре на VBA, используя оператор Resume для повторного выполнения действия через некоторый интервал времени (сделав паузу). Назовем этот способ синхронизацией доступа к данным.

Рассмотрим в качестве примера синхронизации функцию отправки сервером сообщения одному из игроков (программа 16.9). Вспомогательная функция doPause, позволяющая сделать паузу в работе приложения на заданное количество секунд, приведена в программе 16.10.

Программа 16.9. Синхронизация записи изменений в источнике данных

 ' Послать сообщение подключенному игроку Public Sub SendMessage(message As String, playerName As String) . ' Объявления локальных объектных переменных: Dim db As Database Dim rs As Recordset Dim counter As Integer ' Определяем собственную обработку ошибок: On Error GoTo errHandler Set db = CurrentDb ' Открываем таблицу сообщений для игрока: Set rs = db.OpenRecordset("Сообщения", dbOpenDynaset) On Error GoTo 0 ' Добавляем сообщение в таблицу сообщений клиента: rs.AddNew rs!ИмяИгрока = playerName rs!Сообщение = message ' Обработка ошибок, возникающих при совместном доступе ' к источнику данных: On Error GoTo tryAgain rs.Update On Error GoTo 0 rs.Bookmark = rs.LastModified ' Закрываем открытые объекты: closeAHHandler: rs.Close endHandler: ' Очищаем объектные переменные, т. к. они больше не используются: Set rs = Nothing Set db = Nothing ' Завершаем работу: Exit Sub ' Синхронизация: tryAgain: counter = counter + 1 If counter < 400 Then doPause 5 Resume End If Обработка ошибок: errHandler: Dim errMsg As String errMsg = "Ошибка: " & Err.Number & vbCrLf & _ "Источник: " & Err.Source & vbCrLf & _ vbCrLf & Err.Description MsgBox errMsg, vbCritical, ERR_TITLE Resume endHandler End Sub

Программа 16.10. Сделать паузу на заданное количество секунд в работе приложения

Public Sub doPause(seconds As Integer) Dim var_timeStart, var_timeCurrent Dim ftimeOut As Boolean var_timeStart = Time() ' Время начала паузы Do ' Передать управление другим процессам операционной системы DoEvents var_timeCurrent = Time() ' Текущее системное время ftimeOut = _ CDate(var timeCurrent - var timeStart) >= CDate(TimeSerial(0, 0, seconds)) Loop Until ftimeOut End Sub

Транзакцией называется операция обмена данными между клиентом и сервером. Методы объекта Workspace, использующиеся для выполнения транзакций, представлены в табл. 16.7.

Метод  Описание 
BeginTrans Обозначает начало транзакции. Транзакции могут быть вложенными
CommitTrans Обозначает конец транзакции. В этот момент все изменения сохраняются в источнике без возможности их отмены
RollBack Завершение транзакции и отмена результата ее выполнения. Записи в источнике возвращаются в прежнее состояние, отмеченное командой BeginTrans

Таблица 16.7. Методы объекта Workspace для выполнения транзакций

Все базы данных, открытые в рабочей области, имеют общую область действия транзакций. Это значит, что действие методов BeginTrans, CommitTrans и RollBack объекта Workspace распространяется на все базы данных в семействе Databases объекта Workspace.

Рассмотрим пример программы на VBA с использованием механизма выполнения транзакций (программа 16.11). В приложении «Игра в доминирование» механизм транзакций не используется.

Программа 16.11. Применение механизма транзакций

 Sub ResetCount () Dim ws As Workspace Dim db As Database Dim rs As Recordset Dim flnTrans As Boolean On Error GoTo errHandler ;.. flnTrans = False ' Транзакция еще не началась Set ws = DBEngine.Workspaces(0) Set db = CurrentDb Set rs = db.OpenRecordset("Игроки", dbOpenTable) ws.BeginTrans ' Начало транзакции flnTrans = True ' Транзакция началась rs.MoveFirst Do Until rs.EOF rs.Edit rs!Счет = 0 rs.Update rs.MoveNext Loop If MsgBox("Сохранить сделанные изменения?", _ vbQuestion + vbYesNo, "Вопрос") = vbYes Then ws.CommitTrans ' Сохранить изменения Else ws.Rollback ' Отменить изменения End If exitHandle: rs.Close Set db = Nothing Set ws = Nothing Exit Sub errHandler: MsgBox "Ошибка!" ' Если ошибка возникла в процессе выполнения транзакции, ' отменяем сделанные изменения If flnTrans Then ws.Rollback End If Resume exitHandle End Sub

Выбор политики защиты и установка защиты — предмет разработки приложения. А настройка схемы защиты приложения в соответствии с текущими потребностями в процессе использования приложения — задача администрирования. Администратор управляет составом пользователей и групп пользователей приложения и предоставляет им необходимые права доступа к объектам приложения по мере необходимости. Разработчик приложения предварительно определяет политику защиты приложения, выполняет установку защиты приложения и подготавливает приложение к использованию — определяет начальный состав пользователей и групп пользователей приложения и выполняет начальное распределение между ними прав доступа к объектам приложения. Таким образом, в процессе установки защиты приложения разработчик, помимо прочих действий, в определенный момент выполняет функции администратора.

Действия, которые выполняет администратор защищенного приложения, описаны в гл. 20. В этой главе мы расскажем о действиях, выполняемых разработчиком, связанных с установкой защиты и определением политики защиты приложения.

Определение политики защиты включает решение следующих вопросов:

  • какова степень защиты приложения;
  • по какому принципу производится выделение групп пользователей;
  • по какому принципу организуется разграничение прав доступа между отдельными пользователями и группами;
  • какие права доступа необходимо задать по умолчанию.

Например, разработчик может решить, предоставить ли разрешение другим пользователям просматривать или выполнять запрос без изменения данных или структуры запроса, задать ли права по умолчанию для всех запросов.

Администратор приложения обладает всеми необходимыми правами для изменения политики защиты приложения, но необходимости в этом не должно возникать. Ведь в задачу разработчика приложения входить выбор наиболее подходящей политики защиты, которая удовлетворяет требованиям, предъявляемым к приложению, и упрощает процесс администрирования.

Защита на уровне пользователей предназначена для предоставления разным пользователям разного уровня доступа к объектам приложения. Пользователи могут объединяться в группы внутри рабочей группы. Группам, как и пользователям, могут быть назначены определенные права доступа к объектам базы данных.

Существует два типа прав доступа, предоставляемых пользователю: явные и неявные. Явные права доступа — те, что назначены непосредственной учетной записи пользователя. Неявные права доступа — те, что назначены учетной записи группы, в которую входит этот пользователь. Добавление пользователя в группу приводит к предоставлению пользователю прав, назначенных группе. Удаление пользователя из группы лишает пользователя этих прав.

Права пользователя на доступ к объекту складываются из его явных и неявных прав. В системе защиты на уровне пользователей Microsoft Access, в отличие от системы защиты на уровне пользователей файловой системы NTFS, применяется политика «наименьших ограничений». Это означает следующее: если пользователю (который может входить в разные группы, обладающие различными правами доступа) назначены и разрешающие и запрещающие права к некоторому объекту базы данных Access, то доступ к объекту пользователю предоставляется.

Группы пользователей делают управление правами доступа более удобным. Вместо того чтобы каждый раз при введении нового пользователя в рабочую группу прелоетавлять ему все необходимые права к объектам базы данных, можно назначить эти права группе. Тогда процесс предоставления заданных прав доступа сведется к добавлению нового пользователя в эту группу.

Рабочей группой в Access называется группа пользователей сети, совместно использующих одну или несколько баз данных Access. Если база данных защищена на уровне пользователей, в файл рабочей группы (файл с расширением mdw) записываются учетные записи пользователей и групп, входящих в рабочую группу. Пароли пользователей также хранятся в файле рабочей группы. Учетным записям в рабочей группе могут быть назначены права доступа к базе данных и ее объектам — таблицам, запросам, формам, отчетам и макросам. Права доступа сохраняются в защищенной базе данных.

Замечание

В ранней версии Access 97 в файле рабочей группы сохранялась также информация о настройках Access, заданных пользователем в окне Параметры (Options). В Access 2000 и Access 2002 эти настройки сохраняются в реестре Windows, в разделах:

HKEY_CURRENT_USERSoftwareMicrosoft: