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

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

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

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

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

Разберем по шагам логику реализации:

  1. Создадим непериодический регистр сведений, например, СохраненныеРезультатыОтчетов.
  2. В качестве измерений добавим Сотрудник (тип СправочникСсылка.Сотрудники) и, при необходимости, ВидОтчета.
  3. Ресурсом регистра сделаем поле ДанныеОтчета с типом ХранилищеЗначения.

Рассмотрим пример кода для сохранения текущего табличного документа с формы отчета в регистр:


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

Для восстановления документа при открытии формы используем обратный метод Получить(). Выясним важный нюанс: сохранять документ нужно именно в формате .mxl (внутри объекта ТабличныйДокумент), так как экспорт в PDF или Excel сделает невозможным дальнейшее редактирование ячеек средствами 1С.

Вариант 2. Интеграция с подсистемой «Присоединенные файлы» (БСП)

Если в вашей конфигурации используется Библиотека стандартных подсистем (БСП), мы можем задействовать штатный механизм присоединенных файлов. Это более «чистый» архитектурный подход, так как он поддерживает версионность.

Проанализируем преимущества этого метода:

Для реализации нам потребуется программно сконвертировать ТабличныйДокумент в двоичные данные и передать их в функции БСП. Посмотрим на логику вызова:


// Пример получения двоичных данных для сохранения
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("mxl");
ТабличныйДокумент.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.MXL);
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);

// Далее используем программный интерфейс БСП РаботаСФайлами.ПриложитьФайл...

Вариант 3. Создание технического документа-контейнера

Иногда редактирование результата — это признак того, что данные должны храниться в базе, но для них нет подходящих полей. Посмотрим на ситуацию с точки зрения методологии: если пользователь постоянно дописывает «Особые условия», возможно, стоит создать документ ПодготовкаДоговора.

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

Вариант 4. Сериализация в XML/JSON для передачи между клиентом и сервером

Если задача стоит максимально просто — сохранить «как есть» без создания новых объектов метаданных, можно рассмотреть метод преобразования табличного документа в строку XML. Рассмотрим подробнее, как это реализовать:

При нажатии кнопки «Сохранить» мы переводим документ в поток данных:


&НаСервере
Функция ПолучитьСтрокуИзТабДока(ТабДок)
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ТабДок);
    Возврат ЗаписьXML.Закрыть();
КонецФункции

Такую строку можно хранить даже в дополнительном реквизите справочника Сотрудники (тип ДополнительныеСведения), если не хочется вносить изменения в структуру конфигурации.

Рекомендации по выбору метода

Выясним, какой метод лучше подходит для ваших условий:

1. Если правок очень много и они хаотичны: Используйте Вариант 1 (Регистр сведений). Это обеспечит быстрое сохранение «один в один» и позволит пользователю вернуться к работе с того же места, где он остановился. 2. Если важна юридическая значимость и история: Выбирайте Вариант 2 (БСП). Возможность видеть, кто и когда изменил файл договора, критически важна для кадрового учета. 3. Если правки можно формализовать: Лучше потратить время на Вариант 3 (Доп. реквизиты). Это позволит в будущем строить отчеты по этим данным, чего невозможно сделать, если текст просто «нарисован» в табличном документе.

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

← На главную