Как получить доступ к данным табличной части, если ее видимость на форме отключена?

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

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

Выясняем причину: почему пропадают ТекущиеДанные?

Проанализируем поведение платформы. Свойство ТекущиеДанные принадлежит элементу управления (интерфейсу), а не самой табличной части (данным объекта). Платформа 1С оптимизирована для работы в тонком клиенте и веб-клиенте. Чтобы минимизировать трафик между сервером и клиентом, система исключает из контекста формы все элементы, которые в данный момент невидимы. Если таблица скрыта, платформа считает, что пользователю не нужно знать о «текущей строке», и прекращает синхронизацию этого свойства. Таким образом, программная попытка прочитать данные через визуальный элемент управления при Видимость = Ложь всегда будет приводить к ошибке или значению Неопределено.

Решение 1: Использование вспомогательных реквизитов формы

Этот метод считается наиболее «правильным» с точки зрения архитектуры управляемого приложения. Рассмотрим его по шагам. Вместо того чтобы привязывать поля ввода напрямую к Элементы.Таблица.ТекущиеДанные.ИмяПоля, мы создаем промежуточный слой данных.

  1. Создадим на форме реквизиты с именами, соответствующими именам колонок табличной части (например, ТекРеквизит_Количество, ТекРеквизит_Номенклатура).
  2. Разместим их на форме и настроим их видимость (показывать, когда таблица скрыта).
  3. Напишем процедуру синхронизации данных между этими реквизитами и первой строкой табличной части.

Пример кода для синхронизации при открытии формы или изменении состава ТЧ:


&НаКлиенте
Процедура ОбновитьОтображениеРеквизитов()
    
    Если Объект.Товары.Количество() > 0 Тогда
        // Берем данные из первой строки (индекс 0)
        ТекущаяСтрокаТЧ = Объект.Товары[0];
        
        // Заполняем реквизиты формы
        ТекРеквизит_Номенклатура = ТекущаяСтрокаТЧ.Номенклатура;
        ТекРеквизит_Количество   = ТекущаяСтрокаТЧ.Количество;
    КонецЕсли;
    
    // Управляем видимостью
    ЭтоОднаСтрока = (Объект.Товары.Количество() = 1);
    Элементы.ГруппаРеквизитовОднойСтроки.Видимость = ЭтоОднаСтрока;
    Элементы.Товары.Видимость = НЕ ЭтоОднаСтрока;
    
КонецПроцедуры

Важно помнить: если пользователь меняет значение в ТекРеквизит_Номенклатура, необходимо в событии ПриИзменении этого реквизита записать данные обратно в Объект.Товары[0].

Решение 2: Работа через идентификатор строки (ТекущаяСтрока)

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

Рассмотрим пример функции, которая безопасно получает данные, даже если таблица невидима:


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

Решение 3: «Обман» платформы через группировку и страницы

Проанализируем еще один способ: как скрыть таблицу визуально, но сохранить её «видимость» для программного интерфейса. Если установить Элементы.Таблица.Видимость = Ложь, элемент полностью исключается из рендеринга. Но что, если мы переместим таблицу на страницу, которая не активна в данный момент?

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

В некоторых версиях платформы это позволяет сохранить доступ к ТекущиеДанные, так как элемент технически остается «видимым» в иерархии формы, просто он находится на неактивной вкладке. Однако стоит учитывать, что это поведение может меняться в зависимости от режима оптимизации формы.

Решение 4: Использование Пути К Данным (ограничения и возможности)

В процессе обсуждения часто звучит предложение прописать в свойстве ПутьКДанным элемента формы прямой индекс, например: Объект.Товары[0].Цена. Важно понимать: конфигуратор 1С не поддерживает такой синтаксис в поле «Путь к данным». Платформа ожидает там только цепочку реквизитов через точку.

Однако мы можем обойти это программным созданием реквизитов. Рассмотрим пример кода, который выполняется НаСервере при создании формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Если мы точно знаем, что работаем с первой строкой,
    // мы могли бы связать реквизиты динамически, но в 1С 
    // для этого все равно потребуется создать программно реквизит формы
    // и связать его с элементом.
    
КонецПроцедуры

Как мы видим, универсального способа «прописать индекс в свойствах» нет, поэтому возвращаемся к Решению 1 как к самому надежному.

Рекомендации и Best Practices

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

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

← На главную