При изучении разработки на платформе 1С:Предприятие 8.3 (например, по методике М.Г. Радченко) начинающие программисты часто сталкиваются с необходимостью наложить ограничения на выбор данных. Типичная ситуация: в документе ПриходнаяНакладная пользователь должен выбирать только товары, при этом услуги или другие категории должны быть скрыты или запрещены для выбора — для этой задачи есть расширение для настройки контроля ввода и скрытия элементов списков 1С. Рассмотрим подробно, как реализовать этот функционал правильно, и разберем, почему «папки» в справочнике — не самый надежный способ для логических проверок.
Начнем с самого простого способа, который не требует написания кода. Платформа 1С позволяет задать жесткий фильтр непосредственно в свойствах реквизита — также для этого подойдет модуль гибкой настройки ограничений доступа и выбора данных без программирования. Разберем этот процесс по шагам:
ПриходнаяНакладная.СписокНоменклатуры).Номенклатура и откроем его палитру свойств. Для более детальной настройки интерфейса «на лету» разработчиками часто применяется редактор форм в режиме предприятия.Здесь мы можем добавить новый параметр. Если мы хотим, чтобы в форме выбора отображались только элементы, принадлежащие определенной группе, мы можем указать отбор по родителю — для сложных условий подойдет расширение для настройки фильтров и отборов в списках 1С. Однако, как правильно заметили опытные разработчики, привязка к конкретной ссылке на папку в конфигураторе — это «хрупкое» решение. Если ваша логика требует сложной работы с иерархией, используйте инструмент для формирования запросов по родителям всех уровней справочника, чтобы лучше понимать структуру вложенности.
Важный нюанс: Чтобы пользователь не мог выбрать саму папку (группу) вместо товара, обязательно установите свойство Выбор групп и элементов в значение Элементы. Это базовое правило гигиены данных в 1С.
Проанализируем более гибкий подход — использование программного кода. Это позволит нам динамически определять, какие элементы показывать пользователю.
Нам необходимо перехватить событие НачалоВыбора для поля табличной части. Разберем пример кода для управляемых форм:
&НаКлиенте
Процедура СписокНоменклатурыНоменклатураНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
// Отменяем стандартное открытие формы, так как будем открывать её программно с параметрами
СтандартнаяОбработка = Ложь;
// Создаем структуру отбора
ПараметрыОтбора = Новый Структура;
// Допустим, мы ищем только те элементы, которые НЕ являются услугами
// Здесь мы используем реквизит "Услуга" (тип Булево)
ПараметрыОтбора.Вставить("Услуга", Ложь);
// Формируем параметры открытия формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора;
// Открываем форму выбора справочника Номенклатура
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры
Этот метод гораздо надежнее, так как он не зависит от иерархии папок. Если же ваша задача — просто скрыть неактуальные или устаревшие позиции, рекомендуем рассмотреть готовый механизм архива элементов в 1С, который позволяет выводить только актуальные данные.
Проанализируем ситуацию, описанную в сообщениях форума. Пользователь может случайно или намеренно переместить товар из папки «Товары» в папку «Услуги». Если ваша логика завязана только на иерархию (родителя), система начнет работать некорректно.
Выясним причину, почему профессионалы советуют использовать Виды номенклатуры вместо групп. Вид номенклатуры — это, как правило, либо перечисление, либо отдельный справочник, ссылка на который есть в каждой карточке номенклатуры. Рассмотрим, как это упрощает жизнь:
Посмотрим, как в таком случае будет выглядеть настройка в конфигураторе через Связи параметров выбора. Если у вас в документе есть реквизит ВидОперации, вы можете настроить реквизит Номенклатура так, чтобы он автоматически фильтровался по соответствующему виду без единой строчки кода.
Даже если мы настроили фильтры в форме выбора, данные могут попасть в документ иными путями: через обработку загрузки из Excel, через копирование строк или простым вводом по строке. Чтобы обеспечить 100% чистоту данных, рассмотрим реализацию ОбработкаПроверкиЗаполнения в модуле объекта документа.
Проанализируем процедуру ОбработкаПроверкиЗаполнения:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Для Каждого СтрокаТЧ Из СписокНоменклатуры Цикл
// Проверяем, не является ли выбранный элемент услугой
Если СтрокаТЧ.Номенклатура.Услуга Тогда
ТекстСообщения = "В приходной накладной нельзя указывать услуги! Строка №" + СтрокаТЧ.НомерСтроки;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения, , "СписокНоменклатуры[" + (СтрокаТЧ.НомерСтроки - 1) + "].Номенклатура");
Отказ = Истина; // Запрещаем проведение и запись документа
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Используя этот метод, мы гарантируем, что бизнес-логика не будет нарушена. Пользователь получит понятное сообщение об ошибке, а система подсветит проблемную строку.
Разберем спорный момент из обсуждения: стоит ли создавать отдельные справочники Товары и Услуги? В экосистеме 1С традиционно используется один справочник Номенклатура.
Подведем итог: Для решения вашей задачи лучше всего использовать комбинацию Метода 2 (для удобства пользователя при выборе) и Метода 4 (для обеспечения целостности данных). При этом старайтесь уходить от логики «папок» в пользу реквизита ВидНоменклатуры или простого булева поля Услуга.