Как извлечь данные из таблицы значений, если она не является реквизитом формы

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

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

Анализируем причину проблемы: Клиент-серверное взаимодействие

Первое, что нам необходимо понять: почему стандартные методы не работают. Проанализируем ситуацию, описанную в сообщениях форума. Автор пытается использовать ПолучитьОбъект(), надеясь найти таблицу внутри объекта документа. Однако, если таблица создана только в форме для визуализации, в самом объекте (в базе данных) её не существует.

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

  1. Контекст исполнения: В управляемом приложении формы существуют на стороне клиента. На сервере «формы» как визуального объекта не существует, есть только её данные.
  2. Локальные переменные: Если таблица объявлена в модуле формы или создана программно через ИзменитьРеквизиты, она живет только пока открыто окно формы.
  3. Отсутствие связи с метаданными: Поскольку это не реквизит, платформа не сохраняет эти данные автоматически при записи документа.

Рассмотрим по шагам, как можно «вытащить» эти данные наиболее грамотными способами.

Способ 1. Дублирование логики получения данных (Рекомендуемый)

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

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

  1. Откроем модуль формы интересующего нас документа.
  2. Найдем процедуру ПриСозданииНаСервере или обработчики команд, которые заполняют таблицу.
  3. Скопируем текст запроса и логику установки параметров.
  4. Вынесем эту логику в Модуль менеджера документа или в Общий модуль, чтобы её можно было вызывать из любого места системы.

Посмотрим на пример кода, который реализует получение таких данных в произвольном месте (например, в регламентном задании или другой форме):


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

Теперь в любом месте программы мы можем просто вызвать Документы.Агригация.ПолучитьДанныеДляТаблицы(НужнаяСсылка) и получить идентичную таблицу значений.

Способ 2. Использование Временного хранилища

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

Разберем, как это работает. Мы помещаем таблицу в хранилище на клиенте (в модуле формы) и передаем адрес (строку) на сервер или в другое окно.

Пример помещения данных в форме:


&НаКлиенте
Процедура ПередатьДанныеКудаТо()
    // Преобразуем данные формы в обычную таблицу значений на сервере
    АдресХранилища = ПоместитьДанныеВоВременноеХранилищеНаСервере();
    // Теперь передаем АдресХранилища как параметр в другую форму или процедуру
КонецПроцедуры

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

Важно помнить, что данные во временном хранилище живут столько, сколько живет сеанс или форма (в зависимости от переданного идентификатора).

Способ 3. Экспортные функции модуля формы

Если нам принципиально нужно обратиться к открытой форме, мы можем объявить в её модуле функцию с ключевым словом Экспорт. Однако, этот метод работает только если у нас есть доступ к объекту формы в памяти клиента.

Рассмотрим пример в модуле формы:


&НаСервере
Функция ПолучитьТекущееСостояниеТаблицыЭкспорт() Экспорт
    // Превращаем данные формы обратно в таблицу значений
    Возврат РеквизитФормыВЗначение("ИмяВашейТаблицы");
КонецФункции

Но помните: вызвать эту функцию через ПолучитьФорму().ПолучитьТекущееСостояниеТаблицыЭкспорт() на сервере не получится. Это сработает только в клиентском коде, если форма уже открыта.

Почему не работает ПолучитьФорму на сервере?

Выясним причину ошибки, упомянутой в сообщении №4. Метод ПолучитьФорму является клиентским. Когда вы находитесь «на сервере» (например, в модуле объекта или в общем модуле с признаком «Сервер»), система не может создать визуальный объект формы. Программирование в 1С 8.3 четко разделяет данные и их представление.

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

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

Подводя итог, проанализируем лучший путь решения задачи:

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

← На главную