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