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