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