При разработке и сопровождении сложных конфигураций, таких как 1С:Розница, часто возникает проблема «фантомных» дублей в табличных частях документов. Когда обмен данными с внешними системами (например, Bitrix) исключен, а регламентные задания и обработки работают параллельно, поиск конкретного места возникновения ошибки становится критической задачей. Рассмотрим, как поэтапно локализовать источник проблемы.
Если нам необходимо «поймать за руку» код, который добавляет лишнюю строку, мы можем внедрить проверку непосредственно в событие ПередЗаписью объекта. Суть метода заключается в принудительном вызове исключения при обнаружении условия дублирования, что позволяет платформе сформировать отчет о текущем стеке вызовов.
Разберем, как это реализовать на практике:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если Услуги.Количество() > 1 Тогда
Попытка
ВызватьИсключение "Обнаружено дублирование услуг!";
Исключение
СтекВызовов = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации("ОтладкаДублей", УровеньЖурналаРегистрации.Ошибка, , Ссылка, СтекВызовов);
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Важно помнить, что полнота информации в ИнформацияОбОшибке() сильно зависит от версии платформы. Начиная с версии 8.3.19 и выше, платформа предоставляет значительно более детальную информацию о цепочке вызовов.
Технологический журнал является самым надежным инструментом, так как он фиксирует события на уровне СУБД, минуя любые ограничения логики кода 1С. Для поиска «виновника» нам потребуется настроить фильтр на событие DBMSSQL (или DBPOSTGRS).
logcfg.xml на сервере 1С.DBMSSQL для конкретной таблицы или имени объекта.StackTrace в настройки события, чтобы при каждом обращении к базе данных сервер записывал текущий стек вызовов.Пример настройки фрагмента logcfg.xml:
<event-groups>
<event-group name="DataChanges">
<event>DBMSSQL</event>
<property name="SQL"/>
<property name="StackTrace"/>
</event-group>
</event-groups>
<logs>
<log location="..." history="24">
<event-group name="DataChanges"/>
<filter>
<event>DBMSSQL</event>
<sql>LIKE '%ИмяТаблицы%'</sql>
</filter>
</log>
</logs>
Этот метод позволит вам увидеть не только имя пользователя, но и точный стек вызовов (имя метода, модуль, номер строки), который отправил команду INSERT или UPDATE в базу данных.
В библиотеке БСП существует механизм ДополнительныеСвойства. Мы можем использовать его для маркировки данных. Если у вас есть подозрения на конкретные регламентные задания или внешние обработки, попробуйте проставить метку в начале их работы.
В коде обработки добавьте:
Объект.ДополнительныеСвойства.Вставить("ИсточникОбработки", "ИмяМоейОбработки");
// Далее код записи объекта
Объект.Записать();
Затем в ПередЗаписью вы сможете легко прочитать это свойство: Объект.ДополнительныеСвойства.Получить("ИсточникОбработки"). Если метка найдена — вы нашли источник дублей.
Объект.Ссылка = [СсылкаНаПроблемныйЗаказ] позволит остановиться точно в момент изменения объекта и просмотреть весь стек через окно «Стек вызовов».Комбинируя эти подходы, вы сможете с высокой точностью определить, какая часть системы создает избыточные записи, и оперативно устранить ошибку.