Как ограничить выбор помеченных на удаление складов в 1С 8.3 и избежать появления битых ссылок?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе многолетней работы в любой базе данных «1С:Предприятие» накапливается большое количество неактуальных, устаревших или дублирующихся элементов справочников. Особенно остро эта проблема стоит для справочника Склады. Пользователи часто помечают ненужные склады на удаление, однако эти объекты продолжают отображаться в автоподборе при вводе по строке. В результате из-за банальной невнимательности менеджеры продолжают выбирать удаленные склады в новых документах.

В этой статье мы подробно разберем, как решить эту задачу изящно и профессионально. Мы проанализируем различные методы — от простых декларативных настроек в конфигураторе до продвинутых программных механизмов платформы и настройки прав доступа (RLS) без риска получить надписи «Объект не найден» в отчетах.

Почему стандартное предупреждение платформы не всегда работает?

При интерактивном выборе элемента, помеченного на удаление, платформа «1С:Предприятие» по умолчанию выдает предупреждающий вопрос: «Элемент помечен на удаление! Вы действительно хотите выбрать его?». Однако на практике этот механизм оказывается неэффективным по следующим причинам:

  1. Фактор невнимательности: При потоковом вводе документов пользователи нажимают кнопку «Да» автоматически, не вчитываясь в текст предупреждения.
  2. Быстрый ввод по строке: При автоподборе склад может подставиться в поле автоматически, если его наименование частично совпало с вводимым текстом, и документ будет записан без должного контроля.
  3. Засорение интерфейса: Огромный список неактуальных складов мешает быстро ориентироваться в форме выбора.

Давайте подробно рассмотрим эффективные варианты решения этой проблемы, двигаясь от простых к наиболее гибким и архитектурно правильным.

---

Метод 1. Настройка свойства «Параметры выбора» в метаданных (Без программирования)

Самый простой и быстрый способ ограничить выбор удаленных складов в конкретных документах — использовать декларативную настройку свойств реквизитов в конфигураторе. Этот метод хорош тем, что он абсолютно безопасен для существующих документов и старых проводок.

Разберем этот процесс по шагам:

  1. Откроем конфигуратор и найдем документ, в котором необходимо ограничить выбор склада (например, РеализацияТоваровУслуг или ПоступлениеТоваровУслуг).
  2. Перейдем к реквизиту Склад и откроем его палитру свойств.
  3. Найдем свойство Параметры выбора (ChoiceParameters).
  4. Нажмем кнопку выбора (три точки) и добавим новый параметр:
    • Имя параметра: Отбор.ПометкаУдаления
    • Значение: Ложь
  5. Сохраним изменения и обновим конфигурацию базы данных.

Результат: Теперь при попытке выбрать склад в этом документе — будь то через форму выбора или при вводе по строке — платформа автоматически отсечет все помеченные на удаление склады. При этом в старых, уже проведенных документах, ранее выбранные удаленные склады будут отображаться корректно, без системных ошибок.

Совет: Если документов в вашей конфигурации очень много, настраивать параметры выбора вручную для каждого из них может быть трудоемко. В таком случае свойства можно задать на уровне свойств самого справочника Склады в поле «Параметры выбора» для связей или воспользоваться программным переопределением при начале работы системы.

---

Метод 2. Событие модуля менеджера «ОбработкаПолученияДанныхВыбора» (Лучшее программное решение)

Если нам требуется гибко управлять доступностью складов (например, скрывать удаленные склады от обычных пользователей, но разрешать их выбор администраторам или сотрудникам склада для исправления ошибок), идеальным решением станет использование специализированного обработчика платформы 8.3 — ОбработкаПолученияДанныхВыбора в модуле менеджера справочника.

Этот метод перехватывает любой ввод по строке и быстрое заполнение поля ввода на сервере.

Рассмотрим пример реализации. Откроем модуль менеджера справочника Склады и добавим следующий код:


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

Преимущества метода:

---

