Простой способ регистрации изменений реквизитов объектов в 1С Предприятии 8.X (делюсь опытом)
Разработка - Механизмы платформы 1С
Добавить в какой-либо общий модуль функцию и процедуру
// Возвращает значение или структуру с именами и значениями реквизитов произвольного объекта ссылочного типа
// прочитанные из информационной базы
//
// Параметры:
// Ссылка - произвольный объект ссылочного типа (справочник, документ, план обмена, ПВХ, задача)
// СтруктураРеквизитов - Необязательно. Может содержать значения:
// строка - имя реквизита объекта.
// строка - имена реквизитов, перечисленные через запятую, в формате требований к свойствам структуры.
// структура - структура с именами реквизитов.
//
//
// Возвращаемое значение:
// Структура - если СтруктураРеквизитов имеет тип Структура и заполнен - структура с именами и значениями указанных реквизитов
// Структура - если СтруктураРеквизитов не указан или не заполнен - структура с именами и значениями всех реквизитов объекта
// Произвольный - если СтруктураРеквизитов строкового типа - значение данного реквизита
//
Функция ПолучитьРеквизитыОбъекта(Знач Ссылка, Знач СтруктураРеквизитов = Неопределено) Экспорт
МетаданныеОбъекта = Ссылка.Метаданные();
ИмяТаблицы = МетаданныеОбъекта.ПолноеИмя();
ЭтоСправочник = Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка));
ЭтоПланОбмена = ПланыОбмена.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка));
ЭтоПВХ = ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка));
ЭтоДокумент = Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка));
ЭтоЗадача = Задачи.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка));
ТекстЗапроса = "ВЫБРАТЬ ";
//Формируем список реквизитов объекта для запроса
Если ТипЗнч(СтруктураРеквизитов) = Тип("Строка") И ЗначениеЗаполнено(СтруктураРеквизитов) Тогда
ТекстЗапроса = ТекстЗапроса + СокрЛП(СтруктураРеквизитов);
//Если передали список реквизитов, инициализируем структуру
Если Найти(СтруктураРеквизитов, ",") <> 0 Тогда
СтруктураРеквизитов = Новый Структура(СтруктураРеквизитов);
КонецЕсли;
ИначеЕсли ТипЗнч(СтруктураРеквизитов) = Тип("Структура") И СтруктураРеквизитов.Количество() > 0 Тогда
Для каждого Реквизит Из СтруктураРеквизитов Цикл ТекстЗапроса = ТекстЗапроса + Реквизит.Ключ + ","; КонецЦикла;
//Отрезаем последнюю запятую
ТекстЗапроса = Лев(ТекстЗапроса, СтрДлина(ТекстЗапроса) - 1);
Иначе
//Определяем список реквизитов объектов для подстановки в текст запроса
СписокРеквизитов = "";
Если ЭтоСправочник ИЛИ ЭтоПланОбмена ИЛИ ЭтоПВХ Тогда
Если МетаданныеОбъекта.ДлинаКода > 0 Тогда
СписокРеквизитов = "Код,";
КонецЕсли;
Если МетаданныеОбъекта.ДлинаНаименования > 0 Тогда
СписокРеквизитов = СписокРеквизитов + "Наименование,";
КонецЕсли;
Если ЭтоСправочник ИЛИ ЭтоПВХ Тогда
Если МетаданныеОбъекта.Иерархический Тогда
СписокРеквизитов = СписокРеквизитов + "Родитель,";
КонецЕсли;
Если ЭтоСправочник И (МетаданныеОбъекта.Владельцы.Количество() <> 0) Тогда
СписокРеквизитов = СписокРеквизитов + "Владелец,";
КонецЕсли;
КонецЕсли;
ИначеЕсли ЭтоДокумент Тогда
Если МетаданныеОбъекта.ДлинаНомера > 0 Тогда
СписокРеквизитов = "Номер,";
КонецЕсли;
СписокРеквизитов = СписокРеквизитов + "Дата,";
ИначеЕсли ЭтоЗадача Тогда
Если МетаданныеОбъекта.ДлинаНомера > 0 Тогда
СписокРеквизитов = "Номер,";
КонецЕсли;
СписокРеквизитов = СписокРеквизитов + "Дата,";
Если МетаданныеОбъекта.ДлинаНаименования > 0 Тогда
СписокРеквизитов = СписокРеквизитов + "Наименование,";
КонецЕсли;
КонецЕсли;
СписокРеквизитов = СписокРеквизитов + "ПометкаУдаления,";
Для каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл СписокРеквизитов = СписокРеквизитов + Реквизит.Имя + ","; КонецЦикла;
//Отрезаем последнюю запятую
СписокРеквизитов = Лев(СписокРеквизитов, СтрДлина(СписокРеквизитов) - 1);
СтруктураРеквизитов = Новый Структура(СписокРеквизитов);
ТекстЗапроса = ТекстЗапроса + СписокРеквизитов;
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "
|ИЗ " + ИмяТаблицы + "
|ГДЕ Ссылка = &Ссылка";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующий() Тогда
Если ТипЗнч(СтруктураРеквизитов) = Тип("Строка") И ЗначениеЗаполнено(СтруктураРеквизитов) Тогда
Возврат Выборка[СтруктураРеквизитов];
Иначе
ЗаполнитьЗначенияСвойств(СтруктураРеквизитов, Выборка);
Возврат СтруктураРеквизитов;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции //ПолучитьРеквизитыОбъекта()
// Универсальная процедура, регистрирующая изменения реквизитов объекта (справочник, документ, план обмена, ПВХ)
// в журнале регистрации
//
Процедура РегистрацияИзмененийРеквизитовОбъекта(Объект) Экспорт
Перем МетаданныеОбъекта;
Если НЕ Объект.Ссылка.Пустая() Тогда
МетаданныеОбъекта = Объект.Метаданные();
СтрокаСобытие = "Данные.ИзменениеРеквизитов." + МетаданныеОбъекта.Имя;
ПрежнийОбъект = Объект.Ссылка;
РеквизитыПрежнегоОбъекта = ПолучитьРеквизитыОбъекта(ПрежнийОбъект);
СтрокаСообщениеРеквизит = "Изменён реквизит ";
СтрокаСообщениеТабЧасть = "Изменена таб.часть ";
СтрокаСообщениеТабЧастьУдалено = "Удалено ";
СтрокаСообщениеТабЧастьДобавлено = "Добавлено ";
Для Каждого Элемент из РеквизитыПрежнегоОбъекта Цикл
ПрежнийРеквизитЗначение = Элемент.Значение;
НовыйРеквизитЗначение = Объект[Элемент.Ключ];
Если ТипЗнч(НовыйРеквизитЗначение) = Тип("Строка") Тогда
НовыйРеквизитЗначение = СокрЛП(НовыйРеквизитЗначение);
КонецЕсли;
Если ТипЗнч(ПрежнийРеквизитЗначение) = Тип("Строка") Тогда
ПрежнийРеквизитЗначение = СокрЛП(ПрежнийРеквизитЗначение);
КонецЕсли;
Если ПрежнийРеквизитЗначение <> НовыйРеквизитЗначение Тогда
ЗаписьЖурналаРегистрации(СтрокаСобытие, УровеньЖурналаРегистрации.Предупреждение, МетаданныеОбъекта, ПрежнийОбъект, СтрокаСообщениеРеквизит + Элемент.Ключ + Символы.ВК + "Прежний: " + Строка(ПрежнийРеквизитЗначение) + Символы.ВК + "Новый: " + Строка(НовыйРеквизитЗначение));
КонецЕсли;
КонецЦикла;
Если МетаданныеОбъекта.ТабличныеЧасти.Количество() > 0 Тогда
// Определяем список проверяемых реквизитов табличных частей,
// чтобы не забивать журнал регистрации лишними записями.
// Для каждой конфигурации определить свой список, либо удалить проверку
// Здесь приведён пример для Управления Торговлей.
ПроверяемыеРеквизитыТабЧасти = Новый Структура("Номенклатура, ЕдиницаИзмерения, Количество, Цена, Сумма, СтавкаНДС, СерияНоменклатуры, ХарактеристикаНоменклатуры, СерияНоменклатурыНовая, ХарактеристикаНоменклатурыНовая, СерияНоменклатурыСтарая, ХарактеристикаНоменклатурыСтарая, Проект, ЗаказПокупателя, Сделка, ДокументПартии, ДокументРасчетовСКонтрагентом, СуммаВзаиморасчетов, ДоговорКонтрагента, Контрагент, СтатьяДвиженияДенежныхСредств, ПроцентСкидкиНаценки, НаименованиеТовара, ЗаказПоставщику, ДокументПоступления, ДокументОснование, ИсходноеРазмещение, НовоеРазмещение, СуммаТовара, СуммаПлатежа, Размещение, УвеличениеДолгаКонтрагента, УменьшениеДолгаКонтрагента, КоличествоУчет, ДокументРезерва, ТипЦен, Валюта, Пользователь, ВидЗадолженности, ВидОперации");
//This code is ported from http://www.kb.mista.ru/article.php?id=115
Для Каждого МДТЧ ИЗ МетаданныеОбъекта.ТабличныеЧасти Цикл
ИмяТЧ = МДТЧ.Имя;
ТЧ1 = Объект[ИмяТЧ];
ТЧ2 = ПрежнийОбъект[ИмяТЧ];
ТЧ1Количество = ТЧ1.Количество();
ТЧ2Количество = ТЧ2.Количество();
Если ТЧ1Количество <> ТЧ2Количество Тогда
ЗаписьЖурналаРегистрации(СтрокаСобытие, УровеньЖурналаРегистрации.Предупреждение, МетаданныеОбъекта, Объект.Ссылка, СтрокаСообщениеТабЧасть + ИмяТЧ + Символы.ВК + "Прежняя: " + Строка(ТЧ2Количество) + ". Новая: " + Строка(ТЧ1Количество));
КонецЕсли;
Если ТЧ1Количество = ТЧ2Количество Тогда
СтрокаСообщение = СтрокаСообщениеРеквизит;
ИначеЕсли ТЧ2Количество > ТЧ1Количество Тогда
СтрокаСообщение = СтрокаСообщениеТабЧастьУдалено;
ИначеЕсли ТЧ2Количество < ТЧ1Количество Тогда
СтрокаСообщение = СтрокаСообщениеТабЧастьДобавлено;
КонецЕсли;
Для Инд = 0 По Макс(ТЧ1Количество - 1, ТЧ2Количество - 1) Цикл
Для Каждого МДРТЧ ИЗ МДТЧ.Реквизиты Цикл
Реквизит = МДРТЧ.Имя;
// При необходимости проверку можно удалить
Если НЕ ПроверяемыеРеквизитыТабЧасти.Свойство(Реквизит) Тогда
Продолжить;
КонецЕсли;
Если Инд >= ТЧ1Количество Тогда
НовыйРеквизитЗначение = Неопределено;
Иначе
НовыйРеквизитЗначение = ТЧ1[Инд][Реквизит];
КонецЕсли;
Если Инд >= ТЧ2Количество Тогда
ПрежнийРеквизитЗначение = Неопределено;
Иначе
ПрежнийРеквизитЗначение = ТЧ2[Инд][Реквизит];
КонецЕсли;
Если (ЗначениеЗаполнено(ПрежнийРеквизитЗначение) И ЗначениеЗаполнено(НовыйРеквизитЗначение)) ИЛИ (НЕ ЗначениеЗаполнено(ПрежнийРеквизитЗначение) И ЗначениеЗаполнено(НовыйРеквизитЗначение)) ИЛИ (ЗначениеЗаполнено(ПрежнийРеквизитЗначение) И НЕ ЗначениеЗаполнено(НовыйРеквизитЗначение)) Тогда
Если ТипЗнч(НовыйРеквизитЗначение) = Тип("Строка") Тогда
НовыйРеквизитЗначение = СокрЛП(НовыйРеквизитЗначение);
КонецЕсли;
Если ТипЗнч(ПрежнийРеквизитЗначение) = Тип("Строка") Тогда
ПрежнийРеквизитЗначение = СокрЛП(ПрежнийРеквизитЗначение);
КонецЕсли;
Если НовыйРеквизитЗначение <> ПрежнийРеквизитЗначение Тогда
ЗаписьЖурналаРегистрации(СтрокаСобытие, УровеньЖурналаРегистрации.Предупреждение, МетаданныеОбъекта, Объект.Ссылка, СтрокаСообщение + ИмяТЧ + "." + Реквизит + " в строке " + (Инд + 1) + Символы.ВК + "Прежний: " + Строка(ПрежнийРеквизитЗначение) + Символы.ВК + "Новый: " + Строка(НовыйРеквизитЗначение));
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Создать подписку на событие для документов
Источник = ДокументОбъект
Событие = ПередЗаписью
Назначить обработчик события
Процедура ПередЗаписьюДокументаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
//Изменения будем регистрировать для случаев проведения или отмены проведения,
//так как для простой записи контроль не имеет особого смысла
Если НЕ Отказ И ((РежимЗаписи = РежимЗаписиДокумента.Проведение) ИЛИ (РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения)) Тогда
РегистрацияИзмененийРеквизитовОбъекта(Источник);
КонецЕсли;
КонецПроцедуры
Создать подписку на событие для справочников (ПВХ, планов обменов)
Источник = ПланВидовХарактеристикОбъект, ПланОбменаОбъект, СправочникОбъект
Событие = ПередЗаписью
Назначить обработчик события
//Регистрируем изменения для справочника, плана обмена, ПВХ
//
Процедура ПередЗаписьюОбъектаПередЗаписью(Источник, Отказ) Экспорт
Если НЕ Отказ Тогда
РегистрацияИзмененийРеквизитовОбъекта(Источник);
КонецЕсли;
КонецПроцедуры
Собственно всё. Со вчерашнего дня сие творчество стоит на дежурстве в рабочей конфигурации.
Скриншот результатов работы процедуры в журнале регистрации

Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
См. также
Механизмы платформы 1С Разработчик Бесплатно (free)
Разберем 15 мифов о работе платформы «1С:Предприятие 8» – как распространенных, так и малоизвестных. Начнем с классики: «Код, написанный в одну строку, работает быстрее, чем многострочный». Так ли это на самом деле?
16.07.2025 45646 TitanLuchs 109
Работа с интерфейсом WEB-интеграция Механизмы платформы 1С Бесплатно (free)
Веб-интерфейсы повышают качество внешнего вида приложений 1С, предсказуемы с точки зрения верстки, позволяют организовать удобные и высокопроизводительные рабочие места для пользователей. Расскажем об особенностях разработки веб-интерфейсов на React внутри 1С, двустороннем взаимодействии 1С и JavaScript, а также сборке веб-приложения в одностраничный файл.
19.06.2025 18657 zeegin 15
Механизмы платформы 1С Работа с интерфейсом Разработчик Стажер 1С:Предприятие 8 Бесплатно (free)
Про ООП в 1С и о том, как сделать свой код более кратким и выразительным при помощи использования текучего интерфейса (fluent interface).
03.02.2025 26020 bayselonarrend 127
Механизмы платформы 1С Разработчик 1С:Предприятие 8 Бесплатно (free)
В этой статье подробно рассматривается работа с JSON в XDTO в 1С:Предприятие. Вы узнаете, как сериализовать и десериализовать объекты XDTO в JSON, интегрировать 1С с веб-сервисами и API, а также корректно обрабатывать данные при обмене. Разбираются особенности работы с коллекциями, использование функций восстановления и частые ошибки при работе с JSON и XDTO.
30.01.2025 33263 user2122906 10
Механизмы платформы 1С Файловый обмен (TXT, XML, DBF), FTP Разработчик 1С:Предприятие 8 Бесплатно (free)
Этот материал познакомит вас с механизмом XDTO (XML Data Transfer Objects) в 1С и научит эффективно использовать его возможности. Мы разберёмся, как работать с XML-схемами, создавать модели данных, манипулировать объектами XDTO, а также сериализовать и десериализовать их в XML. Вы узнаете, как использовать XDTO для интеграции с внешними системами, избегать типичных ошибок и оптимизировать код. К концу вы будете уверенно применять XDTO для решения сложных задач обмена данными и автоматизации процессов.
17.01.2025 55714 user2122906 13
Механизмы платформы 1С WEB-интеграция Разработчик 1С:Предприятие 8 Бесплатно (free)
В платформе 8.3.27 появилась возможность использовать WebSocket-клиент. Давайте посмотрим, как это все устроено и чем оно нам полезно.
14.01.2025 46759 dsdred 110
Механизмы платформы 1С Разработчик 1С:Предприятие 8 Бесплатно (free)
Особенности "Знач" и разбор документации к нему.
10.01.2025 26436 VAAngelov 60
Механизмы платформы 1С Разработчик Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)
Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.
23.06.2024 40431 bayselonarrend 24
1. Учитывая что анонсировано для 8.1, то почему бы не использовать подписку на события? и типового изменения меньше
2. Кто нить пробовал наложить фильтр на журнал регистрации в случае активной работы? И вы еще хотите туда что-то еще добавлять? и как это потом анализировать?
.
1. отслежтвается программное изменение реквизитов? если нет - в сад!
2. способна прога понять, что изменение порядка строк не является изменением? если нет - в сад!
.. пока хватит..
1. Отслеживается. Подписка на событие срабатывает в любом случае. Учи матчасть. В сад.
2. не способна, так как и не требовалось по условиям матча. Остальное пох. опять же ва сад.
Кстати для этих целей я внедрил в конфу быстрый журнал регистрации.
С сабжем добавление не связано.
Из найденного - не регистрирует изменения для ПВХ и планов счетов, ошибка на строчках:
Если МетаданныеОбъекта.Иерархический ....
И
Если (МетаданныеОбъекта.Владельцы.Количество() .....
Нет для них таких свойств метаданных
Например, ИМХО в БП им это нафиг не нужно, до сих пор механизм полезнейший механизм свойств не добавили :(
В ЗиК-е вполне могут добавить, хотя также очень сомневаюсь.
(23) Кода многовато? ты в УПП-то код версионирования видел? :)
Причем система до этого работала не один месяц, проблемы с блокировками были незаметны.
В результате анализа выяснил, что ошибка в использовании объектного подхода - типа ПрежнийОбъект.Номер
А прежний объект - это ведь ссылка, и идет получение инфы из базы.
Перевел код на использование запросов, блокировки исчезли.
Лучше накапливать изменения и записывать их в журнал после того как зафиксирована транзакция и освобождены все блокировки
см. справку по РегистрСведенийНаборЗаписей
метод Метаданные() у объекта есть, см. Имя Регистра, определяем нужно ли по нему вести историю
Отбор - доступен, через него можно же получить текущее состояние ИБ
Сравнить Источник и Текущее состояние в ИБ.
В типовом варианте сериализация в XML и сохранение в регистр работать будет значительно быстрее, а значит вероятность получить дедлок существенно меньше, т.к. в обоих случаях работаем в рамках транзакции записи.
добавил
а вот это не катит, иначе как у меня будет работать модуль, если его вообще нЕоткуда вызвать?!
Может, подписки и регистрацию изменений разместить в одном модуле?
Вы можете заказать платную консультацию или разработку у автора. Будет создан приватный заказ на «Бирже заказов» для автора.
№ 19949
Создание 11.05.09 17:55
Обновление 15.05.13 20:41
Просмотры 69297
Загрузки 0
Рейтинг
213
Комментарии 77
Код открыт Не указано
Рубрики Механизмы платформы 1С
Кому Разработчик
Тип файла Нет файла
Платформа 1С:Предприятие 8
Конфигурация 1C:Бухгалтерия
Операционная система Не имеет значения
Страна Россия
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Доступ к файлу Бесплатно (free)