Как правильно настроить отбор при выборе значения в табличной части и почему исчезает новая строка

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

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

Разберём подробно внутренние механизмы платформы, вызывающие такое поведение, а также рассмотрим корректные способы открытия форм выбора с динамическим отбором.

Выясним причину: почему исчезает новая строка табличной части

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

  1. Пользователь добавляет новую строку в табличную часть и нажимает кнопку выбора в ячейке. Строка переходит в режим интерактивного редактирования, но ещё не зафиксирована платформой в коллекции данных.
  2. В обработчике события ячейки программно открывается форма выбора (часто устаревшим методом ОткрытьФормуМодально), после чего результат напрямую присваивается в Элементы.ТабличнаяЧасть.ТекущиеДанные.ИмяРеквизита, а форме выставляется признак Модифицированность = Истина.
  3. Поскольку стандартный механизм выбора был нарушен (или не было отключено платформенное событие), при щелчке мышью фокус ввода уходит из ячейки. Платформа воспринимает это как отказ пользователя от ввода новой строки и автоматически удаляет её. При нажатии клавиши Enter, напротив, срабатывает внутренняя команда подтверждения ввода, и строка фиксируется.

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

Способ 1. Передача элемента формы в качестве владельца (рекомендуемый способ для кода)

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

Рассмотрим по шагам реализацию в обработчике события НачалоВыбора для поля табличной части:

  1. В палитре свойств элемента табличной части создадим клиентский обработчик события НачалоВыбора.
  2. Обязательно установим параметр СтандартнаяОбработка = Ложь, чтобы отменить штатное открытие формы без параметров.
  3. Сформируем структуру параметров с отбором.
  4. Вызовем немодальный метод ОткрытьФорму, указав в качестве параметра Владелец переданный в процедуру Элемент.

Посмотрим на пример кода:


&НаКлиенте
Процедура ШтНоменклатураНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    ПараметрыОтбора = Новый Структура;
    ПараметрыОтбора.Вставить("СтруктурноеПодразделение", Объект.Получатель);
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);
    
    // В качестве владельца передаем Элемент (поле ввода таблицы)
    ОткрытьФорму("Справочники.Номенклатура.ФормаВыбора", ПараметрыФормы, Элемент);
    
КонецПроцедуры

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

Способ 2. Использование механизма «Связи параметров выбора» (декларативный подход)

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

Разберём настройку по шагам:

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

Преимущества этого способа: отбор начинает действовать не только при открытии формы выбора по кнопке с многоточием, но и при быстром вводе по строке (автоподборе), что невозможно получить простым переопределением события НачалоВыбора.

Способ 3. Программная настройка свойства «ПараметрыВыбора»

Иногда разработчики пытаются настроить параметры выбора через свойство элемента формы, но сталкиваются с ошибкой: «Поле недоступно для записи». Разберём, почему это происходит.

Свойство элемента формы ПараметрыВыбора возвращает коллекцию типа ФиксированныйМассив, элементы которой нельзя изменять напрямую. Чтобы переопределить параметры выбора кодом (например, при изменении подразделения в шапке), необходимо создать новый массив, заполнить его объектами ПараметрВыбора и передать обратно в виде фиксированного массива:


&НаКлиенте
Процедура ПолучательПриИзменении(Элемент)
    
    ОбновитьПараметрыВыбораНоменклатуры();
    
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьПараметрыВыбораНоменклатуры()
    
    МассивПараметров = Новый Массив;
    
    // Формируем новый параметр отбора
    ПараметрОтбора = Новый ПараметрВыбора("Отбор.СтруктурноеПодразделение", Объект.Получатель);
    МассивПараметров.Добавить(ПараметрОтбора);
    
    // Присваиваем свойству ФиксированныйМассив
    Элементы.ШтНоменклатура.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
    
КонецПроцедуры

Способ 4. Принудительная фиксация строки при нестандартной обработке

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

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


&НаКлиенте
Процедура ОбработатьВыбор(РезультатВыбора, ДополнительныеПараметры) Экспорт
    
    Если РезультатВыбора = Неопределенность Тогда
        Возврат;
    КонецЕсли;
    
    СтрокаТаблицы = Элементы.Шт.ТекущиеДанные;
    Если СтрокаТаблицы <> Неопределенность Тогда
        СтрокаТаблицы.Номенклатура = РезультатВыбора;
        
        // Принудительно фиксируем ввод строки в таблице
        // Параметр Ложь указывает, что отменять редактирование не нужно
        Элементы.Шт.ЗакончитьРедактированиеСтроки(Ложь);
    КонецЕсли;
    
КонецПроцедуры

Метод ЗакончитьРедактированиеСтроки(Ложь) сообщает платформе, что интерактивный ввод успешно завершён, и строка сохраняется в коллекции данных табличной части независимо от того, куда пользователь кликнет мышью.

← На главную