Как исключить помеченные на удаление элементы из автоподбора и корректно очистить составное поле ввода в 1С?

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

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

В этой статье мы подробно разберем, как спроектировать поведение интерфейса так, чтобы пользователь вообще не мог выбрать помеченный на удаление элемент при ручном вводе. Также мы проанализируем ситуацию с очисткой полей составного типа данных и выясним причину, почему стандартное зануление пустой строкой или жесткое приведение к пустой ссылке справочника может нарушить логику работы формы.

---

Часть 1. Предотвращение выбора помеченных на удаление элементов при автоподборе

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

Рассмотрим подробнее два наиболее эффективных способа реализации этой логики.

Способ 1.1. Фильтрация через модуль менеджера справочника (Рекомендуемый)

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

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

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

Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    
    // Проверяем, существует ли уже структура отбора в параметрах, чтобы не вызвать ошибку
    Если Параметры.Свойство("Отбор") Тогда
        // Добавляем жесткое условие: выбирать только не помеченные на удаление элементы
        Параметры.Отбор.Вставить("ПометкаУдаления", Ложь);
    Иначе
        // Если отбора не было, создаем структуру и добавляем параметр
        НовыйОтбор = Новый Структура("ПометкаУдаления", Ложь);
        Параметры.Вставить("Отбор", НовыйОтбор);
    КонецЕсли;
    
    // Стандартная обработка остается Истина, чтобы платформа сама выполнила поиск по строке
    // с учетом нашего нового установленного фильтра.
    
КонецПроцедуры

Преимущество метода: Этот код сработает глобально во всей системе. Где бы пользователь ни пытался ввести наименование элемента данного справочника с клавиатуры, система автоматически отсечет удаленные объекты еще на этапе формирования выпадающего списка подсказок.

Способ 1.2. Настройка параметров выбора на форме (Динамический метод)

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Ограничиваем выбор для конкретного поля табличной части
    НовыйПараметр = Новый ПараметрВыбора("Отбор.ПометкаУдаления", Ложь);
    
    // Создаем массив параметров выбора
    МассивПараметров = Новый Массив;
    МассивПараметров.Добавить(НовыйПараметр);
    
    // Устанавливаем параметры выбора для элемента формы
    Элементы.ТабличнаяЧастьРазмерыРазмерИзделия.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
    
КонецПроцедуры

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

---

Часть 2. Правильная очистка и сброс полей составного типа данных

Если по какой-то причине элемент, помеченный на удаление, все же был выбран (или проверка выполняется постфактум в обработчике ПриИзменении), нам необходимо очистить реквизит. При работе с составными типами данных стандартная очистка таит в себе неочевидные подводные камни.

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

Ниже описаны два правильных подхода к решению этой проблемы.

Подход 2.1. Использование значения Неопределено (Полный сброс)

Для реквизитов составного типа базовым пустым значением, указывающим на отсутствие выбранного типа и объекта, является системное значение Неопределено.

Если мы присвоим полю это значение, платформа полностью сбросит текущую типизацию. Поле очистится, и при попытке нового ввода (или нажатии на кнопку выбора «...») пользователю снова будет предложен выбор из всего перечня доступных справочников, определенных в метаданных реквизита.

Посмотрим на пример кода обработчика изменения строки табличной части:


&НаКлиенте
Процедура ТабличнаяЧастьРазмерыРазмерИзделияПриИзменении(Элемент)
    
    СтрокаТаблицы = Элементы.ТабличнаяЧастьРазмеры.ТекущиеДанные;
    Если СтрокаТаблицы = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    ТекущееЗначение = СтрокаТаблицы.РазмерИзделия;
    
    // Проверяем, заполнено ли значение реквизита
    Если ЗначениеЗаполнено(ТекущееЗначение) Тогда
        
        // Вызываем серверную функцию для проверки пометки удаления
        Если ПроверитьПометкуУдаленияНаСервере(ТекущееЗначение) Тогда
            
            ПоказатьПредупреждение(, "Выбранный размер помечен на удаление! Выберите другой элемент.");
            
            // Корректный сброс составного поля ввода
            СтрокаТаблицы.РазмерИзделия = Неопределено;
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПроверитьПометкуУдаленияНаСервере(ЗначениеСсылка)
    
    // Используем безопасное получение реквизита, чтобы избежать лишней выборки объекта в память
    Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЗначениеСсылка, "ПометкаУдаления");
    
КонецФункции

Подход 2.2. Очистка на клиенте с сохранением выбранного типа (Без вызова сервера)

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

Вместо громоздких обращений к метаданным на сервере, в платформе «1С:Предприятие 8.3» мы можем использовать быстрый конструктор Новый() прямо на клиенте:


&НаКлиенте
Процедура ОчиститьСохраняяТип(СтрокаТаблицы)
    
    // Получаем тип данных текущего (уже выбранного) значения
    ТипТекущегоЗначения = ТипЗнч(СтрокаТаблицы.РазмерИзделия);
    
    // Через конструктор Новый создаем пустую ссылку этого же типа данных на клиенте
    СтрокаТаблицы.РазмерИзделия = Новый(ТипТекущегоЗначения);
    
КонецПроцедуры

Как это работает: Конструктор Новый(Тип) при передаче в него ссылочного типа (например, Тип("СправочникСсылка.РазмерыОдежды")) возвращает пустую ссылку этого типа (Справочники.РазмерыОдежды.ПустаяСсылка()). Это происходит мгновенно на стороне тонкого клиента без выполнения тяжелых контекстных серверных вызовов.

---

Часть 3. Оптимизация с использованием механизмов БСП

Поскольку в вашей конфигурации интегрирована Библиотека Стандартных Подсистем (БСП), крайне рекомендуется задействовать ее встроенные возможности для проверки свойств объектов. Это позволит сделать код более компактным и производительным.

Вместо написания собственных запросов в серверных функциях используйте возможности общего модуля ОбщегоНазначения:

---

Резюме и рекомендации

Подводя итоги совместного разбора проблемы, выделим ключевые правила работы с автоподбором и составными типами в 1С:

  1. Всегда стремитесь ограничить появление удаленных элементов на этапе ввода с клавиатуры через событие ОбработкаПолученияДанныхВыбора в модуле менеджера источника данных.
  2. Для полной очистки реквизита составного типа используйте присвоение значения Неопределено. Это полностью обнулит состояние поля и вернет его к исходному виду.
  3. Если требуется очистить значение, но сохранить текущую типизацию поля для удобства пользователя, применяйте конструкцию Новый(ТипЗнч(ВашеЗначение)) на клиенте.
  4. Используйте готовые функции БСП для получения реквизитов объектов на сервере, чтобы минимизировать нагрузку на базу данных.
← На главную