Всем доброго времени суток!
Немного предыстории. На новом месте работы возникла проблема с размножением договоров контрагентов в системе "Бухгалтерия предприятия" (ред. 3.0.134.23). Было известно только то, что договора создаются автоматически при загрузке документов из других систем с использованием внешних обработок.
На мой взгляд было 2 варианта решения задачи: 1. бегать по пользователям и выпытывать что и откуда они грузят, после чего анализировать код во всех используемых обработках; 2. что-нибудь придумать чтобы автоматизировать сбор данных для последующего анализа. Я выбрал второй путь. Логика была следующей:
- в справочник добавляем дополнительный строковый реквизит (я его назвал "CreatInfo");
- используя в расширении подписку (решил использовать подписку с составным типом источника, т.к. необходимо было организовать данный механизм для нескольких справочников), обрабатываем событие "ПередЗаписью";
- при создании нового договора, помимо записи даты и времени формирования, добавляем информацию о точке входа в процедуру.
Вся проблема заключалась в получении точки входа в процедуру, чтобы определить с какой обработки осуществляется формирование договоров. В процессе "загугливания" информации наткнулся на статью: //infostart.ru/1c/articles/1263068/. Автору большое спасибо за идею.
Т.к. явной процедуры получения данных стека нет и доступно только текстовое представление ошибки, в котором будет содержаться информация стека вызовов, сэмулировал через попытку - исключение ошибку, и в "исключении" обработал текст, получив необходимые строки.
Процедура "СправочникиПередЗаписью" вызывается из добавленной в расширение подписки на события.
Процедура СправочникиПередЗаписью(Источник, Отказ) Экспорт
ТипИсточника = ТипЗнч(Источник);
Если ТипИсточника = Тип("СправочникОбъект.ДоговорыКонтрагентов") Или
ТипИсточника = Тип("СправочникОбъект.Контрагенты") Тогда
ДобавитьИнформациюСозданияЭлемента(Источник);
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьИнформациюСозданияЭлемента(Источник)
Если Не Источник.ЭтоНовый() Тогда
Возврат;
КонецЕсли;
Свойство_CreatInfo = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "CreatInfo");
Если Не ЗначениеЗаполнено(Свойство_CreatInfo) Тогда
Возврат;
КонецЕсли;
Попытка
Ошибка = 1 / 0;
Исключение
//Отсекаем лишний текст
ПоследнееМестоВызова = СтрЗаменить(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), "Деление на 0", "");
ПоследнееМестоВызова = Сред(ПоследнееМестоВызова, Найти(ПоследнееМестоВызова, ")}:ДобавитьИнформациюСозданияЭлемента(Источник);"), СтрДлина(ПоследнееМестоВызова));
ПоследнееМестоВызова = СокрЛП(СтрЗаменить(ПоследнееМестоВызова, ")}:ДобавитьИнформациюСозданияЭлемента(Источник);", ""));
СтрокаТаблицы = Источник.ДополнительныеРеквизиты.Добавить();
СтрокаТаблицы.Свойство = Свойство_CreatInfo;
СтрокаТаблицы.Значение = "Дата создания: '" + Формат(ТекущаяДата(), "ДЛФ=DT") + "'" + Символы.ПС +
"Пользователь: '" + Пользователи.АвторизованныйПользователь() + "'" + Символы.ПС +
"Точка входа: '" + ?(ПустаяСтрока(ПоследнееМестоВызова), "Ручное формирование", ПоследнееМестоВызова) + "'";
КонецПопытки;
КонецПроцедуры
Т.о. эта небольшая доработка сэкономила кучу времени, позволив четко определить откуда приходила проблема, т.к. в элементах справочника стала отражаться информация о их создании:
Надеюсь, кому-либо пригодится. Всем успехов!