Метод 3. Борьба со встроенным кэшем: Отключение истории выбора при вводе

Часто разработчики сталкиваются со следующей проблемой: они настроили фильтры, скрыли удаленные элементы, но при нажатии пользователем клавиши «Стрелка вниз» или очистке поля в списке автоподбора все равно всплывают удаленные склады. Это происходит из-за механизма истории выбора платформы, которая кэширует предыдущие действия пользователя.

Чтобы раз и навсегда решить эту проблему, выполним следующие действия:

  1. В конфигураторе откроем форму документа, в которой размещено поле выбора склада.
  2. Выделим элемент формы (Поле ввода) Склад и откроем его свойства.
  3. Найдем свойство История выбора при вводе (ChoiceHistoryOnInput).
  4. Установим значение свойства в Не использовать (Disable).

Если требуется очистить уже накопленную «плохую» историю выбора у пользователей программно, мы можем использовать следующий метод платформы:


// Очищаем историю выбора для конкретного реквизита справочника Склады
ОчиститьИсториюВыбора(Новый ОписаниеИсторииВыбора(Справочники.Склады.ПустаяСсылка()));

---

Метод 4. Правильная настройка RLS (Ограничение доступа на уровне записей)

На форумах часто советуют ограничить видимость складов через механизм RLS (Record Level Security), прописав в шаблоне ограничений условие ГДЕ НЕ ПометкаУдаления.

Внимание! Настройка RLS на право «Чтение» (Read) для удаленных складов — это критическая архитектурная ошибка. Как только вы закроете право на чтение помеченных элементов, во всех отчетах, журналах и старых документах вместо названия склада пользователи увидят пугающую надпись <Объект не найден> (84:b10000155d01070111e4bf...). Это приведет к панике среди бухгалтеров и невозможности сопоставить данные прошлых периодов.

Как настроить RLS правильно с использованием Библиотеки стандартных подсистем (БСП):

  1. Оставьте право Чтение доступным для всех пользователей без ограничений по пометке удаления. Это гарантирует красивое отображение истории и корректность отчетов.
  2. Настройте ограничения RLS исключительно на права Добавление (Create) и Изменение (Update).
  3. В качестве текста условия ограничения для этих прав укажите простую конструкцию: Склады ГДЕ НЕ Склады.ПометкаУдаления

При такой настройке пользователи смогут беспрепятственно видеть старые склады в отчетах, но система жестко заблокирует любую попытку записать новый документ или перезаписать старый, если в нем указан помеченный на удаление склад.

---

Метод 5. Защита от случайной пометки на удаление работающих складов

Проанализируем еще одну проблему: что делать, если склад пометили на удаление случайно, и никто этого вовремя не заметил? Чтобы застраховаться от таких ситуаций, создадим подписку на событие, контролирующую процесс установки пометки удаления.

Создадим подписку на событие ПередЗаписью для справочника Склады и напишем в ней проверку наличия остатков товаров:


Процедура ПередЗаписьюСкладаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    
    // Проверяем, изменилась ли пометка удаления на "Истина"
    Если Источник.ПометкаУдаления И Не Источник.Ссылка.ПометкаУдаления Тогда
        
        // Проверим, есть ли на складе остатки товаров по регистру накопления
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ
            |	ТоварыНаСкладахОстатки.В НаличииОстаток КАК Остаток
            |ИЗ
            |	РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад) КАК ТоварыНаСкладахОстатки";
            
        Запрос.УстановитьПараметр("Склад", Источник.Ссылка);
        
        Выгрузка = Запрос.Выполнить().Выгрузить();
        Если Выгрузка.Количество() > 0 И Выгрузка[0].Остаток > 0 Тогда
            Отказ = Истина;
            ВызватьИсключение "Невозможно пометить склад на удаление! На складе обнаружены остатки товаров.";
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Этот простой шаг убережет вашу базу данных от случайных или умышленных действий пользователей, которые могут нарушить оперативный учет.

---

Резюме: Какой метод выбрать?

← На главную