В практике разработки на платформе 1С:Предприятие 8.3 часто встречается ситуация, когда в форме документа или обработки отображается ТаблицаЗначений, которая не привязана к реквизитам объекта или самой формы. Она заполняется динамически — например, при открытии или по нажатию кнопки. Попытка получить доступ к такой таблице «снаружи» (через ссылку на документ или метод ПолучитьФорму) обычно заканчивается неудачей. Разберем детально, почему так происходит и как правильно решить эту задачу.
Первое, что нам необходимо понять: почему стандартные методы не работают. Проанализируем ситуацию, описанную в сообщениях форума. Автор пытается использовать ПолучитьОбъект(), надеясь найти таблицу внутри объекта документа. Однако, если таблица создана только в форме для визуализации, в самом объекте (в базе данных) её не существует.
Разберем основные причины сложности доступа к таким данным:
ИзменитьРеквизиты, она живет только пока открыто окно формы.Рассмотрим по шагам, как можно «вытащить» эти данные наиболее грамотными способами.
Как справедливо отмечено в сообщениях форума, самый надежный путь — не пытаться взломать контекст формы, а выяснить, откуда форма берет эти данные. В сообщении №15 автор подтверждает, что данные загружаются из запроса. Следовательно, нам нужно выполнить тот же самый запрос в нашем коде.
Проанализируем алгоритм реализации этого подхода:
ПриСозданииНаСервере или обработчики команд, которые заполняют таблицу.Модуль менеджера документа или в Общий модуль, чтобы её можно было вызывать из любого места системы.Посмотрим на пример кода, который реализует получение таких данных в произвольном месте (например, в регламентном задании или другой форме):
// Функция в модуле менеджера документа
Функция ПолучитьДанныеДляТаблицы(СсылкаНаДокумент) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДанныеДокумента.Номенклатура,
| ДанныеДокумента.Количество
|ИЗ
| РегистрСведений.ВнешниеДанные КАК ДанныеДокумента
|ГДЕ
| ДанныеДокумента.ДокументОснование = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Теперь в любом месте программы мы можем просто вызвать Документы.Агригация.ПолучитьДанныеДляТаблицы(НужнаяСсылка) и получить идентичную таблицу значений.
Бывают случаи, когда данные в таблице на форме не просто подтягиваются из базы, а меняются пользователем интерактивно, но еще не записаны. Если нам нужно перехватить именно эти «живые» данные, придется использовать ВременноеХранилище.
Разберем, как это работает. Мы помещаем таблицу в хранилище на клиенте (в модуле формы) и передаем адрес (строку) на сервер или в другое окно.
Пример помещения данных в форме:
&НаКлиенте
Процедура ПередатьДанныеКудаТо()
// Преобразуем данные формы в обычную таблицу значений на сервере
АдресХранилища = ПоместитьДанныеВоВременноеХранилищеНаСервере();
// Теперь передаем АдресХранилища как параметр в другую форму или процедуру
КонецПроцедуры
&НаСервере
Функция ПоместитьДанныеВоВременноеХранилищеНаСервере()
ТЗ = РеквизитФормыВЗначение("ИмяРеквизитаТаблицы");
Возврат ПоместитьВоВременноеХранилище(ТЗ, ЭтаФорма.УникальныйИдентификатор);
КонецФункции
Важно помнить, что данные во временном хранилище живут столько, сколько живет сеанс или форма (в зависимости от переданного идентификатора).
Если нам принципиально нужно обратиться к открытой форме, мы можем объявить в её модуле функцию с ключевым словом Экспорт. Однако, этот метод работает только если у нас есть доступ к объекту формы в памяти клиента.
Рассмотрим пример в модуле формы:
&НаСервере
Функция ПолучитьТекущееСостояниеТаблицыЭкспорт() Экспорт
// Превращаем данные формы обратно в таблицу значений
Возврат РеквизитФормыВЗначение("ИмяВашейТаблицы");
КонецФункции
Но помните: вызвать эту функцию через ПолучитьФорму().ПолучитьТекущееСостояниеТаблицыЭкспорт() на сервере не получится. Это сработает только в клиентском коде, если форма уже открыта.
Выясним причину ошибки, упомянутой в сообщении №4. Метод ПолучитьФорму является клиентским. Когда вы находитесь «на сервере» (например, в модуле объекта или в общем модуле с признаком «Сервер»), система не может создать визуальный объект формы. Программирование в 1С 8.3 четко разделяет данные и их представление.
Полезный совет: Если вы видите, что данные в форме заполняются сложным образом, проанализируйте свойство ДинамическийСписок. Часто новички путают обычную таблицу значений и динамический список. Если это список, то данных как таковых в нем нет — это просто «окно» в базу данных. В этом случае вам нужно анализировать ТекстЗапроса самого списка.
Подводя итог, проанализируем лучший путь решения задачи:
РеквизитФормыВЗначение, если вам нужно преобразовать данные, которые уже есть на экране, в объект ТаблицаЗначений для дальнейшей обработки на сервере.Такой подход делает ваш код более устойчивым к изменениям интерфейса и упрощает отладку, так как логика получения данных становится независимой от визуальной части приложения.