Как и где временно сохранить динамическую таблицу значений в 1С для последующего использования?

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

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

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

Вариант 1. Использование регистра сведений

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

Основные преимущества использования регистра:

  1. Структурированность: Каждая колонка вашей динамической таблицы становится отдельным ресурсом или реквизитом регистра.
  2. Возможность анализа: Вы можете использовать стандартные запросы 1С для поиска нужных строк, фильтрации и группировки данных.
  3. Длительное хранение: Данные никуда не пропадут при закрытии сеанса или перезагрузке сервера.

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

Разберем пример кода для записи таблицы значений в регистр:


Для Каждого СтрокаТЗ Из МояДинамическаяТаблица Цикл
    МенеджерЗаписи = РегистрыСведений.ВременныеДанныеОбработок.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Период = ТекущаяДата();
    МенеджерЗаписи.Пользователь = ПараметрыСеанса.ТекущийПользователь;
    МенеджерЗаписи.ИдентификаторДанных = "УникальныйКлюч_123";
    
    // Заполняем ресурсы из колонок таблицы
    ЗаполнитьЗначенияСвойств(МенеджерЗаписи, СтрокаТЗ);
    
    МенеджерЗаписи.Записать();
КонецЦикла;

Проанализируем ситуацию с очисткой: поскольку данные «временные», база будет расти. Рекомендуется создать регламентное задание, которое будет удалять записи старше определенного количества дней, чтобы не забивать таблицы базы данных лишней информацией.

Вариант 2. Объект «ХранилищеЗначений» в справочнике или регистре

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

Рассмотрим, как это работает. Мы создаем в справочнике (например, Пользователи или специальном техническом справочнике) реквизит с типом ХранилищеЗначений. Весь массив данных «упаковывается» в бинарный вид.

Пример сохранения таблицы:


// Сериализуем таблицу в хранилище со сжатием
ОбъектХранения = Справочники.ТехническиеДанные.СоздатьЭлемент();
ОбъектХранения.Наименование = "Временная таблица от " + ТекущаяДата();
ОбъектХранения.Данные = Новый ХранилищеЗначений(МояДинамическаяТаблица, Новый СжатиеДанных(9));
ОбъектХранения.Записать();

Важный момент: Этот способ очень быстр в реализации, но имеет ограничение. Если в таблице содержатся несериализуемые объекты (например, COM-объекты или активные формы), при попытке записи возникнет ошибка. Также помните, что для извлечения даже одной строчки вам придется прочитать из базы и десериализовать всю таблицу целиком.

Вариант 3. Хранилище общих настроек (CommonSettingsStorage)

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

Посмотрим на пример программного сохранения:


// Сохраняем таблицу настроек
ХранилищеОбщихНастроек.Сохранить("МояОбработка", "КлючТаблицыДанных", МояДинамическаяТаблица);

// Загружаем данные обратно
МояДинамическаяТаблица = ХранилищеОбщихНастроек.Загрузить("МояОбработка", "КлючТаблицыДанных");

Этот метод хорош тем, что не требует изменения метаданных конфигурации (создания новых регистров или справочников). Но он не подходит для хранения очень больших объемов данных, хотя для простых параметров часто применяют шаблон дополнительной обработки с сохранением параметров.

Вариант 4. Сериализация в JSON или XML (Файловый метод)

Если данные не обязательно хранить в самой базе данных SQL, или если их нужно передать между разными базами, можно использовать сохранение в файл. Самым современным форматом является JSON.

Разберем по шагам, как превратить таблицу в строку JSON:

  1. Создаем объект ЗаписьJSON.
  2. Используем метод ЗаписатьJSON, передавая туда таблицу значений.
  3. Сохраняем полученную строку в текстовый файл на диске или в присоединенный файл объекта базы.

Пример записи в JSON:


Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, МояДинамическаяТаблица);
СтрокаРезультат = Запись.Закрыть();
// Далее сохраняем СтрокаРезультат в файл или реквизит

Методы ЗначениеВФайл() и ЗначениеИзФайла(), упомянутые в обсуждении, работают аналогично, но используют внутренний формат 1С. Они проще, но менее универсальны, если вы захотите прочитать эти данные чем-то, кроме 1С.

О чем важно помнить (Технические нюансы)

При выборе любого из способов мы должны учитывать критические ограничения платформы:

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

2. Циклические ссылки: Если одна строка таблицы ссылается на другую структуру, которая в свою очередь ссылается на первую, возникнет бесконечная петля при попытке записи в ХранилищеЗначений, что может привести к аварийному завершению работы рабочего процесса сервера.

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

Итоги: что же выбрать?

Подводя итоги нашего анализа, можно дать следующие рекомендации:

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

← На главную