В типовых конфигурациях, таких как 1С:Бухгалтерия предприятия 3.0, стандартный реквизит Ответственный отражает пользователя, закрепленного за документом, но не всегда гарантирует, что именно этот человек внес последние изменения. В процессе разработки отчетов или печатных форм часто возникает необходимость вывести имя пользователя, который реально отредактировал или создал объект.
Рассмотрим подробнее основные способы решения этой задачи, их преимущества, ограничения и примеры реализации в программном коде.
Подсистема БСП «Версионирование объектов» сохраняет историю изменений справочников и документов. Данные о версиях записываются в регистр сведений ВерсииОбъектов, где ресурс Автор содержит ссылку на справочник Пользователи.
Для включения функционала в режиме «1С:Предприятие» перейдем по пути: Администрирование -> Общие настройки -> История изменений и установим флаг Хранить историю изменений. После этого выберем нужные документы и настроим для них режим версионирования (например, «Версионировать при записи»).
Разберем по шагам, как запросом получить последнего пользователя, изменившего документ:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ВерсииОбъектов.Автор КАК АвторИзменения,
| ВерсииОбъектов.ДатаВерсии КАК ДатаИзменения
|ИЗ
| РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
|ГДЕ
| ВерсииОбъектов.Объект = &СсылкаНаДокумент
|УПОРЯДОЧИТЬ ПО
| ВерсииОбъектов.НомерВерсии УБЫВ
|";
Запрос.УстановитьПараметр("СсылкаНаДокумент", СсылкаНаДокумент);
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
ПользовательИзменивший = Выборка.АвторИзменения;
КонецЕсли;
Если необходимо получить первого автора (создателя документа), достаточно изменить сортировку запроса на УПОРЯДОЧИТЬ ПО ВерсииОбъектов.НомерВерсии ВОЗР.
Начиная с версии платформы 8.3.11, доступен встроенный механизм истории данных. В отличие от БСП, платформенный механизм работает быстрее и оптимизирован на уровне СУБД.
Проанализируем пример получения сведений о версиях через менеджер ИсторияДанных:
МассивВерсий = ИсторияДанных.ПолучитьИсторияИзменений(СсылкаНаДокумент);
Если МассивВерсий.Количество() > 0 Тогда
// Последняя версия в массиве содержит сведения о завершающем редактировании
ПоследняяВерсия = МассивВерсий[МассивВерсий.Количество() - 1];
ПользовательМодификатор = ПоследняяВерсия.Пользователь;
ДатаМодификации = ПоследняяВерсия.Дата;
КонецЕсли;
Журнал регистрации фиксирует все события записи и проведения объектов. Этот метод не требует изменения конфигурации или включения дополнительного версионирования, однако считывание данных журнала может создавать нагрузку при частых вызовах.
Посмотрим на пример выгрузки данных с помощью функции ВыгрузитьЖурналРегистрации:
ТаблицаСобытий = Новый ТаблицаЗначений;
Фильтр = Новый Структура;
Фильтр.Вставить("Данные", СсылкаНаДокумент);
МассивСобытий = Новый Массив;
МассивСобытий.Добавить("_$Data$_.Update");
МассивСобытий.Добавить("_$Data$_.Post");
Фильтр.Вставить("Событие", МассивСобытий);
ВыгрузитьЖурналРегистрации(ТаблицаСобытий, Фильтр, "Пользователь, Дата");
Если ТаблицаСобытий.Количество() > 0 Тогда
// Последняя строка содержит самое свежее событие
ПоследняяЗапись = ТаблицаСобытий[ТаблицаСобытий.Количество() - 1];
ИмяПользователя = ПоследняяЗапись.Пользователь;
КонецЕсли;
Если требуется хранить информацию о создателе и редакторе непосредственно в объекте, наиболее корректный подход — использование расширения конфигурации. Это позволяет оставить типовую конфигурацию на автоматическом обновлении.
Выясним порядок действий для реализации данного варианта:
АвторСоздания и АвторИзменения (тип СправочникСсылка.Пользователи).ПередЗаписью для нужных документов.
Процедура ПодпискаПриЗаписиЗаполнениеАвтораПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
ТекущийПользовательБазы = Пользователи.ТекущийПользователь();
Если Источник.ЭтоНовый() Тогда
Источник.АвторСоздания = ТекущийПользовательБазы;
КонецЕсли;
Источник.АвторИзменения = ТекущийПользовательБазы;
КонецПроцедуры
Чтобы отобразить пользователя, изменившего документ, при печати, рекомендуется использовать расширение конфигурации с перехватом процедуры печати в модуле менеджера или внешнюю печатную форму.
При формировании табличного документа вызываем выбранную процедуру (например, запрос к регистру ВерсииОбъектов) и подставляем полученное имя пользователя в параметр соответствующей области макета:
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
ОбластьПодвал.Параметры.ИзменилПользователь = ПользовательИзменивший;
ТабличныйДокумент.Вывести(ОбластьПодвал);
Таким образом, выбор метода зависит от требований к базе данных: для типовых конфигураций без снятия с поддержки оптимально использовать подсистему версионирования БСП или расширение конфигурации с собственными реквизитами.