Как правильно использовать временное хранилище 1С для передачи сложных данных между клиентом и сервером в управляемых формах?

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

При разработке решений на платформе 1С:Предприятие 8.3 в режиме управляемого приложения (для этого подойдёт набор инструментов для разработки и отладки на управляемых формах) часто возникает необходимость передавать объемные или сложные структуры данных между клиентской и серверной частями приложения. Прямая передача параметров процедур и функций при работе с большими таблицами значений, массивами ссылок или другими объектами может быть неэффективной или приводить к ошибкам, особенно при работе через тонкий или веб-клиент. В таких случаях на помощь приходит универсальный механизм временного хранилища.

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

Понимание механизма временного хранилища

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

Основные функции для работы с временным хранилищем:

  1. ПоместитьВоВременноеХранилище(Значение, ИдентификаторВладельца): Помещает указанное Значение во временное хранилище и возвращает его адрес. ИдентификаторВладельца может быть произвольной строкой или уникальным идентификатором формы, который поможет системе определить владельца данных.
  2. ПолучитьИзВременногоХранилища(Адрес): Извлекает данные из временного хранилища по указанному Адресу.
  3. УдалитьИзВременногоХранилища(Адрес): Удаляет данные из временного хранилища по Адресу.

Важно понимать, что данные во временное хранилище попадают в сериализованном виде. Для оптимизации ресурсов и предотвращения утечек памяти, а также в целях безопасности, всегда рекомендуется явно очищать временное хранилище после использования.

Передача таблицы значений с клиента на сервер и обратно

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

Шаг 1: Подготовка данных на клиенте и помещение их во временное хранилище

На клиентской стороне мы формируем таблицу значений — для этого есть инструментарий для разработки и отладки кода 1С. После этого помещаем ее во временное хранилище, получая адрес, который затем передадим на сервер.


// Пример на клиенте:
// Создаем и заполняем таблицу значений
ПередаваемыеДанные = Новый ТаблицаЗначений;
ПередаваемыеДанные.Колонки.Добавить("Поле1", Новый ОписаниеТипов("Строка"));
ПередаваемыеДанные.Колонки.Добавить("Поле2", Новый ОписаниеТипов("Число"));

НоваяСтрока = ПередаваемыеДанные.Добавить();
НоваяСтрока.Поле1 = "Значение 1";
НоваяСтрока.Поле2 = 123;

НоваяСтрока = ПередаваемыеДанные.Добавить();
НоваяСтрока.Поле1 = "Значение 2";
НоваяСтрока.Поле2 = 456;
// ... продолжаем заполнять таблицу ...

// Помещаем таблицу значений во временное хранилище.
// В качестве идентификатора владельца можно использовать УникальныйИдентификаторФормы,
// если данные привязаны к конкретной форме.
АдресДанных = ПоместитьВоВременноеХранилище(ПередаваемыеДанные, УникальныйИдентификаторФормы);

// Вызываем серверную процедуру, передавая ей только адрес
РезультатСервернойОбработки = МояСервернаяПроцедура(АдресДанных);

// После получения результата, если данные больше не нужны,
// можно их удалить из временного хранилища на клиенте,
// если серверная процедура не сделала это сама
// УдалитьИзВременногоХранилища(АдресДанных); 
// В данном примере удаление происходит на сервере.

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

Шаг 2: Получение и обработка данных на сервере

На серверной стороне мы получаем переданный адрес, извлекаем по нему данные из временного хранилища, выполняем необходимую логику обработки (её ускоряет инструмент для пошаговой отладки кода 1С в режиме «Предприятие»), а затем обязательно удаляем данные из хранилища.


// Пример на сервере (в модуле формы или в общем модуле с директивой 'НаСервере' или 'НаСервереБезКонтекста'):
Процедура МояСервернаяПроцедура(АдресДанных) Экспорт
    // Получаем данные из временного хранилища по переданному адресу
    ДанныеДляОбработки = ПолучитьИзВременногоХранилища(АдресДанных);

    // Убедимся, что данные получены и имеют ожидаемый тип
    Если ДанныеДляОбработки = Неопределено Тогда
        ВызватьИсключение "Не удалось получить данные из временного хранилища по адресу: " + АдресДанных;
    КонецЕсли;

    // Проверяем тип данных, если необходимо
    Если ТипЗнч(ДанныеДляОбработки) = Тип("ТаблицаЗначений") Тогда
        // ... выполняем обработку полученной таблицы значений ...
        Сообщить("На сервере получена таблица значений с " + ДанныеДляОбработки.Количество() + " строками.");

        // Пример простейшей обработки: добавление колонки
        Если Не ДанныеДляОбработки.Колонки.Содержит("Статус") Тогда
            ДанныеДляОбработки.Колонки.Добавить("Статус", Новый ОписаниеТипов("Строка"));
        КонецЕсли;
        Для Каждого СтрокаТЗ Из ДанныеДляОбработки Цикл
            СтрокаТЗ.Статус = "Обработано на сервере";
        КонецЦикла;

    Иначе
        ВызватьИсключение "Получены данные неожиданного типа: " + ТипЗнч(ДанныеДляОбработки);
    КонецЕсли;

    // После того как данные обработаны и больше не нужны на сервере,
    // ОБЯЗАТЕЛЬНО удаляем их из временного хранилища.
    УдалитьИзВременногоХранилища(АдресДанных);

    // Если нужно вернуть что-то на клиент (например, обработанную таблицу или статус),
    // можно снова поместить результат во временное хранилище или вернуть как обычный параметр.
    Возврат "Обработка завершена успешно!";
КонецПроцедуры;

Принцип очистки: В нашем примере, очистка временного хранилища происходит на сервере сразу после того, как данные были получены и обработаны. Это является лучшей практикой.

Особенности работы с различными типами данных

Механизм временного хранилища основан на сериализации и десериализации объектов. Это означает, что не все типы данных могут быть успешно помещены и извлечены из временного хранилища напрямую. Однако большинство стандартных объектов 1С, включая ссылки на объекты базы данных, успешно сериализуются.

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

Пример передачи массива ссылок:

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


// На клиенте:
МассивСсылок = Новый Массив;
МассивСсылок.Добавить(Документы.ЗаказПокупателя.НайтиПоНомеру("00000001"));
МассивСсылок.Добавить(Документы.ЗаказПокупателя.НайтиПоНомеру("00000002"));

АдресМассива = ПоместитьВоВременноеХранилище(МассивСсылок, УникальныйИдентификаторФормы);
Результат = МояСервернаяПроцедураДляМассива(АдресМассива);

// На сервере:
Процедура МояСервернаяПроцедураДляМассива(АдресМассива) Экспорт
    МассивПолученныхСсылок = ПолучитьИзВременногоХранилища(АдресМассива);

    Если ТипЗнч(МассивПолученныхСсылок) = Тип("Массив") Тогда
        Сообщить("На сервере получен массив из " + МассивПолученныхСсылок.Количество() + " ссылок.");
        Для Каждого Ссылка Из МассивПолученныхСсылок Цикл
            Сообщить("Обрабатываем ссылку: " + Ссылка);
        КонецЦикла;
    КонецЕсли;

    УдалитьИзВременногоХранилища(АдресМассива);
КонецПроцедуры;

Стратегии очистки временного хранилища

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

  1. Немедленная очистка после использования: Это наиболее распространенный и рекомендуемый подход. Как только данные извлечены из хранилища и больше не нужны, они должны быть удалены.
  2. Отложенная очистка при закрытии формы: Если данные привязаны к конкретной форме (вы поместили их с УникальныйИдентификаторФормы), можно предусмотреть их удаление в обработчике события ПриЗакрытии формы.
  3. Очистка при завершении сеанса: Если вы не удаляете данные явно, они будут храниться до завершения сеанса пользователя. Для крупных систем такая стратегия не рекомендуется.

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

Альтернативные подходы и когда их использовать

Хотя временное хранилище является мощным инструментом, существуют и другие способы передачи данных:

  1. Прямая передача параметров: Для небольших объемов данных (несколько примитивных значений, небольшая структура) это наиболее простой способ.
  2. Реквизиты формы: Если данные нужны в течение всего жизненного цикла формы и их объем не критичен, можно хранить их в реквизитах формы.
  3. Объект ДвоичныеДанные и ПоместитьФайл / ПолучитьФайл: Для работы с файлами или очень большими двоичными данными.
    
    // На клиенте:
    ДвоичныеДанныеФайла = Новый ДвоичныеДанные("C:\path\to\file.txt");
    АдресФайла = ПоместитьФайл(ДвоичныеДанныеФайла, "file.txt"); 
    
    МояСервернаяПроцедураСФайлом(АдресФайла);
    

Рекомендации и лучшие практики

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

← На главную