При регулярном обновлении типовых конфигураций «1С:Предприятие» пользователи и администраторы часто сталкиваются с рассинхронизацией логики конфигураций и правил обмена данными. Одной из наиболее распространенных ошибок при обмене между конфигурациями «1С:Управление нашей фирмой» (УНФ) и «1С:Бухгалтерия предприятия» (БП) является сбой при обработке полученных счетов-фактур.
В этой статье мы подробно разберем, почему возникает ошибка Метод объекта не обнаружен (Выгрузить) в модуле менеджера документа СчетФактураПолученный, проанализируем внутренние механизмы платформы и предложим три практических способа решения этой проблемы.
Рассмотрим детально текст ошибки, который регистрируется в журнале регистрации базы-приемника (БП) при выполнении синхронизации:
{ОбщийМодуль.ОбменДаннымиСервер.Модуль(4462)}: {Обработка.КонвертацияОбъектовИнформационныхБаз.МодульОбъекта(4328)}:
Ошибка в обработчике события ПослеЗагрузкиОбъекта
ИмяПКО = СчетФактураПолученный
ТипОбъекта = Счет-фактура полученный
Объект = Счет-фактура полученный ТСАС-000057 от 01.04.2018 12:00:01
Обработчик = ПослеЗагрузкиОбъекта
ОписаниеОшибки = Метод объекта не обнаружен (Выгрузить)
ПозицияМодуля = Документ.СчетФактураПолученный.МодульМенеджера(53)
Выясним причину этой ошибки на уровне программного кода. Ошибка происходит в модуле менеджера документа СчетФактураПолученный конфигурации «1С:Бухгалтерия предприятия» в функции ПолучитьКодВидаОперации(Параметры). Обратим внимание на строку №53 в этой функции:
Функция ПолучитьКодВидаОперации(Параметры) Экспорт
КодВидаОперации = "";
ПараметрыОпределенияКВО = НовыйПараметрыОпределенияКВО;
ЗаполнитьЗначенияСвойств(ПараметрыОпределенияКВО, Параметры);
Если НЕ УчетНДСПереопределяемый.ИспользуетсяПостановлениеНДС1137(ПараметрыОпределенияКВО.Дата) Тогда
Возврат КодВидаОперации;
КонецЕсли;
// Строка 53, вызывающая критическую ошибку:
ДокументыОснования = Параметры.ДокументыОснования.Выгрузить(,"ДокументОснование");
...
КонецФункции
Данная строка ожидает, что в свойстве ДокументыОснования переданного параметра находится объект, обладающий методом Выгрузить(). В контексте платформы «1С:Предприятие 8» таким методом обладают типы ТабличнаяЧасть и ТаблицаЗначений.
Однако при использовании устаревших или кастомизированных (нетиповых) правил обмена в обработчике события ПослеЗагрузкиОбъекта ПКО СчетФактураПолученный выполняется следующий код инициализации параметров:
Если РежимЗагрузкиДанныхВИнформационнуюБазу Тогда
Если НЕ ЗначениеЗаполнено(Объект.Организация) Тогда
Объект.Организация = Параметры.ОсновнаяОрганизация;
КонецЕсли;
Объект.КодСпособаПолучения = 1;
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("Дата", Объект.Дата);
СтруктураПараметров.Вставить("ВидСчетаФактуры", Объект.ВидСчетаФактуры);
СтруктураПараметров.Вставить("Исправление", Объект.Исправление);
СтруктураПараметров.Вставить("ВидДоговора", ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Объект.ДоговорКонтрагента, "ВидДоговора"));
СтруктураПараметров.Вставить("СчетФактураБезНДС", Объект.СчетФактураБезНДС);
СтруктураПараметров.Вставить("КодВидаОперации", Объект.КодВидаОперации);
СтруктураПараметров.Вставить("КодВидаОперацииОснования", Неопределено);
// Формирование проблемного параметра:
СтруктураПараметров.Вставить("ДокументыОснования", Объект.ДокументыОснования.Выгрузить(,"ДокументОснование"));
Объект.КодВидаОперации = Документы.СчетФактураПолученный.ПолучитьКодВидаОперации(СтруктураПараметров);
Объект.КодСпособаПолучения = 1;
Выполнить(Алгоритмы.ОбработатьДоговорКонтрагента);
КонецЕсли;
Проанализируем эту ситуацию подробнее. Метод Объект.ДокументыОснования.Выгрузить(,"ДокументОснование") выгружает колонку табличной части во временную Таблицу значений. При сериализации структуры параметров для выполнения обмена (особенно в клиент-серверном варианте или через веб-сервисы) эта таблица преобразуется платформой в тип Массив (массив структур или соответствий).
Когда этот десериализованный массив передается в функцию ПолучитьКодВидаОперации, система пытается выполнить метод Выгрузить() у объекта типа Массив. Но у массива такого метода нет! Это и приводит к аварийному завершению транзакции обмена.
В актуальных релизах конфигурации 1С разработчики изменили этот подход. Теперь в функцию ПолучитьКодВидаОперации передается непосредственно сам загружаемый ДокументОбъект, чья табличная часть ДокументыОснования гарантированно сохраняет свой тип и имеет метод Выгрузить().
Если в вашей системе используются измененные или нетиповые правила синхронизации, их необходимо скорректировать вручную. Разберем этот процесс по шагам.
CorrespondentExchangeRules.xml).CorrespondentExchangeRules.xml в любом текстовом редакторе (например, Notepad++).ПослеЗагрузкиОбъекта.Было (устаревший код):
Если РежимЗагрузкиДанныхВИнформационнуюБазу Тогда
Если НЕ ЗначениеЗаполнено(Объект.Организация) Тогда
Объект.Организация = Параметры.ОсновнаяОрганизация;
КонецЕсли;
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("Дата", Объект.Дата);
СтруктураПараметров.Вставить("ВидСчетаФактуры", Объект.ВидСчетаФактуры);
СтруктураПараметров.Вставить("Исправление", Объект.Исправление);
СтруктураПараметров.Вставить("ВидДоговора", ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Объект.ДоговорКонтрагента, "ВидДоговора"));
СтруктураПараметров.Вставить("СчетФактураБезНДС", Объект.СчетФактураБезНДС);
СтруктураПараметров.Вставить("КодВидаОперации", Объект.КодВидаОперации);
СтруктураПараметров.Вставить("КодВидаОперацииОснования", Неопределено);
СтруктураПараметров.Вставить("ДокументыОснования", Объект.ДокументыОснования.Выгрузить(,"ДокументОснование"));
Объект.КодВидаОперации = Документы.СчетФактураПолученный.ПолучитьКодВидаОперации(СтруктураПараметров);
Объект.КодСпособаПолучения = 1;
Выполнить(Алгоритмы.ОбработатьДоговорКонтрагента);
КонецЕсли;
Стало (актуальный исправленный код):
Попытка
Если РежимЗагрузкиДанныхВИнформационнуюБазу Тогда
Если НЕ ЗначениеЗаполнено(Объект.Организация) Тогда
Объект.Организация = Параметры.ОсновнаяОрганизация;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(Объект.КодВидаОперации) Тогда
Объект.КодВидаОперации = Документы.СчетФактураПолученный.ПолучитьКодВидаОперации(Объект);
Если НЕ ЗначениеЗаполнено(Объект.КодВидаОперации) Тогда
Объект.КодВидаОперации = "01";
КонецЕсли;
КонецЕсли;
Объект.КодСпособаПолучения = 1;
Выполнить(Алгоритмы.ОбработатьДоговорКонтрагента);
КонецЕсли;
Исключение
// Запись ошибки в журнал регистрации при необходимости
КонецПопытки;
CorrespondentExchangeRules.xml, запакуйте его обратно в ZIP-архив.Важно: Обратите внимание, что аналогичную правку кода может потребоваться выполнить и для ПКО СчетФактураВыданный, если аналогичная ошибка зафиксирована для выданных счетов-фактур.
Если вы не хотите вносить изменения в xml-файлы правил конвертации или используете закрытые нередактируемые правила, проблему несоответствия типов данных можно решить на стороне базы-приемника (БП) с помощью механизма расширений.
Разберем, как написать перехватчик вызова проблемного метода. Создадим расширение конфигурации в 1С:Бухгалтерии и добавим в него модуль менеджера документа СчетФактураПолученный с методом-перехватчиком:
&Вместо("ПолучитьКодВидаОперации")
Функция Ипс_ПолучитьКодВидаОперации(Параметры)
// Проверим тип переданного параметра
Если ТипЗнч(Параметры) = Тип("Структура") И Параметры.Свойство("ДокументыОснования") Тогда
ТекущийТипКоллекции = ТипЗнч(Параметры.ДокументыОснования);
// Если пришел Массив или некорректная ТаблицаЗначений, у которых нет метода Выгрузить
Если ТекущийТипКоллекции = Тип("Массив") Или ТекущийТипКоллекции = Тип("ТаблицаЗначений") Тогда
// Сформируем корректную ТаблицуЗначений
НоваяТЗ = Новый ТаблицаЗначений;
НоваяТЗ.Колонки.Добавить("ДокументОснование");
Для Каждого СтрокаКоллекции Из Параметры.ДокументыОснования Цикл
НоваяСтрока = НоваяТЗ.Добавить();
Если ТипЗнч(СтрокаКоллекции) = Тип("Структура") Тогда
НоваяСтрока.ДокументОснование = СтрокаКоллекции.ДокументОснование;
Иначе
// Если передан массив ссылок напрямую
НоваяСтрока.ДокументОснование = СтрокаКоллекции;
EndIf;
КонецЦикла;
// Подменяем структуру параметров на ту, которую ожидает типовой код
Параметры.Вставить("ДокументыОснования", НоваяТЗ);
КонецЕсли;
КонецЕсли;
// Вызываем оригинальный метод БП, который теперь отработает без ошибок
Возврат ПродолжитьВызов(Параметры);
КонецФункции
Такой подход гарантирует работоспособность синхронизации даже при использовании устаревших правил обмена и защитит базу от сбоев при последующих обновлениях.
Если в вашей системе используются исключительно типовые механизмы обмена, выполните следующие действия: