При работе в программе «1С:Бухгалтерия предприятия 3.0» пользователи часто сталкиваются со специфическими ошибками при попытке взаимодействия с подсистемами маркировки продукции (ГИСМ/Честный Знак). Одна из таких неприятных проблем возникает в разделе Продажи — 1С Маркировка — Уведомление о розничных возвратах. При попытке открыть список возвратов или создать документ система аварийно завершает работу, выдавая ошибку: «Метод объекта не обнаружен (получить)».
Очистка локального кэша, запуск процедуры «Тестирование и исправление» (ТИИ) базы данных, а также удаление временных файлов в каталоге пользователя в данном случае не приносят результата. Давайте подробно разберем, почему возникает этот сбой, проанализируем код платформы и рассмотрим два надежных способа устранения данной проблемы.
Для начала детально изучим стек вызова ошибки, полученный из подробного лога:
{ОбщийМодуль.ИнтеграцияГИСМКлиентСервер.Модуль(782)}: Метод объекта не обнаружен (Получить)
Значение = Настройки.Получить(ИмяКолонки);
---
Проанализируем процедуру ОтборПоЗначениюСпискаПриЗагрузкеИзНастроек в общем модуле ИнтеграцияГИСМКлиентСервер, на которую указывает стек ошибки. Вот фрагмент этого кода:
Процедура ОтборПоЗначениюСпискаПриЗагрузкеИзНастроек(Список, ИмяКолонки, Значение, Знач СтруктураБыстрогоОтбора,
Настройки, Использование = Неопределено, ВидСравнения = Неопределено) Экспорт
Если СтруктураБыстрогоОтбора = Неопределено Тогда
Значение = Настройки.Получить(ИмяКолонки);
ИспользованиеЭлементаОтбора = ?(Использование = Неопределено, ЗначениеЗаполнено(Значение), Использование);
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(Список, ИмяКолонки, Значение, ВидСравнения,,ИспользованиеЭлементаОтбора);
Else
Если Не СтруктураБыстрогоОтбора.Свойство(ИмяКолонки) Тогда
Значение = Настройки.Получить(ИмяКолонки); // Ошибка происходит здесь!
ИспользованиеЭлементаОтбора = ?(Использование = Неопределено, ЗначениеЗаполнено(Значение), Использование);
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(Список, ИмяКолонки, Значение, ВидСравнения,,ИспользованиеЭлементаОтбора);
КонецЕсли;
КонецЕсли;
Настройки.Удалить(ИмяКолонки);
КонецПроцедуры
Суть проблемы кроется в строгом ожидании определенного типа данных со стороны разработчиков конфигурации. Код написан исходя из предположения, что в параметр Настройки передается объект типа Соответствие (или ФиксированноеСоответствие). У объекта типа Соответствие действительно существует встроенный метод Получить().
Однако в процессе работы платформы, особенно после обновления конфигурации или сбоя в системных таблицах настроек пользователей, в параметр Настройки передается объект типа Структура (или ФиксированнаяСтруктура). У этих объектов метод Получить() отсутствует. Для работы со структурой разработчики платформы используют метод Свойство() или обращение через квадратные скобки (например, Настройки[ИмяКолонки]). Поскольку система пытается вызвать отсутствующий метод у структуры, выполнение кода прерывается критической ошибкой.
Почему очистка локального кэша и ТИИ не помогают? Пользовательские настройки отображения форм и списков хранятся не в локальных файлах на диске компьютера, а непосредственно внутри базы данных — в специальной таблице под управлением механизма ХранилищеСистемныхНастроек. При физическом повреждении или неактуальности кэша этих настроек в базе данных, платформа продолжает считывать некорректную структуру настроек для конкретного пользователя.
---
Поскольку проблема напрямую связана с индивидуальными сохраненными настройками конкретного пользователя для формы «Уведомления о розничных возвратах», самым быстрым и безопасным решением без программирования является полная очистка этих настроек.
Выполним очистку настроек по шагам:
---
Если вы хотите решить проблему глобально для всех пользователей и гарантировать, что ошибка больше никогда не повторится (даже если у кого-то снова повредятся системные настройки), необходимо сделать код процедуры более гибким. Для этого отлично подойдет механизм расширений конфигурации, который позволит не снимать типовую конфигурацию с поддержки.
Создадим расширение и заменим исходный код процедуры ОтборПоЗначениюСпискаПриЗагрузкеИзНастроек на универсальный вариант, который одинаково успешно работает как со Структурой, так и с Соответствием.
Рассмотрим безопасный вариант программного кода:
&Вместо("ОтборПоЗначениюСпискаПриЗагрузкеИзНастроек")
Процедура Расш_ОтборПоЗначениюСпискаПриЗагрузкеИзНастроек(Список, ИмяКолонки, Значение, Знач СтруктураБыстрогоОтбора,
Настройки, Использование = Неопределено, ВидСравнения = Неопределено)
ТипНастроек = ТипЗнч(Настройки);
Значение = Неопределено;
// Получаем значение безопасным методом в зависимости от типа коллекции
Если ТипНастроек = Тип("Структура") Или ТипНастроек = Тип("ФиксированнаяСтруктура") Тогда
Настройки.Свойство(ИмяКолонки, Значение);
ИначеЕсли ТипНастроек = Тип("Соответствие") Или ТипНастроек = Тип("ФиксированноеСоответствие") Тогда
Значение = Настройки.Получить(ИмяКолонки);
КонецЕсли;
Если СтруктураБыстрогоОтбора = Неопределено Тогда
ИспользованиеЭлементаОтбора = ?(Использование = Неопределено, ЗначениеЗаполнено(Значение), Использование);
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(Список, ИмяКолонки, Значение, ВидСравнения,,ИспользованиеЭлементаОтбора);
Иначе
Если Не СтруктураБыстрогоОтбора.Свойство(ИмяКолонки) Тогда
ИспользованиеЭлементаОтбора = ?(Использование = Неопределено, ЗначениеЗаполнено(Значение), Использование);
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(Список, ИмяКолонки, Значение, ВидСравнения,,ИспользованиеЭлементаОтбора);
КонецЕсли;
КонецЕсли;
// Безопасное удаление ключа: фиксированные структуры и соответствия вызовут ошибку при вызове Удалить()
Если ТипНастроек <> Тип("ФиксированнаяСтруктура")
И ТипНастроек <> Тип("ФиксированноеСоответствие") Тогда
Настройки.Удалить(ИмяКолонки);
КонецЕсли;
КонецПроцедуры
Важное примечание для разработчиков: Обратите особое внимание на последнюю строку исходной процедуры — Настройки.Удалить(ИмяКолонки);. Если в процедуру в качестве параметра Настройки будет передана коллекция типа ФиксированнаяСтруктура или ФиксированноеСоответствие, то попытка выполнения метода Удалить() приведет к очередному падению программы с ошибкой, так как фиксированные объекты защищены от модификации. В предложенном выше универсальном коде этот момент полностью учтен — удаление ключа производится только из изменяемых типов коллекций.
Применение любого из предложенных вариантов позволит вам успешно справиться с этой системной ошибкой и вернуть пользователям возможность полноценно работать с возвратами маркированного товара.