При разработке управляемых форм в платформах 1С часто возникает задача: пользователь вводит текст в поле на форме, и по этому тексту необходимо выполнить поиск в базе данных через запрос. Начинающие разработчики иногда путаются в том, как обратиться к введенным в поле формы данным и передать их на сервер в запрос.
Рассмотрим подробно, как устроена работа со строковыми реквизитами формы, разберем порядок передачи параметра в запрос и разберем лучшие практики оптимизации таких процедур.
Если серверная процедура выполняется в контексте формы (директива &НаСервере), все реквизиты формы доступны напрямую по их именам. Никаких дополнительных преобразований типа или сложных функций обращений не требуется — имя реквизита формы выступает переменной, содержащей текущее значение.
Проанализируем базовый пример кода в обработчике события ПриИзменении для поля формы:
&НаСервере
Процедура ФамилияДляОдногоПриИзмененииНаСервере()
ЗапФамилия = Новый Запрос;
ЗапФамилия.Текст =
"ВЫБРАТЬ
| ДанныеПациентов.Фамилия КАК Фамилия
|ИЗ
| РегистрСведений.ДанныеПациентов КАК ДанныеПациентов
|ГДЕ
| ДанныеПациентов.Фамилия = &Фамилия";
// Передаем значение реквизита формы "ФамилияДляОдного" напрямую в параметр запроса
ЗапФамилия.УстановитьПараметр("Фамилия", ФамилияДляОдного);
РезультатЗапроса = ЗапФамилия.Выполнить();
КонецПроцедуры
В приведенном коде ФамилияДляОдного — это имя реквизита формы строкового типа. Метод УстановитьПараметр() принимает имя параметра запроса без символа амперсанда & и само значение реквизита.
На практике точное совпадение строки требуется не всегда. Если необходимо найти записи, содержащие фрагмент введенного текста, в тексте запроса используется оператор ПОДОБНО.
По стандартам разработки 1С спецсимволы шаблона (такие как % или _) рекомендуется добавлять к строке в коде BSL до передачи параметра в запрос:
&НаСервере
Процедура ПоискПоЧастиСтрокиНаСервере()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДанныеПациентов.Фамилия КАК Фамилия
|ИЗ
| РегистрСведений.ДанныеПациентов КАК ДанныеПациентов
|ГДЕ
| ДанныеПациентов.Фамилия ПОДОБНО &ШаблонПоиска";
// Формируем шаблон поиска с подстановкой символов процента
СтрокаШаблона = "%" + СокрЛП(ФамилияДляОдного) + "%";
Запрос.УстановитьПараметр("ШаблонПоиска", СтрокаШаблона);
Результат = Запрос.Выполнить();
КонецПроцедуры
Передача контекста всей формы на сервер при каждом изменении текстового поля может снижать производительность системы. Чтобы ускорить работу, рекомендуем переносить логику выполнения запроса в процедуру с директивой &НаСервереБезКонтекста и передавать значение строки в качестве явного параметра процедуры.
Разберем по шагам эту схему взаимодействия клиента и сервера:
&НаКлиенте
Процедура ФамилияДляОдногоПриИзменении(Элемент)
// Проверяем заполнена ли строка перед отправкой на сервер
Если ЗначениеЗаполнено(ФамилияДляОдного) Тогда
ВыполнитьПоискНаСервере(ФамилияДляОдного);
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьПоискНаСервере(Знач ТекстПоиска)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДанныеПациентов.Фамилия КАК Фамилия
|ИЗ
| РегистрСведений.ДанныеПациентов КАК ДанныеПациентов
|ГДЕ
| ДанныеПациентов.Фамилия ПОДОБНО &Шаблон";
Запрос.УстановитьПараметр("Шаблон", "%" + СокрЛП(ТекстПоиска) + "%");
Результат = Запрос.Выполнить();
// Обработка результатов запроса
КонецПроцедуры
ЗначениеЗаполнено(), чтобы избежать холостых запросов к базе данных при пустом поле.СокрЛП() для очистки поисковой строки от незначащих крайних пробелов.%Текст% не задействует стандартные индексы СУБД по строковым полям и при больших объемах данных может выполнять полное сканирование таблицы. По возможности используйте поиск по началу строки (Текст%) или механизмы полнотекстового поиска.