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