В процессе разработки в среде 1С:Предприятие (особенно в типовых конфигурациях вроде УТ 10.3, УПП 1.1 или КА 1.1) часто возникает задача автоматического заполнения дополнительных свойств объектов. Однако начинающие разработчики часто сталкиваются с ситуацией, когда код записи в регистр ЗначенияСвойствОбъектов отрабатывает без ошибок, но данные в регистре так и не появляются или исчезают сразу после записи объекта. Рассмотрим подробно, почему это происходит и как правильно реализовать этот механизм.
Проанализируем ситуацию, когда код помещается в процедуру ПриЗаписи модуля объекта. В типовых конфигурациях на обычных формах реализован мощный универсальный механизм работы с дополнительными свойствами. Когда пользователь нажимает кнопку "Записать", запускается целая цепочка событий:
ПередЗаписью в модуле объекта.ПриЗаписи, где разработчик часто пытается напрямую записать данные в регистр сведений.ЗначенияСвойствОбъектов по данному объекту.Если вашего нового свойства нет в этом "стандартном" списке свойств формы, типовой механизм просто перезапишет регистр, удалив вашу только что созданную запись. Именно поэтому запись в модуле объекта часто оказывается бесполезной — она просто затирается последующим кодом конфигурации.
Как показывает практика, наиболее простым решением при работе в интерактивном режиме (через форму) является перенос кода в процедуру ПослеЗаписи модуля формы. Разберем, почему это эффективно. Это событие вызывается уже после того, как основная транзакция записи объекта завершена и все стандартные механизмы очистки и заполнения свойств отработали. Ваша запись будет "последним словом" в цепочке событий.
Пример кода для модуля формы:
Процедура ПослеЗаписи(Отказ)
// Убедимся, что объект записан и у нас есть ссылка
Если НЕ ЭтотОбъект.Ссылка.Пустая() Тогда
ЗаписатьЗначениеСвойства(ТекущаяДата(), "ДатаИзмененияКонтрагента", ЭтотОбъект.Ссылка);
КонецЕсли;
КонецПроцедуры
Для записи одиночных значений в независимый регистр сведений удобнее всего использовать РегистрСведенийМенеджерЗаписи. Этот объект позволяет работать с конкретной строкой регистра, определяемой набором измерений. Рассмотрим универсальную функцию, которую можно разместить в общем модуле:
Процедура ЗаписатьЗначениеСвойства(Значение, ИмяСвойства, ОбъектСсылка) Экспорт
// 1. Поиск свойства в Плане видов характеристик
СвойствоСсылка = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию(ИмяСвойства);
Если СвойствоСсылка.Пустая() Тогда
Сообщить("Свойство '" + ИмяСвойства + "' не найдено!");
Возврат;
КонецЕсли;
// 2. Работа с менеджером записи
МенеджерЗаписи = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = ОбъектСсылка;
МенеджерЗаписи.Свойство = СвойствоСсылка;
// Читаем существующую запись, чтобы не перезаписывать лишнего, если это нужно
МенеджерЗаписи.Прочитать();
МенеджерЗаписи.Значение = Значение;
Попытка
МенеджерЗаписи.Записать(Истина); // Параметр Истина означает замещение существующей записи
Исключение
Сообщить("Ошибка при записи свойства: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Если вам необходимо записать сразу несколько свойств или вы предпочитаете работать с коллекциями, используйте РегистрСведенийНаборЗаписей. Это более производительный метод при массовых изменениях. Проанализируем важный нюанс: при использовании набора записей необходимо устанавливать отбор, иначе метод Записать() может очистить весь регистр (если не установлен отбор) или перезаписать данные по другим объектам.
НаборЗаписей = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Объект.Установить(ЭтотОбъект.Ссылка);
НаборЗаписей.Отбор.Свойство.Установить(ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("ДатаИзменения"));
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Объект = ЭтотОбъект.Ссылка;
НоваяЗапись.Свойство = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("ДатаИзменения");
НоваяЗапись.Значение = ТекущаяДата();
НаборЗаписей.Записать(Истина);
Внимание: Если вы устанавливаете отбор только по Объекту, но не по Свойству, то вызов Записать(Истина) удалит все остальные дополнительные свойства этого контрагента и оставит только те, что вы добавили в набор в текущем коде. Будьте осторожны!
Выясним одну из частых причин неудач при поиске свойства. Метод НайтиПоНаименованию чувствителен к точному написанию. В типовых конфигурациях (УТ 10.3) наименование элемента в Плане видов характеристик СвойстваОбъектов часто выглядит так: "ДатаИзменения (Контрагенты)". Если вы ищете просто "ДатаИзменения", система может ничего не найти.
Рекомендуется проверить реальное наименование в режиме "Предприятие" или использовать поиск по коду, если вы создали предопределенный элемент. Также убедитесь, что тип значения, который вы записываете (например, Дата), совпадает с типом, разрешенным для этого свойства в настройках ПВХ. Хотя ресурс Значение в регистре обычно имеет составной тип, несоответствие типов может привести к ошибкам в стандартных отчетах.
Если запись по-прежнему пропадает, воспользуемся инструментами отладки. Рассмотрим алгоритм поиска "виновника":
Записать().Записать для регистра ЗначенияСвойствОбъектов. Так вы увидите, какой общий модуль или подписка на событие срабатывает после вашего кода и перезаписывает данные.Выполнение этих рекомендаций позволит вам надежно управлять дополнительными свойствами объектов, избегая конфликтов с логикой типовых конфигураций 1С.