При написании запросов в платформе «1С:Предприятие» разработчики часто сталкиваются с двумя популярными задачами: как правильно фильтровать данные по строковым условиям и как применить привычные конструкции языка запросов к внешним источникам данных, например к файлам формата DBF. Проанализируем эти ситуации по шагам, выясним причины возникающих ошибок и разберем практические способы решения.
Выясним причину ошибки, с которой часто сталкиваются начинающие разработчики. Если прописать текстовое значение прямо в теле запроса без использования дополнительных кавычек, система выведет сообщение вида «Поле не найдено». Это происходит потому, что платформа воспринимает текст без кавычек как имя поля или реквизита таблицы.
Для явного указания строкового литерала внутри текста запроса строку необходимо оборачивать в двойные кавычки:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Наименование, Имя ИЗ Справочник.ФИО ГДЕ Наименование = ""ЛИПКИН""";
РезультатЗапроса = Запрос.Выполнить();
Однако жесткое прописывание строк в тексте запроса считается нелучшей практикой. Динамическая подстановка текстовых значений усложняет чтение кода и препятствует кэшированию планов выполнения запросов на стороне СУБД. Рекомендуется использовать параметры запроса с символом &. Рассмотрим пример:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФИО.Наименование КАК Наименование,
| ФИО.Имя КАК Имя
|ИЗ
| Справочник.ФИО КАК ФИО
|ГДЕ
| ФИО.Наименование = &Наименование";
Запрос.УстановитьПараметр("Наименование", "ЛИПКИН");
Результат = Запрос.Выполнить();
Если требуется найти подстроку или выполнить поиск по частичному совпадению, используем оператор ПОДОБНО и спецсимволы шаблона (% — любая последовательность символов, _ — один любой символ):
Запрос.Текст =
"ВЫБРАТЬ
| ФИО.Наименование КАК Наименование,
| ФИО.Имя КАК Имя
|ИЗ
| Справочник.ФИО КАК ФИО
|ГДЕ
| ФИО.Наименование ПОДОБНО &ШаблонПоиска";
Запрос.УстановитьПараметр("ШаблонПоиска", "%ЛИПКИН%");
Рассмотрим следующий вопрос: можно ли выполнять выборку данных из внешнего DBF-файла с помощью конструкции ВЫБРАТЬ ... ГДЕ ...? Напрямую применить язык запросов 1С к объекту XBase нельзя. Объект XBase предоставляет базовые механизмы последовательного считывания данных или поиска по заранее созданному индексу.
Базовый построчный обход выполняется следующим образом:
ФайлDBF = Новый XBase;
ФайлDBF.Кодировка = КодировкаXBase.OEM;
ФайлDBF.ОткрытьФайл("C:\LPU\fio_209.dbf",, Истина);
Если ФайлDBF.Открыт() Тогда
ФайлDBF.Первая();
Пока Не ФайлDBF.ВКонце() Цикл
// Проверяем условие программно
Если ФайлDBF.Наименование = "ЛИПКИН" Тогда
Сообщить(ФайлDBF.Наименование + " " + ФайлDBF.Имя);
КонецЕсли;
ФайлDBF.Следующая();
КонецЦикла;
ФайлDBF.ЗакрытьФайл();
КонецЕсли;
Для позиционирования на нужной записи без тотального обхода можно применить метод НайтиПоКлючу(). Однако важно учитывать следующие особенности:
.cdx или .ndx).XBase необходимо назначить активный индекс через свойство ТекущийИндекс.Ключ для индексируемого поля.ФайлDBF.НайтиПоКлючу("=").Разберем по шагам, как применить язык запросов 1С (со всеми преимуществами ГДЕ, СГРУППИРОВАТЬ ПО, ОБЪЕДИНИТЬ и соединений) к внешнему файлу DBF. Для этого используется механизм временных таблиц.
ТаблицаЗначений и формируем колонки, строго задавая их типы через ОписаниеТипов.Посмотрим на практический пример реализации такого подхода:
// 1. Создаем и подготавливаем Таблицу Значений
ТЗДанные = Новый ТаблицаЗначений;
ТЗДанные.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(100)));
ТЗДанные.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(50)));
// 2. Читаем DBF и заполняем ТЗ
ФайлDBF = Новый XBase;
ФайлDBF.Кодировка = КодировкаXBase.OEM;
ФайлDBF.ОткрытьФайл("C:\LPU\fio_209.dbf",, Истина);
Пока ФайлDBF.ВКонце() = Ложь Цикл
ЗаписьТЗ = ТЗДанные.Добавить();
ЗаписьТЗ.Наименование = СокрЛП(ФайлDBF.Наименование);
ЗаписьТЗ.Имя = СокрЛП(ФайлDBF.Имя);
ФайлDBF.Следующая();
КонецЦикла;
ФайлDBF.ЗакрытьФайл();
// 3. Выполняем запрос к полученной таблице
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ.Наименование КАК Наименование,
| ТЗ.Имя КАК Имя
|ПОМЕСТИТЬ ВТ_ФИО
|ИЗ
| &ВнешниеДанные КАК ТЗ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_ФИО.Наименование КАК Наименование,
| ВТ_ФИО.Имя КАК Имя
|ИЗ
| ВТ_ФИО КАК ВТ_ФИО
|ГДЕ
| ВТ_ФИО.Наименование = &ОтборНаименование";
Запрос.УстановитьПараметр("ВнешниеДанные", ТЗДанные);
Запрос.УстановитьПараметр("ОтборНаименование", "ЛИПКИН");
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование + " " + Выборка.Имя);
КонецЦикла;
Рассмотрим дополнительные методы обработки данных из DBF, которые могут пригодиться в практике разработки.
1. Поиск методом НайтиСтроки() в памяти
Если данные уже выгружены в ТаблицуЗначений, не обязательно составлять запрос для простого поиска. Можно использовать встроенный метод таблицы значений:
Отбор = Новый Структура;
Отбор.Вставить("Наименование", "ЛИПКИН");
НайденныеСтроки = ТЗДанные.НайтиСтроки(Отбор);
Для Каждого СтрокаТЗ Из НайденныеСтроки Цикл
Сообщить(СтрокаТЗ.Наименование + " " + СтрокаТЗ.Имя);
КонецЦикла;
2. Подключение через ADODB
Для прямого выполнения SQL-запросов к DBF-файлам без полного чтения в память можно использовать объект COMОбъект("ADODB.Connection"). Однако при использовании данного метода необходимо учитывать ряд ограничений: