ПРОЦЕДУРЫ ПЕРЕНОСА ДАННЫХ
Вторым осложняющим обстоятельством является то, что реквизиты Образование, ПриказОклац, ПриказПрием и Календарь имеют типы, которые в чистом виде нельзя воспроизвести в DBF-файле. (Средствами 1С в DBF-файле можно определить числовые, символьные, логические поля и поля типа Дата.) Поэтому нам придется некоторым образом заменить значения этих реквизитов на значения стандартных типов, но таким образом, чтобы иметь возможность восстановить при обратном преобразовании исходные величины. Замены будем выполнять в соответствии с правилами, изложенными в табл. 9.4.
Таблица 9.4
Правила преобразования значений объектов 1С |
Объект 1С |
На что заменяется в DBF-файле |
Элемент справочника |
Идентификатор справочника и код элемента |
Документ |
Идентификатор документа и номер документа |
Календарь |
Идентификатор календаря |
|
И наконец, третий осложняющий фактор в том, что, кроме данных о сотрудниках, справочник содержит группы, отражающие имена подразделений предприятия, а также описывает иерархию групп и сотрудников (см. табл. 5.1). В создаваемом файле эти сведения также надо сохранить.
Таким образом, файл employee.dbf будет иметь отраженные в табл. 9.5 поля. |
Таблица 9.5
Поля файла employee.dbf |
Имя DBF-
поля |
Имя 1C-
реквизита |
Свойства DBF-поля |
Описание |
Id |
Код |
Числовое поле формата 5.0 |
Код сотрудника или группы |
Parentld |
- |
"" 5.0 |
Ссылка на группу, в которую входит текущий элемент |
IsGroup |
- |
Логическое поле |
Имеет значение истина, если элемент является группой, или ложь -в противном случае |
Name |
Наименование |
Строка из 30 символов |
ФИО сотрудника или имя группы |
Ed |
Образование |
Строка из 13 символов |
Имеет значение Образование_2 |
EdId |
|
Числовое поле формата 3.0 |
Код соответствующей записи в справочнике Образование_2 |
|
Имя DBF-
поля |
Имя 1C-реквизита |
Свойства DBF-поля |
Описание |
OrderEng |
ПриказПрием |
Строка из 15 символов |
Имеет значение ПриказОПриеме |
OrderEngld |
" |
Числовое поле формата 5.0 |
Номер приказа о приеме на работу |
OrderSal |
ПриказОклад |
Строка из 13 символов |
Имеет значение ИзменениеОклада |
OrderSalld |
" |
Числовое поле формата 5.0 |
Номер приказа об изменении оклада |
Calendar |
Календарь |
Строка из 9 символов |
Идентификатор календаря |
|
Очевидно, что, имея файлы employee.dbf и salary.dbf, можно полностью восстановить справочник Сотрудники_2. Правда, восстановленный справочник не будет точной копией оригинала. |
9.З.1.2.
Во-первых, нужно по известной структуре справочника Сотрудники_2 и по изложенным правилам преобразования данных создать файлы employee.dbf и salary.dbf. Предварительно, однако, мы в процедуре АтрСвойства сформируем таблицу значений, содержащую преобразованное в соответствии с табл. 9.5 описание атрибутов (реквизитов) справочника Сотрудники_2. Для этого нам придется воспользоваться объектом Метаданные. Запустим процедуру АтрСвойства из обработки Проба и просмотрим п о-лученный результат.
процедура АтрСвойства(тЗнач) далее
процедура ЕщеОднаСтрока(тЗнач, видСпр, типРек, ин, кон) далее
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем тЗнач;
ОчиститьОкноСообщений();
// Формируем таблицу с описанием реквизитов справочника Сотрудники_2 АтрСвойства(тЗнач);
// Просмотр таблицы значений. Результат см. на рис. 9.3
тЗнач.ВыбратьСтроку(, "Преобразованные реквизиты справочника Сотрудники_2"); конецПроцедуры // Выполнить
// Возвращает таблицу значений, содержащую преобразованное описание // атрибутов справочника Сотрудники_2 процедура АтрСвойства(тЗнач) перем видСпр;
тЗнач = СоздатьОбъект("ТаблицаЗначений");
видСпр = "Сотрудники_2"; // Вид справочника
// Формируем столбцы таблицы значений
тЗнач. НоваяКолонка(''Идентификатор", "Строка");
тЗнач. НоваяКолонка("Тип", "Строка");
тЗнач. НоваяКолонка("Длина", "Число");
тЗнач.НоваяКолонка(''Точность", "Число");
тЗнач.НоваяКолонка("Периодический"," Число");
// Запишем в таблицу значений идентификатор, тип, длину и точность реквизитов // справочника Сотрудники_2. Длина записывается для символьных и числовых // реквизитов, а точность - только для числовых
// Два первых реквизита - это атрибуты Код и Наименование справочника
тЗнач.НоваяСтрока(); // Добавляем новую строку в таблицу значений
// Атрибут Код
тЗнач.Идентификатор = "Код";
тЗнач.Тип = Метаданные.Справочник(видСпр).ТипКода; тЗнач.Длина = Метаданные.Справочник(видСпр).ДлинаКода; тЗнач.Точность = 0; тЗнач.Периодический = 0;
тЗнач.НоваяСтрока(); // Еще одна новая строка
// Атрибут Наименование тЗнач.Идентификатор = "Наименование"; тЗнач.Тип = "Строка";
тЗнач.Длина = Метаданные.Справочник(видСпр).ДлинаНаименования; тЗнач.Точность = 0; тЗнач.Периодический = 0;
// Реквизиты справочника Сотрудники_2
// Напоминаем, что реквизиты типа Справочник и Документ порождают 2 DBF-поля,
// поэтому для них в тЗнач выделяем две строки для ин = 1 по Метаданные.Справочник(видСпр).Реквизит() цикл // Тип реквизита
типРек = Метаданные.Справочник(видСпр).Реквизит(ин).Тип;
// Очередная новая строка
ЕщеОднаСтрока(тЗнач, видСпр, типРек, ин, ""); если (типРек = "Справочник") или (типРек = "Документ") тогда // Очередная новая строка
ЕщеОднаСтрока(тЗнач, видСпр, типРек, ин, "2"); конецЕсли; конецЦикла;
конецПроцедуры // АтрСвойства
// Добавляет новую строку в таблицу значений тЗнач процедура ЕщеОднаСтрока(тЗнач, видСпр, типРек, ин, кон)
перем обВид; // Разновидность типа объекта
// кон = "", если добавляется первая строка для справочника или документа // кон = "2", если добавляется вторая строка для справочника или документа тЗнач.НоваяСтрока();
если (типРек = "Число") или (типРек = "Строка") или (типРек = "Дата") тогда тЗнач.Идентификатор =
Метаданные.Справочник(видСпр). Реквизит(ин). Идентификатор; тЗнач.Тип = типРек;
тЗнач.Длина = Метаданные.Справочник(видСпр).Реквизит(ин).Длина; иначе // Справочник, Документ или Календарь
если типРек = "Календарь" тогда тЗнач.Идентификатор =
Метаданные.Справочник(видСпр).Реквизит(ин).Идентификатор;
иначе
обВид = Метаданные.Справочник(видСпр).Реквизит(ин).Вид; тЗнач.Идентификатор = обВид + кон; конецЕсли;
если кон = "" тогда
тЗнач.Тип - "Строка";
тЗнач.Длина = СтрДлина(тЗнач.Иденгификатор); иначе // кон = 2
тЗнач.Тип = "Число"; если типРек = "Справочник" тогда
тЗнач.Длина = Метаданные.Справочник(обВид).ДпишКода; иначе // типРек = "Документ"
тЗнач.Длина = МетаданныеДокумент(обВид)ДлинаНомера; конецЕсли; конецЕсли; конецЕсли;
тЗнач.Точность = Метаданные.Справочник(видСпр).Реквизит(ин).Точность; тЗнач.Периодический = Метаданные.Справочник(видСпр).Реквизит(ин).Периодический; конецПроцедуры // ЕщеОднаСтрока
 |
Рис. 9.3. Результат работы процедуры АтрСвойства |
Замечания:
1. Процедуры АтрСвойства и ЕщеОднаСтрока показывают, что объект Метаданные обеспечивает доступ к значению любого компонента структуры объекта агрегатного типа.
2. Примеры структур метаданных системы приведены в прил. 1.
Теперь таблица тЗнач содержит практически все необходимые данные для создания файла employee.dbf. Осталось только заменить значения столбца Идентификатор на соответствующие имена полей файла employee.dbf. Выполним эти замены в процедуре ДляДБФ. В процедуре СоздатьПоляДБФ подготовим, пользуясь данными таблицы значений тЗнач, поля для файла employee.dbf, а в процедуре СоздатьСотр сформируем файл employee.dbf и его индексы.
Перенос данных в файл employee.dbf выполнит процедура ПеренестиСотр, обраб а-тывающая справочник Сотрудники_2 по следующему алгоритму:
1. Начало.
2. Выполнить выборку элементов справочника Сотрудники_2.
3. Для каждого элемента найти переносимые в DBF-поля значения.
4. Создать новую запись в файле employee.dbf и перенести в нее найденные в п. 3 значения.
5. Конец.
Для выбранного сотрудника пп. 3 и 4 алгоритма реализует следующий код:
дбф.Добавить();
дбф.И = сСотр_2.Код;
дбф. ParentId= сСотр_2. Родитель. Код;
дбф.IsGroup = сСотр_2.ЭтоГруппа();
дбф.Name = сСотр_2. Наименование;
дбф.Ed = сСотр_2.0бразование.Вид();
дбф^И = сСотр_2.Образование.Код;
дбф.QrderEng = сСотр_2.ПриказПрием.Вид();
дбф.OrderEngId = сСотр_2.ПриказПрием.НомерДок;
дбф.OrderSal = сСотр_2.ПриказОклад.Вид();
дбф.OrderSalId = сСотр_2.ПриказОклад.НомерДок;
дбф.Calendar = сСотр_2.Календарь.Вид();
дбф.3аписать();
Создание файла salary. dbf осуществит процедура СоздатьОклад, принимающая объект дбф2, содержащий поля файла, сформированные в процедуре СоздатьПоля-ДБФ. Предварительно, однако, мы, как и в случае файла employee.dbf, сформируем в процедуре ДляДБФ2 таблицу значений тЗнач, на основании которой процедурой СоздатьПоляДБФ будут созданы поля файла salary.dbf.
Заполнение файла salary.dbf выполним в процедуре ПеренестиОклад по схеме, реализованной в примере 3 разд. 6.1. Процедура ПеренестиОклад вызывается для выбранного сотрудника в процедуре ПеренестиСотр.
Итоговый код переноса будет таким:
процедура АтрСвойства(тЗнач) далее
процедура ЕщеОднаСтрока(тЗнач, видСпр, типРек, ин, кон) далее
процедура ДляДБФ(тЗнач) далее
процедура СоздатьПоляДБФ(тЗнач, дбф, пРекв) далее
процедура СоздатьСотр(дбф) далее
процедура ДляДБФ2(тЗнач) далее
процедура СоздатьОклад(дбф) далее
процедура ПеренестиСотр(дбф, дбф2) далее
процедура ПеренестиОклад(сотр, оп, дбф) далее
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем тЗнач, дбф, дбф2;
ОчиститьОкноСообщений();
// Формируем таблицу с описанием реквизитов справочника Сотрудники_2 АтрСвойства(тЗнач);
// Готовим таблицу значений тЗнач для процедуры создания файла employee.dbf ДляДБФ(тЗнач);
// Просмотр таблицы значений. Результат см. на рис. 9.4 тЗнач.ВыбратьСтроку(, "Свойства полей файла employee.dbf);
СоздатьПоляДБФ(тЗнач, дбф, 0); // Создаем поля файла employee.dbf
СоздатьСотр(дбф); // Создаем файл employee.dbf
ДляДБФ2(тЗнач);
// Просмотр таблицы значений. Результат см. на рис. 9.5 тЗнач.ВыбратьСтроку(, "Свойства полей файла salary.dbf);
СоздатьПоляДБФ(тЗнач, дбф2, 1); // Создаем поля файла salary.dbf
// Готовим таблицу значений тЗнач для процедуры создания файла salary.dbf СоздатьОклад(дбф2); // Создаем файл salary.dbf
// Перенос данных в файлы employee.dbf и salary.dbf.
// Вызывает процедуру ПеренестиОклад. Результаты см. на рис. 9.6 и 9.7 ПеренестиСотр(дбф, дбф2);
Предупреждение('Тотово."); конецПроцедуры // Выполнить
// Код процедур АтрСвойства и ЕщеОднаСтрока см. выше
// Заменяет в таблице значений тЗнач данные столбца Идентификатор,
// на соответствующие имена поле файла employee.dbf. Вставляет также две // строки для полей Parentld и IsGroup файла employee.dbf процедура ДляДБФ(тЗнач)
перем сЗнач, ин, поз, имяПоля, номСтроки, колСтрок;
// Список значений сЗнач содержит перечень соответствий между именами // DBF-полей файла employee.dbf и значениями столбца Идентификатор таблицы тЗнач сЗнач = СоздатьОбъект("СписокЗначений"); сЗнач.ДобавитьЗначение("Код", " Id"); сЗнач.ДобавитьЗначение("Наименование", "Name"); сЗнач.ДобавитьЗначение("Оклад", "Salary"); сЗначДобавитьЗначение("Образование_2", "Ed"); сЗнач.ДобавитьЗначение("Образование_22"; "Edld"); сЗнач.ДобавитьЗначение("ПриказОПриеме", "OrderEng"); сЗнач.ДобавитьЗначение("ПриказОПриеме2", "OrderEngld"); сЗнач.ДобавитьЗначение("ИзменениеОклада", "OrderSal"); сЗнач.ДобавитьЗначение("ИзменениеОклада2", "OrderSalld"); сЗнач.ДобавитьЗначение("Календарь", "Calendar"); тЗнач.ВыбратьСтроки();
// Заносим вместо имеющегося в столбце Идентификатор значения имя DBF-поля пока тЗнач.ПолучитьСтроку() = 1 цикл
поз = сЗнач.НайтиЗначение(тЗнач.Идентификатор); если поз > 0 тогда
сЗнач.ПолучитьЗначение(поз, имяПоля); тЗнач.Идентификатор = имяПоля; конецЕсли; конецЦикла; // пока
// Добавляем данные для двух полей файла employee.dbf- ParentID и IsGroup,
// а затем располагаем добавленные строки вслед за первой строкой таблицы тЗнач тЗнач. НоваяСтрока(); тЗнач.Идентификатор = "ParentID"; тЗнач.Тип = "Число";
// Длина поля ParentID равна длине поля ID
тЗнач.НайтиЗначение("И", номСтроки, 1);
тЗнач.Длина = тЗнач.ПолучитьЗначение(номСтроки, 3);
тЗнач.Точность = 0;
тЗнач.Периодический = 0;
тЗнач. НоваяСтрока();
тЗнач.Идентификатор = "IsGroup";
тЗнач.Тип = "Логический"; тЗнач.Длина= 1; тЗнач.Точность - 0; тЗнач.Периодический = 0;
// Сдвигаем новые строки вверх колСтрок = тЗнач.КоличествоСтрок(); тЗнач.СдвинутьСтроку(2 - колСтрок, колСтрок); тЗнач.СдвинутьСтроку(2 - колСтрок, колСтрок); конецПроцедурЫ // ДляДБФ
// Создает на основе таблицы значений тЗнач поля DBF-файл процедура СоздатьПоляДБФ(тЗнач, дбф, пРекв)
// Формальный параметр пРекв = 1, если создается поле для периодического реквизита,
// или пРекв = 0 - в противном случае
перем имяПоля, типПоля;
дбф = СоздатьОбъект("ХВаse");
тЗнач.ВыбратьСтроки();
// Каждая строка таблицы значений тЗнач, отвечающая непериодическому реквизиту // справочника Сотрудники2, порождает одно DBF-поле пока тЗнач.ПолучитьСтроку() = 1 цикл
// Значения периодических реквизитов размещаются в отдельной таблице // (в нашем случае речь идет о периодическом реквизите Оклад) если (тЗнач.Периодический = 1) и (пРекв = 0) тогда
продолжить; // Пропускаем периодический реквизит
конецЕсли;
имяПоля = тЗнач.Идентификатор;
если (тЗнач.Тип = "Число") или (тЗнач.Тип = "Числовой") тогда типПоля = "N";
иначеЕсли тЗнач.Тип = "Строка" тогда типПоля = "S";
иначеЕсли тЗнач.Тип = "Дата" тогда типПоля = "D";
иначеЕсли тЗнач.Тип = "Логический" тогда типПоля = "L"; конецЕсли;
дбф.ДобавитьПоле(имяПоля, типПоля, тЗнач.Длина, тЗнач.Точность); конецЦикла; // пока конецПроцедуры // СоздатьПоляДБФ
процедура СоздатьСотр(дбф) // Создает файл employee. dbf
// Создаем два индекса
// Индекс Name обеспечит сортировку по значению поля Name дбф.ДобавитьИндекс("№те", "Name", 0, 0,"");
// Индекс Depart обеспечить сортировку по группам (поле Parentld),
// а в пределах групп по полю Name
дбф.ДобавитьИндекс("Depart", "trim(str(ParentId)) + Name", 0, 0, ""); дбф.СоздатьФайл("employee.dbf, "employee. cdx"); конецПроцедуры // СоздатьСотр
// Готовит таблицу значений тЗнач для создания файл salary.dbf процедура ДляДБФ2(тЗнач)
перем сЗнач, ин, значен, предст, номСтроки, тЗнач2, колСтрок;
// Модифицируем таблицу значений тЗнач в соответствии с табл. 9.2 //Для этого создадим список значений сЗнач, содержащий соответствия между // старыми и новыми значениями поля Идентификатор таблицы тЗнач // Строки таблицы значений тЗнач, не отраженные в списке сЗнач, удаляются сЗнач = СоздатьОбъект("СписокЗначений"); сЗнач.ДобавитьЗначение("Ы", "Id"); сЗнач.ДобавитьЗначение("OrderSal", "DocName"); сЗнач.ДобавитьЗначение("OrderSalId", "DocId"); сЗнач.ДобавитьЗначение("Salary", " Salary");
// Перемещаем строки, отраженные в списке сЗнач, в верх таблицы значений тЗнач // и делаем предписанные списком сЗнач замены имен для ин = 1 по сЗнач.РазмерСписка() цикл
значен = сЗнач.ПолучитьЗначение(ин, предст); номСтроки = 0;
тЗнач.НайтиЗначение(значен, номСтроки, 1);
// Изменения значения поля Идентификатор в соответствии со списком сЗнач тЗнач.УстановитьЗначение(номСтроки, 1, предст); тЗнач.СдвинутьСтроку(ин - номСтроки, номСтроки); конецЦикла; // для
// Выгружаем строки, отраженные в списке сЗнач, в таблицу тЗнач2 тЗнач2 = СоздатьОбъект("ТаблицаЗначений"); тЗнач.Выгрузить(тЗнач2, 1, сЗнач.РазмерСписка());
// Переносим таблицу тЗнач2 в таблицу тЗнач т3нач.3агрузить(т3нач2);
тЗнач2 = 0; // Более таблица значений тЗнач2 не нужна
// Добавляем в тЗнач строку для даты и перемещаем ее на вторую позицию таблицы
тЗнач.НоваяСтрока(); // Добавляем новую строку в таблицу значений
тЗнач.Идентификатор = "Date";
тЗнач.Тип = "Дата";
тЗнач.Длина = 0;
тЗнач.Точность = 0;
тЗнач.Периодический = 0;
// Ставим строку с датой на вторую позицию колСтрок = тЗнач.КоличествоСтрок(); тЗнач.СдвинутьСтроку(2 - колСтрок, колСтрок); конецПроцедуры // ДляДБФ2
процедура СоздатьОклад(дбф) // Создает файл salary.dbf
// Создаем один индекс
// Индекс IdDate обеспечит сортировку по дате в пределах заданного кода сотрудника дбф.ДобавитьИндекс("IdDate", "str(Id) + dtos(Date)", 0, 0,""); дбф.СоздатьФайл("salary.dbf, "salary. cdx"); конецПроцедуры // СоздатьОклад
// Заполняет файл employee.dbfи вызывает процедуру ПеренестиОклад, которая добавляет //данные в файл salaIy.dbfдля выбранного сотрудника процедура ПеренестиСотр(дбф, дбф2) перем сСотр_2, оп;
// Создаем объект типа Периодический для работы с файлом
оп = СоздатьОбъектС'Периодический");
сСотр_2 = СоздатьОбъект("Справочник.Сотрудники_2");
сСотр_2.ВыбратьЭлементы();
пока сСотр_2.ПолучитьЭлемент() = 1 цикл
дбф.Добавить(); // Новая запись в файле employee.dbf
дбф.Id = сСотр_2.Код;
дбф.PaгentId = сСотр_2.Родитель.Код;
дбф.ЕОгоир = сСотр_2.ЭтоГруппа();
дбф.№те = сСотр_2.Наименование;
дбф.Ed = сСотр_2.0бразование.Вид();
дбф.EdId = сСотр_2.0бразование.Код;
дбф.OгdeгEng = сСотр_2.ПриказПрием.Вид();
дбф.OгdeгEngId = сСотр_2.ПриказПрием.НомерДок;
дбф.OгdeгSal = сСотр_2.ПриказОклад.Вид();
дбф.ОМейаІИ = сСотр_2.ПриказОклад.НомерДок;
дбф.Calendaг = сСотр_2.Календарь.Вид();
дбф.3аписать(); // Сохраняем данные
// Если выбран сотрудник, а не группа если сСотр_2.ЭтоГруппа() = 0 тогда
// Добавляем данные об окладе текущего сотрудника в файл salary.dbf ПеренестиОклад(сСотр_2, оп, дбф2); конецЕсли; конецЦикла // пока конецПроцедуры // ПеренестиСотр
// Добавляет для сотрудника сотр записи в файл salary.dbf процедура ПеренестиОклад(сотр, оп, дбф) перем док;
// Прикрепляем ОП к периодическому реквизиту Оклад найденного сотрудника оп. ИспользоватьО бъект(" Оклад", сотр .Т екущийЭлемент());
// Позиционируемся перед первой записью истории окладов сотрудника оп.ВыбратьЗначения();
// Метод ПолучитьЗначение позиционирует ОП на следующей записи // периодического реквизита Оклад пока оп.ПолучитьЗначение() = 1 цикл
дбф.Добавить(); // Новая запись в файле salary.dbf
дбф.И = сотр.Код; // Код сотрудника
дбф^Ыгу = оп.Значение; // Значение и ДатаЗнач- атрибуты ОП
дбф.Date = оп.ДатаЗнач;
// Документ, вызвавший изменение оклада док = оп.ТекущийДокумент(); если док.Выбран() = 1 тогда дбф.DocName = док.Вид(); дбф.БоеИ = док.НомерДок; иначе
дбф.DocName = ""; дбф.DocId = 0; конецЕсли;
дбф.3аписать( ); // Сохраняем данные
конецЦикла; // пока конецПроцедуры // ПеренестиОклад
 |
Рис. 9.4. Таблица тЗнач, преобразованная в процедуре ДляДБФ |
 |
Рис. 9.5. Таблица тЗнач, преобразованная в процедуре ДляДБФ2 |
 |
Рис. 9.6. Фрагмент файла employee.dbf |
 |
Рис. 9. 7. Фрагмент файла salary.dbf |
Замечания:
1. Поскольку путь к файлам не указан, то они будут созданы в каталоге пользователя, из которого запускается обработка Проба. Имя каталога возвращается встроенной функцией КаталогПользователя.
2. С файлом, на который ссылается объект XBase, может одновременно работать только один пользователь. Поэтому если есть не равная нулю вероятность одновременного доступа к одному и тому же DBF-файлу более одного пользователя, то с объектом XBase нужно соответствующим образом использовать конструкцию Попытка.
9.3.2. АТРИБУТЫ И МЕТОДЫ ОБЪЕКТА XBASE
9.З.2.1. АТРИБУТЫ ОБЪЕКТА XBASE
Объект XBase имеет два вида атрибутов: поля DBF-файла и его ключи.
Атрибут Поле позволяет по имени поля читать и изменять значение поля текущей записи DBF-файла. Число таких атрибутов равно числу полей файла, на который ссылается объект XBase.
Пример. В окне сообщений выводится значение поля Name 3-й записи файла ет-ployee.dbf. В соответствии с рис. 9.6 в этом поле хранится строка Агальцов Юрий Алексеевич. Затем меняется значение 6-й записи файла employee.dbf.
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем дбф, ин;
ОчиститьОкноСообщенийО; дбф = СоздатьОбъект(''ХВазе''); дбф.ОткрытьФайл(''emplоуее.dbf'); если дбф.Открыта( ) = 0 тогда
Предупреждение("Файла employee.dbf в каталоге пользователя нет."); возврат; конецЕсли;
// Перемещаемся на третью запись файла employee.dbf
// После того как файл открыт, он позиционируется на своей первой записи
дбф.Перейти(З);
, Сообщить(дбф.Name); // Напечатает Агальцов Юрий Алексеевич
// Перемещаемся на шестую запись файла employee.dbf дбф.Перейти(б);
дбф-Name = "Бараненков Иван Несторович";
дбф.3аписать( ); // Не забываем записать изменения в файл
Предупреждение('Тотово."); конецПроцедуры // Выполнить
Замечание. Файл employee.dbf изменялся при закрытом индексном файле ет-ployee.cdx, поэтому индексы этого файла, в которые входит в качестве выражения имя поля Name, не отвечают в полной мере файлу employee.dbf. Следовательно, для поиска по индексу файл employee.cdx необходимо предварительно переиндексировать.
Атрибут Ключ является объектом агрегатного типа. Число компонентов объекта равно числу полей DBF-файла, на который ссылается объект XBase. Имя компонента атрибута Ключ составляется по следующей схеме:
дбф.Ключ.<имя поля DBF-файла>
Атрибут применяется для задания значений, употребляемых при вычислении индексного выражения. Полученное значение индексного выражения используется методом НайтиПоКлючу в качестве ключа поиска. Этот метод осуществляет поиск по текущему индексу, применяя в качестве ключа выражение, составленное из значений компонентов атрибута Ключ. Например, с файлом employee.dbf используется индекс
Depart, вычисляемый по выражению TRIM(STR(ParentId)) + Name. Чтобы задать это выражение в программе 1С, необходимо определить два компонента ключа: Ключ. ParentI d и RnKiq.Name.
Пример 1. Задаются ключи, обеспечивающие получение значения индексного выражения индекса Depart, равное 12Бараненков.
дбф.Ключ.ParentId = 12; // Значение для TRIM(STR(ParentId))
дбф.Ключ.Name = "Бараненков"; // Значение для Name
// Индексное выражение TRIM(STR(12)) + "Бараненков" вернет 12Бараненков
Пример 2. В файле employee.dbf ищется по индексу Name, индексное выражение которого равно Name (см. процедуру СоздатьСотр в разд. 9.3.1.2), ключ, равный Агальцов Юрий Алексеевич.
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перемдбф;
ОчиститьОкноСообщений(); дбф = СоздатьОбъект("ХВаве"); дбф.ОткрытьФайл(''етр1оуее.dbf', "employee.cdx"); если дбф.Открыта() = 0 тогда
Предупреждение("Файла employee. dbf и/или файла employee.cdx | в каталоге пользователя нет."); возврат; конецЕсли;
дбф.ТекущийИндекс ("Name"); дбф.Ключ.Name = "Агальцов Юрий Алексеевич"; дбф. НайтиПоКлючу( 1);
Сообщить(дбф.Name); // Напечатает Агальцов Юрий Алексеевич
конецПроцедуры // Выполнить
Замечание. При таком использовании метода НайтиПоКлючу можно задать неполное значение ключа, например
дбф.Ключ.Name = "Ага”; дбф.НайтиПоКлючу(І);
Сообщшъ(дбф.Name); // Напечатает Агальцов Юрий Алексеевич
Пример 3. В файле employee.dbf ищется по индексу Depart, индексное выражение которого равно TRIM(STR(ParentId)) + Name (см. процедуру СоздатьСотр в разд. 9.3.1.2), Ключ, равный TRIM((STR(12)) + "Бараненков".
Процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем дбф;
ОчиститьОкноСообщений(); дбф = СоздаIъОбъекг("ХВasе"); дбф.ОткрытьФайл("етр1оуее^Ь^ "employee.cdx"); если дбф.Открыта() = 0 тогда
Предупреждение("Файла employee.dbf и/или файла employee.cdx | в каталоге пользователя нет."); возврат;
дбф.ТекущийИндекс('^ераг1:");
дбф.Ключ.Раі-entId = 12; //Значение для TRIM(STR(ParentId))
дбф.Ключ^аше = "Бараненков"; // Значение для Name
дбф.НайтиПоКлючу(1); // Ключ равен 12Бараненков
Сообщить(дбф.Naшe); // Напечатает Бараненков Иван Несторович
конецПроцедуры // Выполнить
9.3.2.2. МЕТОДЫ ОБЪЕКТА XBASE
Приводятся в табл. 9.6.
|
Таблица 9.6
Методы объекта XBase |
Метод |
Описание |
дбф.СоздатьФайл
(ОВ?файл,
[СБХфайл]); |
Создает файл базы данных (DBF-файл) и, если задан второй параметр, индексный файл (CDX-файл). Имена файлов задаются символьными параметрами DBFфайл и СБХфайл. Если имя не содержит пути, то файлы будут созданы в каталоге пользователя. Если файлы с указанными именами на диске имеются, то они будут заменены на новые |
дбф.ОткрытьФайл
(ОВ?файл,
[СБХфайл],
[флагЧтения]); |
Открывает DBF-файл и, если задан второй параметр, индексный файл. Тип параметров DBFфайл и СБХфайл -символьный. Файлы открываются только для чтения, если флаг Чтения = 1, и доступны для редактирования, если флагЧтения = 0. По умолчанию флагЧтения = 0 |
флаг = дбф.Открыта(); |
Вернет 1, если DBF-файл открыт, или 0-в противном случае |
дбф.ЗакрытьФайл(); |
Закрывает ранее открытый или созданный DBF-файл. Игнорируется, если DBF-файл не был открыт или создан до употребления метода. DBF-файл при нормальном завершении программы будет закрыт и без вызова метода |
дбф. ОчиститьФайл (); |
Выполняет физическое удаление всех записей DBF-файла. После выполнения метода удаленные записи восстановить нельзя |
дбф.Сжать( ); |
Удаляет физически записи DBF-файла, имеющие пометку удаления |
дбф.Переиндексировать(); |
Выполняет переиндексацию индексного файла. Применяется для восстановления порядка следования записей в индексном файле, который может быть нарушен при аварийном завершении программы или при модификации DBF-файла при закрытом индексном файле |
режимТек = дбф.Показывать Удаленные ([режим]); |
Устанавливает режим доступа к записям, имеющим пометку удаления. Если режим = 1, то такие записи доступны, и недоступны, если режим = 0. По умолчанию режим = 0. Возвращает текущее значение режима |
Метод |
Описание |
флаг = дбф.Первая(); |
Перемещает DBF-файл на первую запись. Если задан текущий индекс, то первой является запись, отвечающая при возрастающем индексе его наименьшему значению или наибольшему - при убывающем индексе. Вернет 1 в случае успеха или 0 при неудаче |
флаг = дбф.Последняя(); |
Перемещает DBF-файл на последнюю запись. Если задан текущий индекс, то последней является запись, отвечающая при возрастающем индексе его наибольшему значению или наименьшему - при убывающем индексе. Вернет 1 в случае успеха или 0 при неудаче |
флаг = дбф.Следующая(); |
Перемещает DBF-файл на следующую запись. Если задан текущий индекс, то порядок записей определяется этим индексом. Вернет 1 в случае успеха или 0 при неудаче |
флаг = дбф.Предыдущая(); |
Перемещает DBF-файл на предшествующую запись. Если задан текущий индекс, то порядок записей определяется этим индексом. Вернет 1 в случае успеха или 0 при неудаче |
нЗап = дбф.НомерЗаписи(); |
Возвращает номер записи DBF-файла. Вернет 0, если файл позиционирован перед первой или вслед за последней записью |
дбф.Перейти(нЗап); |
Перемещает DBF-файл на запись, имеющую номер нЗап. Методу всегда доступны записи, имеющие пометку удаления. Если нЗап < 0 или нЗап > дбф.КоличествоЗаписей(), то возникнет информационная ошибка |
флаг = дбф.ВКонце(); |
Вернет 1, если DBF-файл находится вслед за своей последней записью, или О-в противном случае |
флаг = дбф.ВНачале(); |
Вернет 1, если DBF-файл находится перед своей первой записью, или О-в противном случае |
имяИндТек =дбф.Текущий Ивдекс([ИмяИнд]); |
Устанавливает, если задан параметр имяИнд, текущий индекс. Возвращает значение текущего индекса до вызова метода. Параметр имяИнд и результат имеют символьный тип |
флаг = дбф.Найти
(ключ, [режим]); |
Ищет ключ, используя текущий индекс. Вернет 1 в случае успеха или 0 при неудаче. При успешном поиске позиционирует файл на найденной записи. Если числовой параметр режим есть:
• 0, то ищется запись, индексное выражение которой точно равно ключу;
• 1, то ищется запись, индексное выражение которой больше или равно ключу;
• 2, то ищется запись, индексное выражение которой больше ключа;
• -1, то ищется запись, индексное выражение которой меньше или равно ключу;
• -2, то ищется запись, индексное выражение которой
меньше ключа.
По умолчанию режим = 0. Используется для простых индексов |
Метод |
Описание |
флаг = дбф.НайтиПоКлючу ([режим]); |
Ищет, используя текущий индекс, ключ, заданный компонентами атрибута Ключ. Описание метода такое же, как и метода Найти. Используется для любых индексов |
значение = дбф.Получить ЗначениеПоля (имяПоля\ номерПоля); |
Возвращает значение текущей записи в поле, заданным параметром имяПоля^омерПоля. Параметр имяПоля - это строка с именем поля. Параметр номерПоля - это номер поля. Возникнет информационная ошибка, если имяПоля (номерПоля) содержит несуществующее имя (несуществующий номер) или если файл находится перед первой или за последней записью |
дбф.УстановитьЗначение Поля(имяПоля \ номерПоля, значение); |
Устанавливает значение текущей записи в поле, заданным параметром имяПоля^омерПоля. Дальнейшую информацию о методе см. в описании метода ПолучитьЗначениеПоля. Для сохранения изменений, если не задан режим автосохранения, применяется метод Записать |
дбф.Добавить(); |
Добавляет пустую запись. Для ее сохранения в DBF-файле применяется, если не задан режим автосохранения, метод
Записать |
дбф.Скопировать(); |
Добавляет запись, которая является копией текущей записи. Для сохранения добавленной записи в DBF-файле применяется, если не задан режим автосохранения, метод
Записать |
режимТек =
дбф.АвтоСохранение
([режим]); |
Задает, если режим = 1, автоматическое сохранение (АС) измененных записей базы данных. В этом случае применение метода Записать избыточно. Для отмены изменений применяется метод Отменить. Если режим = 0, АС измененных записей не выполняется; изменения сохраняются методом Записать. Возвращает существовавший до вызова метода режим АС |
дбф.3аписать( ); |
Заносит изменения текущей записи в базу данных. Если метод не применен и не задано АС, смена позиции файла или его закрытие приведет к потере введенных данных |
дбф.Отменить(); |
Отменяет запись в базу данных изменений, выполненных в режиме автосохранения. Не отменяет действие метода Записать |
дбф.Удалить(); |
Проставляет пометку удаления текущей записи |
флаг = дбф.ЗаписьУдалена(); |
Возвращает 1, если запись имеет пометку удаления, или 0 -в противном случае |
дбф.Восстановить(); |
Снимает пометку удаления текущей записи |
дбф. Очистить(); |
Очищает текущую запись, то есть в символьное поле заносится строка нулевой длины, в числовое - 0, в логическое - .F., а в поле типа Дата - пустая дата. Изменения сохраняются, если задан режим автосохранения или если вслед за методом Очистить применен метод Записать |
числоЗап =
дбф.КоличествоЗаписей(); |
Возвращает число записей в DBF-файле |
Метод |
Описание |
числоПолей = дбф.Количество Полей(); |
Возвращает число полей DBF-файла |
числоИнд = дбф. Количество Индексов(); |
Возвращает число индексов открытого индексного файла |
дбф.ОписаниеПоля (номерПоля, имяПоля, тип, длина, точндсть); |
Возвращает для поля, имеющего номер, равный параметру номерПоля, имя, тип, длину иточность поля в соответствующие параметры метода |
дбф.ОписаниеИндекса
(номерИнд, имяИнд, выражение, уник, убыв, фильтр); |
Возвращает для индекса, имеющего номер, равный параметру номерИнд, имя, индексное выражение, флаги уникальности и убывания, а также фильтр в соответствующие параметры метода. Параметр уник равен единице, если индекс уникальный, или нулю - в противном случае. Параметр убыв равен единице, если индекс сортируется по убыванию значений индексного выражения, и равен нулю, если по возрастанию |
номПоля = дбф.НомерПоля (имяПоля); |
Возвращает номер поля по его имени |
дбф.ДобавитьПоле(ИмяПоля, тип, длина, точность); |
Добавляет в структуру DBF-файла поле, имя которого определено символьным параметром имяПоля, а тип, длина и точность задаются соответствующими параметрами метода. Параметр точность имеет смысл только для числового поля. Параметр тип равен:
• 1 или "N", если добавляется числовое поле;
• 2 или "S", если добавляется символьное поле;
• 3 или "D", если добавляется поле типа Дата;
• 4 или "L", если добавляется логическое поле;
• 5 или "F", если добавляется числовое поле.
После добавления всех полей употребляется метод СоздатьФайл |
дбф.ДобавитьИндекс
(имяИнд, выражение, уник, убыв, фильтр); |
Добавляет в структуру индексного файла индекс, имя которого определено символьным параметром имяИнд, а индексное выражение, флаги уникальности, убывания и фильтр индекса задаются соответствующими параметрами метода. Параметры выражение и фильтр имеют символьный тип. Смысл параметров уник и убыв см. в методе ОписаниеИндекса. После добавления всех индексов употребляется метод СоздатьФайл или
СоздатьИндексныйФайл |
дбф.СоздатьИндексныйФайл
(имяФайла); |
Создает индексный файл имяФайла, содержащий все индексы, сконструированные до вызова метода СоздатьИндексныйФайл методом ДобавитьИндекс. Тип параметра имяФайла - символьный. Также индексный файл может быть создан и методом СоздатьФайл |
Метод |
Описание |
кодСтрТек - дбф.Кодовая
Страница( [кодСтр]); |
Устанавливает, если кодСтр = 0, Windows-кодовую страницу или DOS-кодовую страницу, если кодСтр = 1. Возвращает существовавшую до вызова метода кодовую страницу.
По умолчанию кодСтр = 1 |
код = дбф.КодОшибки(); |
Возвращает код последней ошибки, возникшей при исполнении метода объекта XBase |
|
Замечания: |
1. Префикс дбф, употребленный с методами объекта XBase, может быть произвольным.
2. Фильтр индекса является логическим выражением, составленным по правилам, изложенным в разд. 9.3.1.3. В индексном файле, если фильтр задан, есть ссылка только на те записи DBF-файла, для которых выражение фильтра истинно. Тогда, если индекс с фильтром является текущим, записи, на которых нет ссылок в и н-дексном файле, пользователю недоступны. Отсутствие фильтра равнозначно фильтру, возвращающему для всех записей .Т. (истина).
Пример 1. Выводятся коды (табельные номера) всех сотрудников, имеющих оклад, равный 2900 руб.
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем дбф;
ОчистшъОкноСообщенийО; дбф = СоздатьОбъект("ХВаsе"); дбф.ОткрытьФайп("8а1аіу.йЬГ); если дбф.Открыта() = 0 тогда
Предупреждение("Файла salary.dbf в каталоге пользователя нет."); возврат; конецЕсли;
// Переход в начало файла salary.dbf; в данном примере метод может быть опущен,
// поскольку после открытия файл и так находится на своей первой записи
дбф.Первая();
пока дбф.ВКонце() = 0 цикл
если дбф.Sa1aIy = 2900 тогда Сообщить(цбф.И); конецЕсли; дбф.СледующаяО; конецЦикла; // пока конецПроцедуры // Выполнить
Результат:
111
209
Пример 2. Выводятся ФИО всех сотрудников, фамилия которых начинается с буквы Б.
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем дбф;
ОчиститьОкноСообщенийО; дбф = СоздатьОбъект("ХВаse"); дбф.ОткрытьФайл("етр1оуееЛЬГ, "employee.cdx");
если дбф.Открыта( ) = 0 тогда
Предупреждение("Файла employee.dbf и/или файла employee.cdx | в каталоге пользователя нет."); возврат; конецЕсли;
дбф.ТекущийИндекс("Name");
// Ищем запись, равную или большую символа "Б" если дбф.Найти("Б", 1) = 1 тогда
пока Лев(дбф.Name, 1) = "Б" цикл Сообщить(дбф.Name); дбф.Следующая(); конецЦикла; // пока иначе
Предупреждение
("Сотрудников, фамилия которых начинается на букву Б, в файле нет."); конецЕсли;
конецПроцедуры // Выполнить Результат:
Бараненков Иван Несторович Безверхний Игорь Петрович
Пример 3. Оклад сотрудника, табельный номер (код) которого равен 209, увеличивается на 500 руб. Для нового оклада в файл salary.dbfдобавляется запись.
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем дбф, окл;
ОчиститьОкноСообщений(); дбф = СоздатьОбъект("ХВаse"); дбф.ОткрытьФайл("salary.dbf'," salary.cdx"); если дбф.Открыта() = 0 тогда
Предупреждение("Файла salary.dbf и/или файла salary.cdx | в каталоге пользователя нет."); возврат; конецЕсли;
дбф.ТекущийИндекс("IdDate"); дбф.Ключ.Ы = 209;
// Ищем запись, большую str(209)
// Помним, что индексное выражение - это STR(Id) + DTOS(Date) если дбф.НайтиПоКлючу(2) = 1 тогда
// Перемещаемся на последнее значение оклада сотрудника с кодом 209 пока дбф.И = 209 цикл дбф.Следующая(); конецЦикла; // пока
дбф.Предыдущая(); // Шаг назад
окл = дбф.ПолучитьЗначениеПоля("Salary");
// или, используя атрибут: окл = дбф.Salary; дбф.Добавить();
дбф.УстановитьЗначениеПоля("И", 209);
дбф .УстановитьЗначениеПоля("Date", ТекущаяДата());
дбф.УстановитьЗначениеПоля("Salaly", окл + 500);
// или, используя атрибуты:
// дбф.И= 209; дбф.БаІе = ТекущаяДата(); дбф.8аіагу = окл + 500; дбф.3аписать();
ПредупреждениеС'Тотово.");
иначе
ПредупреждениеС'Сотрудника с кодом 209 в файле нет."); конецЕсли;
конецПроцедуры // Выполнить
Пример 4. Копируется и записывается в файл salary.dbf его последняя запись.
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем дбф;
ОчиститьОкноСообщений(); дбф = СоздатьОбъектС'ХВаБе"); дбф. ОткрытьФайл('^1агу. dbf"); если дбф.Открыта() = 0 тогда
Предупреждение("Файла salary.dbf в каталоге пользователя нет."); возврат; конецЕсли;
дбф.АвтоСохранение(1); // Будем обходиться без метода Записать
дбф.Последняя(); . // Переход на последнюю запись
дбф.Скопировать( ); // Добавляем копию последней записи
Предупреждение('Тотово."); конецПроцедуры // Выполнить
Пример 5. Выводятся описания всех полей и индексов файла salary.dbf.
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем дбф, ин, имяПоля, тип, длина, точность; перем имяИнд, выражение, уник, убыв, фильтр;
ОчиститьОкноСообщений(); дбф = СоздатъОбъектС'ХВазе"); дбф.ОткрытьФайп("sa1ary.dbf," salary.cdx"); если дбф.Открыта( ) = 0 тогда
Предупреждение("Файла salary.dbf и/или файла salary.cdx | в каталоге пользователя нет."); возврат; конецЕсли;
Сообщить("Описание полей файла salary.dbf:"); для ин = 1 по дбф.КоличествоПолей() цикл
дбф.ОписаниеПоля(ин, имяПоля, тип, длина, точность);
Сообщить(имяПоля + "" + тип + "" + длина + "" + точность); конецЦикла; // для
Сообщить("Описание индексов файла salary.dbf:"); для ин = 1 по дбф.КоличествоИндексов( ) цикл
дбф.ОписаниеИндекса(ин, имяИнд, выражение, уник, убыв, фильтр); Сообщить(имяИнд + " " + выражение + " " + уник + " " + убыв + " " + фильтр); конецЦикла; // для конецПроцедуры // Выполнить
Результат:
Описание полей файла salary. dbf:
ID 1 50 DATE 3 8 0 DOCNAME 2 15 0 DOCID 1 5 0 SALARY 1 10 2
Описание индексов файла salary. dbf:
IDDATE STR(id)+DTOS(date) 0 0
Пример 6. Содержимое произвольного DBF-файла выводится в таблицу значений. Диалог формы, содержащей таблицу значений, оформим в соответствии с рис. 9.8. |
 |
Рис. 9.8. Таблица значений для записей DBF-файла В заголовке таблицы значений будем выводить значение выражения "Состав файла " + имяФайла |
которое зададим в диалоге как формулу элемента диалога Текст.
// Вводим переменную модуля для ее использования в диалоге перем имяФайла;
процедура ПоказатьДБФ(дбф, имяФайла) далее
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем дбф, флаг, папка;
ОчиститьОкноСообщений();
// Открываем диалог для выбора DBF-файла // В качестве примера выберем файл employee.dbf
флаг = ФСВыбратъФайл(0, имяФайла, папка, "Выберите файл"," | *.DBF"); если флаг = 0 тогда возврат; конецЕсли;
дбф = СоздатьОбъект("ХВаsе"); дбф.ОткрытьФайл(папка + имяФайла); если дбф.Открыта() = 0 тогда
Предупреждение("Не удалось открыть файл " + имяФайла); возврат; конецЕсли;
// Отобразим DBF-файл имяФайла в таблице значений // Результат приведен на рис. 9.9 ПоказатьДБФ(дбф, имяФайла); конецПроцедуры // Выполнить
// Выводит записи DBF-файла имяФайла в таблицу значений процедура ПоказатьДБФ(дбф, имяФайла)
перем ин, имяПоля, тип, длина, точность, номСтроки;
// Формируем столбцы таблицы значений и устанавливаем их параметры для ин = 1 по дбф.КоличествоПолей() цикл
дбф.ОписаниеПоля(ин, имяПоля, тип, длина, точность); тЗнач.НоваяКолонка(имяПоля, тип);
тЗнач.УстановитьПараметрыКолонки(ин, тип, длина, точность,, мин(10, длина)); конецЦикла; // для
// Заголовок таблицы значений диалога загТЗнач = "Состав файла " + имяФайла;
// Заполняем таблицу значений тЗнач данными из DBF-файла
дбф.Первая(); // Переходим на первую запись файла
номСтроки = 0;
пока дбф.ВКонце() = 0 цикл // Пока не достигнут конец файла
номСтроки = номСтроки + 1; тЗнач.НоваяСтрока(номСтроки); для ин = 1 по дбф.КоличествоПолей() цикл
тЗнач.УстановитьЗначение(номСтроки, ин, дбф.ПолучитьЗначениеПоля(ин)); конецЦикла; // для дбф. Следующая(); конецЦикла; // пока конецПроцедуры // ПоказатьДБФ
 |
Рис. 9.9. Файл employee.dbf в таблице значений |
Замечание. Подобного рода процедуру всегда удобно иметь под рукой для оперативного просмотра используемых DBF-файлов. Напомним, что таблицу значений также можно отобразить, применив метод ВыбратьСтроку.
Пример 7. Выводятся коды сотрудников, оклад которых больше 3000 руб. Для получения результата в дополнение к существующему создается индекс с выражением Salary и фильтром Salary > 3000.
перем имяФайла;
процедура Выполнить() // Связана с кнопкой Пуск обработки Проба
перем дбф, флаг, папка;
ОчиститьОкноСообщенийО; дбф = СоздатъОбьект(''ХВаsе''); дбф.ОткрытьФайл("salary.dbf'); если дбф.Открыта( ) = 0 тогда
Предупреждение("Файла salary.dbf в каталоге пользователя нет."); возврат; конецЕсли;
// Индекс IdDate обеспечит сортировку по дате в пределах заданного кода сотрудника дбф.ДобавитьИндекс("ІёБа1е", "str(Id) + dtos(Date)", 0, 0, "");
// Индекс Salary обеспечит сортировку по окладу дбф.ДобавитьИндекс("Salary", "Salary", 0, 0, "Salary > 3000"); дбф.СоздатьИндексныйФайл("Salaryxdx"); дбф.ТекущийИндекс("Salary");
дбф.Первая(); // Переход в начало файла
// Вывод результата. Доступны только те записи, у которых Salary > 3000 Сообщить("Коды сотрудников, оклад которых более 3000 руб."); пока дбф.ВКонце() = 0 цикл // Пока не достигнут конец файла
Сообщить(Строка(дбф.И) + Символ Табуляции +
"(оклад сотрудника равен " + Строка(дбф.Salary) + " руб.)"); дбф.Следующая(); конецЦикла; // пока имяФайла = "salary.dbf";
ПоказатьДБФ(дбф, имяФайла); // Код процедуры ПоказатьДБФ см. выше
конецПроцедуры
Результат работы процедуры ПоказатьДБФ см. на рис. 9.10.
Результат:
Коды сотрудников, оклад которых более 3000 руб.
301 (оклад сотрудника равен 3100 руб.)
122 (оклад сотрудника равен 3200 руб.)
2010 (оклад сотрудника равен 3200 руб.)
302 (оклад сотрудника равен 3200 руб.)
303 (оклад сотрудника равен 3200 руб.)
 |
Рис. 9.10. Файл salary.dbf под действием снабженного фильтром индекса Salary |
9.3.2.3. ВЫРАЖЕНИЯ ИНДЕКСА И ФИЛЬТРА
Выражения, употребляемые в методе -ДобавитьИндекс, для индекса и фильтра, могут содержать в качестве операндов имена полей, константы и вызовы функций. Аргументами функций, применяемых в выражениях, могут также быть имена полей, константы и вызовы, функций. Например, в методе
дбф.ДобавитьИндекс("Depart", "trim(str(ParentId)) + Name", 0, 0,"");
индексное выражение содержит функции TRIM, STR и имена полей DBF-файла ParentId и Name, а в методе
дбф.ДобавитьИндекс("Salary", "Salary", 0, 0, "Salary > 3000");
выражение фильтра включает имя поля Salary и числовую константу 3000.
В качестве логических констант используются .Т. и .F. для обозначения соответственно констант истина и ложь.
Константы типа Дата задаются в фигурных скобках.
Регистр написания операндов выражения не имеет значения.
Выражение индекса может иметь числовой, символьный, логический тип или тип Дата.
Выражение фильтра, если задано, должно иметь логический тип.
В выражениях индекса и фильтра могут применяться приведенные в табл. 9.7 операции (они расположены в таблице в порядке убывания их приоритета; операции с одним приоритетом размещаются в одной строке таблицы).
Таблица 9.7
Операции выражений индекса и фильтра |
Операции |
Значения |
Арифметические операции |
- |
Унарный минус |
** или Л |
Возведение в степень |
*,/ |
Умножение, деление |
_ |
Сложение, вычитание |
Символьные операции |
+ |
Объединение (конкатенация) |
- |
Объединение 2 (конкатенация 2) |
Операции отношения |
=, <> или #,<,>,<=,>= $ |
Равно, не равно, меньше, больше, меньше или равно, больше или равно, содержит |
Логические операции |
.NOT. |
Логическое НЕ (отрицание) |
.AND. |
Логическое И |
.OR. |
Логическое ИЛИ |
|
Замечания:
1. Все операции, кроме унарного минуса, являются двуместными (бинарными), то есть употребляются между двумя операндами.
2. Выражения вычисляются слева направо в порядке, определяемом приоритетом операций. Часть подвыражения, заключенная в круглые скобки, вычисляется в первую очередь. Более подробно о вычислении выражений см. в разд. 2.6.
3. Унарный минус имеет больший приоритет, чем иные арифметические (и другие) операции. Например, выражение
вернет, так же как и выражение (-2)**2 число 4.
4. Символьная операция в отличие от операции +, перемещает завершающие пробелы первого операнда в конец результата, например, выражение
"3 п "+"робела"
вернет строку "3 п робела", а выражение "3 п " - "робела"
- строку "3 пробела ".
5. Операция $ применяется только с символьными операндами. Выражение отношения с операцией $ вернет .Т., если первый операнд выражения является подстрокой второго, или .F. - в противном случае. Например выражение
"БВ” $"АБВГ"
вернет .Т., а выражение
"БГ" $ "АБВГ" вернет .F..
6. В отличие от 1С в выражениях индекса и фильтра нельзя смешивать символьные и арифметические операнды. Так, вместо
"АБС” + 2
чтобы получить строку "АБС2", нужно употребить выражение "АБС" + trim(str(2)) или выражение "АБС" + str(2', 1)
В выражениях индекса и фильтра используются приведенные в табл. 9.8 функции.
Таблица 9.8
Функции для выражений индекса и фильтра |
Функция |
Что возвращает |
Тип
результата |
DATE() |
Текущую дату, например 01/14/02 |
Дата |
DAY(dama) |
День месяца, заданного параметром дата |
Число |
DTOC(dama) |
Символьное представление даты, заданной параметром дата |
Строка |
DTOS(dama) |
Символьное представление даты, заданной параметром дата, в виде ГГГГММДД |
|
IIF(nBbip, выр1, выр2) |
Результат выражения выр1, если истинно логическое выражение лВыр, или результат выражения выр2 -в противном случае. Выражения выр1 и выр2 могут быть произвольного типа |
Совпадает
с типом выр1 или выр2 |
БТЯІМ(строка) |
Строку, в которой удалены ведущие пробелы параметра строка |
Строка |
|
Функция |
Что возвращает |
Тип
результата |
MONTH^a) |
Номер месяца в году, заданного параметром дата |
Число |
STOD(cmpo^) |
Дату в формате ГПТММДД |
Дата |
STR(число, [длина], [десСим]) |
Символьное представление параметра число в виде строки длиной длина, содержащей десСим десятичных символов. Если параметры длина и десСим опущены, то результирующая строка имеет 10 символов и не содержит десятичной части. Если опущен параметр десСим, то результат также не содержит десятичной части |
Строка |
SUBSTR^^^ra,
начПоз,
[числоСим]) |
Подстроку параметра строка, начинающуюся с позиции начПоз и содержащую числоСим последующих символов. Если последний параметр опущен, то результатом будут все символы от позиции начПоз до конца строки строка |
|
TIME() |
Текущее время в формате ЧЧ:ММ:СС |
" |
TRIM(строка) |
Строку, в которой удалены завершающие пробелы параметра строка |
|
UPPER(строка) |
Строку, преобразованную в верхний регистр |
" |
VAL(строка) |
Числовое представление параметра строка |
Число |
YEARC^'ra) |
Номер года, заданного параметром дата |
" |
Замечание. Параметры функций являются выражениями. Причем параметр дата является выражением типа Дата; параметр строка - символьное выражение; параметры число, длина, десСим, начПоз и числоСим - числовые выражения.
Примеры употребления функций приведены в табл. 9.9.
Примеры вызова функций для выражений индекса и фильтра
Таблица 9.9 |
Пример вызова |
Результат |
Тип |
day(date()) |
14 |
Числовой |
month(date()) |
1 |
" |
year(date()) |
2002 |
" |
time() |
16:08:46 |
Символьный |
dtoc(date()) |
01/14/02 |
" |
dtos(date()) |
20020114 |
" |
k = 5
IIF(k > 8, 2 * 3, "A" + "B") |
6 |
Числовой |
k = 9
IIF(k > 8, 2 * 3, "A" + "B") |
AB |
Символьный |
ltrim(" ABC") |
ABC |
" |
trim(" ABC ") + "D" |
ABCD |
" |
|
Содержание раздела