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