В практике разработки на платформе 1С часто возникает задача временного или постоянного хранения данных, которые вводятся пользователем непосредственно в отчете. Типичный пример: установка «плана на неделю», который должен подтягиваться при каждом формировании отчета, но при этом заказчик или архитектура системы не позволяют создавать новые объекты метаданных (например, Регистры Сведений). Рассмотрим, как реализовать сохранение таблицы значений, используя штатные механизмы платформы, и разберем плюсы и минусы каждого подхода.
Самым логичным и «чистым» способом сохранения данных без изменения структуры метаданных является использование системного хранилища настроек. Платформа 1С предоставляет объект ХранилищеОбщихНастроек, который позволяет сохранять произвольные данные (в том числе структуры и таблицы значений) в привязке к объекту и пользователю.
Разберем пример реализации сохранения настроек, где мы упаковываем таблицу значений в структуру и записываем её в базу. Рассмотрим программный код, который позволяет организовать сохранение:
Процедура СохранитьНастройкиНажатие(Элемент)
// Формируем структуру сохраняемых реквизитов
СохраненнаяНастройка = Новый Структура;
СохраненнаяНастройка.Вставить("Организация", Организация);
СохраненнаяНастройка.Вставить("ТипЦен", ТипЦен);
// Выгружаем табличную часть или таблицу значений в переменную
ТабЧасть = Настройка.Выгрузить();
СохраненнаяНастройка.Вставить("ТабЧасть", ТабЧасть);
// Подготавливаем структуру для системного механизма
СтруктураНастройки = Новый Структура;
// Если нужно сохранить для конкретного пользователя (выбор пользователя)
ТекПольз = Справочники.Пользователи.НайтиПоНаименованию("Иванов");
Если ЗначениеЗаполнено(ТекПольз) Тогда
СтруктураНастройки.Вставить("Пользователь", ТекПольз);
КонецЕсли;
СтруктураНастройки.Вставить("ИмяОбъекта", ЭтотОбъект.Метаданные.Имя);
СтруктураНастройки.Вставить("НаименованиеНастройки", "ПланНаНеделю_Общая");
СтруктураНастройки.Вставить("СохраненнаяНастройка", СохраненнаяНастройка);
// Вызов стандартного механизма сохранения (в типовых конфигурациях)
УниверсальныеМеханизмы.СохранитьНастройку(СтруктураНастройки);
КонецПроцедуры
Важный нюанс: По умолчанию ХранилищеОбщихНастроек работает в разрезе пользователей. Если ваша задача — сделать так, чтобы один пользователь установил план, а остальные его увидели, вам потребуется записывать настройку с правами Администратора или использовать привилегированный режим.
Если рядовые пользователи не имеют прав на запись общих настроек «для всех», мы можем использовать программный переключатель прав. Это позволит системе выполнить запись данных в хранилище от имени системы, игнорируя ограничения текущего пользователя. Проанализируем, как это реализовать в коде:
Процедура ЗаписатьОбщийПлан(ДанныеПлана)
УстановитьПривилегированныйРежим(Истина);
// Сохраняем данные без привязки к конкретному пользователю (используя общий ключ)
ХранилищеОбщихНастроек.Сохранить("УстановкаПланаПродаж", "ОбщийПлан", ДанныеПлана, , "ОбщаяНастройкаДляВсех");
УстановитьПривилегированныйРежим(Ложь);
Сообщить("Данные успешно сохранены для всех пользователей.");
КонецПроцедуры
Выясним причину, по которой этот метод может не сработать. Если ваш отчет является внешним и запускается в безопасном режиме (что часто встречается в клиент-серверных версиях при использовании справочника «Дополнительные отчеты и обработки»), метод УстановитьПривилегированныйРежим будет проигнорирован. В этом случае необходимо либо отключить безопасный режим для данного отчета, либо использовать альтернативные пути хранения.
Если работа с хранилищем настроек затруднена из-за политик безопасности или специфики конфигурации, можно прибегнуть к сохранению данных в файл. Рассмотрим этот вариант подробнее. Автор темы выбрал сохранение в формат Excel, однако с технической точки зрения для 1С более надежными являются форматы XML или JSON.
Почему XML/JSON лучше Excel?
Рассмотрим пример сохранения таблицы значений в XML-файл, расположенный в общей сетевой папке:
Процедура СохранитьТЗвФайл(ТаблицаПланов)
ПутьКФайлу = "\\Server\Share\Settings\weekly_plan.xml";
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ПутьКФайлу);
// Сериализуем таблицу значений в формат XML
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ТаблицаПланов);
ЗаписьXML.Закрыть();
КонецПроцедуры
Для восстановления данных при открытии отчета мы используем обратную операцию:
Функция ПрочитатьТЗизФайла()
ПутьКФайлу = "\\Server\Share\Settings\weekly_plan.xml";
Файл = Новый Файл(ПутьКФайлу);
Если Не Файл.Существует() Тогда
Возврат Неопределено;
КонецЕсли;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлу);
Попытка
Таблица = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Возврат Таблица;
Исключение
Сообщить("Ошибка чтения данных плана!");
Возврат Неопределено;
КонецПопытки;
ЧтениеXML.Закрыть();
КонецФункции
Если ваша конфигурация построена на базе БСП (Библиотека стандартных подсистем), проанализируем возможность использования механизма дополнительных сведений. Это позволяет «прикрепить» данные к любому существующему объекту, например, к конкретной организации или даже к самому элементу справочника, в котором зарегистрирован ваш внешний отчет.
Посмотрим на алгоритм действий:
ЗначениеВСтрокуВнутр).Этот способ хорош тем, что данные хранятся внутри базы данных 1С, они попадают в бэкапы и доступны всем пользователям, у которых есть права на чтение «якорного» объекта, при этом никаких изменений в конфигураторе делать не нужно.
Подведем итоги нашего анализа. Выбор метода зависит от ваших условий:
Помните, что использование ЗначениеВСтрокуВнутр и ЗначениеИзСтрокиВнутр — это самый простой способ превратить сложную таблицу в обычную строку для хранения, однако этот метод чувствителен к изменениям версии платформы, поэтому СериализаторXDTO является более предпочтительным инструментом для долгосрочного хранения.