Как предотвратить исчезновение строк в подчиненной таблице при использовании отбора в 1С

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

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

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

Выясняем причину: почему строки «улетают» из видимости

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

Рассмотрим основные причины исчезновения строк:

  1. Несинхронность данных: В момент добавления новой строки в подчиненную таблицу значение ключевого поля (например, Номенклатура), по которому идет отбор, еще не успело зафиксироваться в данных формы на сервере. Платформа проверяет строку на соответствие фильтру, видит пустое значение и скрывает строку как не подходящую под условия.
  2. Частота события ПриАктивизацииСтроки: Это событие срабатывает чрезвычайно часто — при любом перемещении фокуса, клике или даже автоматическом обновлении интерфейса. Постоянные попытки переустановить ОтборСтрок внутри этого обработчика приводят к тому, что интерфейс «заикается», а текущая редактируемая строка сбрасывается.
  3. Особенности буферизации: Пока пользователь не завершил ввод в ячейку, данные находятся в «состоянии редактирования» на клиенте. Серверная часть таблицы еще не знает о новом значении, поэтому фильтрация по этому значению работает некорректно.

Решение №1: Использование обработчика ожидания

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

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


&НаКлиенте
Процедура ВходнойКонтрольПриАктивизацииСтроки(Элемент)
    // Вместо мгновенного отбора запускаем таймер на 0.1 секунды
    ПодключитьОбработчикОжидания("ИзмеренияПриАктивизацииСтрокиВхКонтроля", 0.1, Истина);
КонецПроцедуры

Теперь создадим саму процедуру, которая выполнит работу по фильтрации. Обратите внимание, что метод ОтборСтрок требует передачи объекта ФиксированнаяСтруктура.


&НаКлиенте
Процедура ИзмеренияПриАктивизацииСтрокиВхКонтроля()
    ТД = Элементы.ВходнойКонтроль.ТекущиеДанные;
    Если ТД <> Неопределено Тогда
        // Устанавливаем фильтр по ключевому полю
        Элементы.Измерения.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", ТД.Номенклатура);
    КонецЕсли;
КонецПроцедуры

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

Решение №2: Гарантированное заполнение в ПередНачаломДобавления

Часто строки исчезают именно в момент нажатия кнопки «Добавить». Чтобы этого избежать, мы должны гарантировать, что новая строка «родится» уже с заполненным ключевым полем. Если значение связи будет установлено до того, как строка отобразится, фильтр ОтборСтрок сразу признает ее «своей».

Рассмотрим пример кода в обработчике события ПередНачаломДобавления для подчиненной таблицы:


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

Заполнение самого поля Номенклатура лучше всего выполнять в событии ПриНачалеРедактирования, чтобы данные подтянулись в объектную структуру строки:


&НаКлиенте
Процедура ИзмеренияПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
    Если НоваяСтрока Тогда
        ДанныеРодителя = Элементы.ВходнойКонтроль.ТекущиеДанные;
        ТекДанныеПодчиненной = Элементы.Измерения.ТекущиеДанные;
        ТекДанныеПодчиненной.Номенклатура = ДанныеРодителя.Номенклатура;
    КонецЕсли;
КонецПроцедуры

Решение №3: Использование Таблицы Значений вместо Табличной Части

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

Проанализируем преимущества этого подхода:

  1. Отсутствие серверных вызовов: Фильтрация и поиск в ТЗ на форме могут происходить на клиенте (если использовать правильные методы отображения), что исключает задержки.
  2. Полный контроль: Вы сами управляете тем, когда данные из ТЗ попадут в ТЧ документа (обычно это происходит в событии ПередЗаписьюНаСервере).
  3. Стабильность UI: Строки в ТЗ не исчезают самопроизвольно, так как платформа не пытается синхронизировать их с базой данных в реальном времени при каждом изменении фокуса.

Схема работы будет следующей:

Подведем итоги

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

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

← На главную