Рассмотрим весьма распространенную ситуацию при разработке интеграций с внешними CRM-системами на базе 1С:Предприятие 8.3 (на примере конфигурации «Управление торговлей 11.4»). Мы собираем данные из CRM, находим или создаем контрагента по ИНН и программно подставляем его в существующий заказ. В отладчике мы четко видим, что реквизит заполнен, объект документа успешно записывается. Но как только мы открываем этот заказ в интерактивном режиме (пользовательском интерфейсе), мы видим, что поле «Контрагент» пустое. Проанализируем, почему так происходит и в какую сторону копать для успешного решения проблемы.
Давайте посмотрим на исходный код функции, которая осуществляет поиск и привязку контрагента:
Процедура СоздатьЗаказ(ТаблицаСделок, Настройки,WinHttp)
Для Каждого Сделка Из ТаблицаСделок Цикл
// ... инициализация ...
Контрагент = СоздатьИлиНайтиКонтрагентаПартнера(ДанныеКомпании);
Если Сделка.СтатусЗаказа = "На согласовании" Тогда
Заказ = Документы.ЗаказКлиента.НайтиПоРеквизиту("ЭС_ИдАМО",Сделка.ИдСделки);
Если ЗначениеЗаполнено(Заказ) Тогда
Заказ = Заказ.Ссылка.ПолучитьОбъект();
Заказ.Контрагент = Контрагент;
Заказ.Партнер = Контрагент.Партнер;
Заказ.Договор = НайтиСоздатьДоговорКонтрагента(Контрагент,Настройки.Организация);
Заказ.Записать();
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция СоздатьИлиНайтиКонтрагентаПартнера (ДанныеКомпании)
Для Каждого Данные Из ДанныеКомпании Цикл
Для Каждого Компания Из Данные.ДанныеКомпании Цикл
Контрагент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",Компания.ИНН);
Если ЗначениеЗаполнено(Контрагент) Тогда
Контрагент = Контрагент.Ссылка.ПолучитьОбъект();
Контрагент.ЭС_ИдАМО = Компания.ИдКомпании;
Контрагент.Записать();
Контрагент = Контрагент.Ссылка;
Возврат Контрагент;
Иначе
Партнер = Справочники.Партнеры.СоздатьЭлемент();
Партнер.БизнесРегион = Компания. // <-- Синтаксическая ошибка и обрыв
Контрагент = Справочники.Контрагенты.СоздатьЭлемент();
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецФункции
Разберем по шагам, какие проблемы скрываются в этом коде, из-за которых данные могут теряться.
В функции СоздатьИлиНайтиКонтрагентаПартнера мы видим блок Иначе, который должен отрабатывать, если контрагент не найден. В этом блоке элементы справочников инициализируются через Справочники.Партнеры.СоздатьЭлемент(), но далее код обрывается на незавершенной строке (Партнер.БизнесРегион = Компания.).
Более того, в этой ветке отсутствуют вызовы метода Записать() для созданных объектов и отсутствует оператор Возврат. Это означает, что если контрагент новый, функция отработает некорректно и вернет Неопределено. В результате в документе реквизитам будет присвоено пустое значение.
Обратим внимание на работу с типами данных. В реквизиты документа (такие как Заказ.Контрагент) необходимо передавать ссылку на элемент справочника, а не сам объект. В исправленном варианте кода автор делает Контрагент = Контрагент.Ссылка; Возврат Контрагент;. Всегда проверяйте, что функции поиска и создания возвращают именно тип СправочникСсылка, иначе при записи документа возникнет ошибка несоответствия типов, или поле запишется некорректно.
В конфигурации 1С:УТ 11 используется раздельный учет: управленческий (справочник Партнеры) и регламентированный (справочник Контрагенты). Это накладывает строгие ограничения на логику заполнения документов.
В строке Заказ.Партнер = Контрагент.Партнер; кроется большая опасность. Если в вашей базе включена независимая связь партнеров и контрагентов, реквизит Партнер в самой карточке контрагента может быть попросту не заполнен. Если Контрагент.Партнер пуст, то и Заказ.Партнер обнуляется. При открытии формы заказа, где первичным клиентом выступает именно Партнер, пустой партнер приведет к тому, что форма скроет или очистит поле "Контрагент".
Даже если программно документ записан идеально, УТ 11 имеет сложную внутреннюю логику. Когда пользователь интерактивно открывает Заказ клиента, срабатывают стандартные обработчики, в частности ПриЧтенииНаСервере и ПриСозданииНаСервере. В них платформа прогоняет загруженные данные через механизмы проверки консистентности.
Выясним причину очистки: в УТ 11 огромную роль играет реквизит Соглашение. Связка реквизитов должна быть строго выверена: Организация — Соглашение — Партнер — Контрагент — Договор.
Соглашение в заказе настроено на конкретного партнера, а вы программно подставили другого контрагента/партнера, форма обнаружит противоречие.Контрагент принудительно очищается прямо при открытии документа.Договоре.Чтобы избежать подобных проблем с "исчезающими" реквизитами, проанализируем ситуацию и выполним следующие шаги:
Иначе полностью дописана, новые партнер и контрагент заполняются обязательными реквизитами, успешно сохраняются через Записать() и функция гарантированно возвращает ссылку (Возврат Контрагент.Ссылка;).Заказ.Партнер = Контрагент.Партнер;, добавьте проверку ЗначениеЗаполнено(Контрагент.Партнер). Если партнер пуст, его нужно либо найти по ИНН/наименованию отдельно, либо создать.Соблюдение этих правил позволит корректно интегрировать данные CRM в 1С:УТ 11, избегая неожиданного поведения управляемых форм при чтении документов.