Для работы с базами данных формата DBF в системе имеется специальный объект – XBase. Механизм работы с базами данных формата DBF предназначен для обеспечения возможности манипулирования ими непосредственно из встроенного языка системы «1С:Предприятие». Возможно практически любое манипулирование данными.
Помимо работы с существующими базами данных, объект XBase имеет набор методов, позволяющих создать новую базу данных произвольной структуры, новые индексы и новый индексный файл. Следует отметить, что если использование методов, изменяющих структуру базы данных, возможно только для объектов, не связанных с существующей базой данных (т. е. для вновь создаваемых баз данных), то создание новых индексов и индексного файла возможно как для создаваемых баз данных, так и для уже существующих и открытых.
Для записи данных в файл DBF может использоваться следующий фрагмент кода (листинг 6.154).
Листинг 6.154. Пример записи данных в файл DBF
&НаКлиенте
Процедура ЗаписьДанных(Команда)
Путь = "c:\temp\";
БД = Новый XBase;
БД.Поля.Добавить("CODE", "S", 9);
БД.Поля.Добавить("NAME", "S", 40);
БД.Поля.Добавить("DATA_B", "S", 10);
БД.Поля.Добавить("CHILD", "S", 1);
БД.СоздатьФайл(Путь + "list.dbf", Путь + "index.cdx");
БД.Индексы.Добавить("IDXCODE", "CODE");
ИБД = БД.СоздатьИндексныйФайл(Путь + "index.cdx");
БД.АвтоСохранение = Истина;
// Получить данные сотрудников в виде одной большой строки.
СтрокаРазделителя = "*";
СтрокаСотрудников = ПолучитьСтрокиСотрудников(СтрокаРазделителя);
// Получить массив строк для каждого сотрудника.
СтрокиСотрудников = СтрРазделить(СтрокаСотрудников, Символы.ПС);
Для ТекущаяСтрока = 0 По СтрокиСотрудников.Количество() 1 Цикл
// Получить данные каждого сотрудника.
Данные = СтрРазделить(СтрокиСотрудников[ТекущаяСтрока], СтрокаРазделителя);
БД.Добавить();
БД.CODE = Данные[0];
БД.NAME = Данные[1];
БД.DATA_B = Данные[2];
БД.CHILD = Данные[3];
КонецЦикла;
БД.ЗакрытьФайл();
КонецПроцедуры
Создается файл, у которого определяются четыре поля (CODE, NAME, DATA_B, CHILD). Все поля имеют строковый тип.
У создаваемого DBF-файла определяется один индексный файл. Следует отметить, что у DBF-файла может быть определено несколько индексов, но создаваемый при этом индексный файл всегда один.
При записи данных следует обращать внимание на свойство АвтоСохранение объекта XBase. Если оно установлено в значение Истина, то добавление записи в файл производится при вызове следующего метода Добавить(), создающего новую запись.
Из процедуры ЗаписьДанных() вызывается серверная функция ПолучитьСтрокиСотрудников(), в которой в цикле обхода выборки элементов справочника Сотрудники формируются строки с данными сотрудников и в виде одной большой строки возвращаются на клиент (см. листинг 6.155).
Затем из этой строки получается массив строк с данными для каждого сотрудника и каждая строка разбирается на структуры с помощью функции глобального контекста СтрРазделить(). Полученные структуры с данными каждого сотрудника записываются в соответствующие поля новой записи DBF-файла.
Листинг 6.155. Функция «ПолучитьСтрокиСотрудников()»
&НаСервере
Функция ПолучитьСтрокиСотрудников(Разделитель)
СтрокаСотрудника = Новый Массив();
МассивСтрокСотрудников = Новый Массив();
Выборка = Справочники.Сотрудники.Выбрать();
Пока Выборка.Следующий() Цикл
СтрокаСотрудника.Очистить();
СтрокаСотрудника.Добавить(Выборка.Код);
СтрокаСотрудника.Добавить(Выборка.Наименование);
СтрокаСотрудника.Добавить(Формат(Выборка.ДатаРождения, "ДЛФ=D"));
СтрокаСотрудника.Добавить(Выборка.КоличествоДетей);
Данные = СтрСоединить(СтрокаСотрудника, Разделитель);
МассивСтрокСотрудников.Добавить(Данные);
КонецЦикла;
Возврат СтрСоединить(МассивСтрокСотрудников, Символы.ПС);
КонецФункции
Для чтения данных может использоваться следующий фрагмент кода (листинг 6.156).
Листинг 6.156. Пример чтения данных из файла DBF
&НаКлиенте
Процедура ЧтениеДанных(Команда)
Путь = "c:\temp\";
БД = Новый XBase;
БД.ОткрытьФайл(Путь + "list.dbf", Путь + "index.cdx");
Сообщение = Новый СообщениеПользователю();
Пока Истина Цикл
Сообщение.Текст = БД.CODE + " " + БД.Name;
Сообщение.Сообщить();
Если Не БД.Следующая() Тогда
Прервать;
КонецЕсли;
КонецЦикла;
БД.ЗакрытьФайл();
КонецПроцедуры
В приведенном фрагменте не используется определенный при записи индекс, порядок отображения данных может быть следующий (фактически это соответствует физическому положению записей в файле) – листинг 6.157.
Листинг 6.157. Порядок отображения данных
000000001 Алексеев Сергей Иванович
REST-0003 Артемов Игорь Владимирович
000000002 Смирнова Светлана Ивановна
Изменим код, добавив в него использование индекса (листинг 6.158).
Листинг 6.158. Пример чтения данных из файла DBF
&НаКлиенте
Процедура ЧтениеДанных(Команда)
Путь = "c:\temp\";
БД = Новый XBase;
БД.ОткрытьФайл(Путь + "list.dbf", Путь + "index.cdx");
БД.ТекущийИндекс = БД.Индексы.IDXCODE;
Сообщение = Новый СообщениеПользователю();
Пока Истина Цикл
Сообщение.Текст = БД.CODE + " " + БД.Name;
Сообщение.Сообщить();
Если Не БД.Следующая() Тогда
Прервать;
КонецЕсли;
КонецЦикла;
БД.ЗакрытьФайл();
КонецПроцедуры
В этом случае в результате будут получены следующие записи, отсортированные в порядке возрастания кодов сотрудников (листинг 6.159).
Листинг 6.159. Порядок отображения данных
000000001 Алексеев Сергей Иванович
000000002 Смирнова Светлана Ивановна
REST-0003 Артемов Игорь Владимирович
При этом надо иметь в виду, что при открытии файла объект XBase позиционируется на записи, которая является физически первой в файле. Однако с точки зрения используемого индекса она может быть далеко не первой. При выполнении метода Следующая() выбирается следующая запись в индексном файле. Поэтому, для того чтобы обойти все записи, необходимо явно использовать метод Первая(), как показано ниже (листинг 6.160).
Листинг 6.160. Пример использования метода «Первая()»
&НаКлиенте
Процедура ЧтениеДанных(Команда)
Путь = "c:\temp\";
БД = Новый XBase;
БД.ОткрытьФайл(Путь + "list.dbf", Путь + "index.cdx");
БД.ТекущийИндекс = БД.Индексы.IDXCODE;
Сообщение = Новый СообщениеПользователю();
БД.Первая();
Пока Истина Цикл
Сообщение.Текст = БД.CODE + " " + БД.Name;
Сообщение.Сообщить();
Если Не БД.Следующая() Тогда
Прервать;
КонецЕсли;
КонецЦикла;
БД.ЗакрытьФайл();
КонецПроцедуры
Индексы полезно использовать не только для упорядочивания выборок записей по какому-либо полю, но и для реализации каких-либо «поисковых механизмов». Рассмотрим следующий пример (листинг 6.161).
Листинг 6.161. Пример поиска данных в файле DBF
&НаКлиенте
Процедура ПоискДанных(Команда)
Путь = "c:\temp\";
БД = Новый XBase;
БД.ОткрытьФайл(Путь + "list.dbf", Путь + "index.cdx");
БД.ТекущийИндекс = БД.Индексы.IDXCODE;
Сообщение = Новый СообщениеПользователю();
Если БД.Найти("000000002", "=") Тогда
Пока Истина Цикл
Сообщение.Текст = БД.CODE + " " + БД.Name;
Сообщение.Сообщить();
Если Не БД.Следующая() Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
БД.ЗакрытьФайл();
КонецПроцедуры
В результате будут получены только две записи (листинг 6.162).
Листинг 6.162. Порядок отображения данных
000000002 Смирнова Светлана Ивановна
REST-0003 Артемов Игорь Владимирович
Менять текущий индекс можно и во время выборки (однако следует помнить, что при «умелой» манипуляции индексами можно никогда не достигнуть конца DBF-файла).