Несколько часов на поиски проблемы, или почему нужно знать базуПотребовалось реализовать задачу связанную с редактированием одного объекта справочника внутри карточки другого справочника. Предыстория для понимания, в конфигурации есть справочник
«Внутренние документы», в котором хранятся разные виды документов: служебные записки, приказы, заявки, договоры и так далее. Для договоров понадобилось добавить большой набор реквизитов пояснительной записки.
Добавлять все эти поля непосредственно во «Внутренние документы» не хотелось: для большинства видов документов они никогда не используются.
Поэтому пояснительную записку решил хранить в отдельном справочнике, а во внутреннем документе — только ссылку на неё. При этом для пользователя всё должно выглядеть максимально прозрачно: открывается карточка внутреннего документа и реквизиты пояснительной записки заполняются прямо в этой карточке. У пользователя должно складываться ощущение, что работа происходит только с карточкой внутреннего документа.
В справочник ВнутренниеДокументы добавляем реквизит:
ПояснительнаяЗаписка, тип СправочникСсылка.ПояснительныеЗаписки
На форму внутреннего документа добавляем реквизит формы:
ПояснительнаяЗапискаОбъект, тип СправочникОбъект.ПояснительныеЗаписки
После этого на форме внутреннего документа можно размещать его поля:
ПояснительнаяЗапискаОбъект.Обоснование и т д.
При создании нового элемента внутреннего документа создаём объект пояснительной записки и заранее формируем для него ссылку:
ПояснительнаяЗапискаОбъект =
Справочники.ПояснительныеЗаписки.СоздатьЭлемент();
ПояснительнаяЗапискаСсылка =
Справочники.ПояснительныеЗаписки.ПолучитьСсылку(
Новый УникальныйИдентификатор());
ПояснительнаяЗапискаОбъект.УстановитьСсылкуНового(
ПояснительнаяЗапискаСсылка);
Объект.ПояснительнаяЗаписка =
ПояснительнаяЗапискаСсылка;
ЗначениеВРеквизитФормы(
ПояснительнаяЗапискаОбъект,
"ПояснительнаяЗапискаОбъект");
Таким образом, во внутреннем документе будет хранится ссылка на будущий элемент справочника, хотя сама пояснительная записка ещё не записана. Перед записью внутреннего документа преобразуем реквизит формы обратно в прикладной объект:
ПояснительнаяЗапискаОбъект =
РеквизитФормыВЗначение(
"ПояснительнаяЗапискаОбъект",
Тип("СправочникОбъект.ПояснительныеЗаписки"));
Затем передаём полученный объект в ПриЗаписиНаСервере через параметры записи:
ПараметрыЗаписи.Вставить(
"ПояснительнаяЗапискаОбъект",
ПояснительнаяЗапискаОбъект);
А в ПриЗаписиНаСервере записываем пояснительную записку:
ПояснительнаяЗапискаОбъект.Записать();
ЗначениеВРеквизитФормы(
ПояснительнаяЗапискаОбъект,
"ПояснительнаяЗапискаОбъект");
Обратное преобразование после записи нужно, чтобы пользователь мог продолжить редактирование и повторно записать карточку.
Далее как раз возникает проблема. После записи оказывается, что в реквизите "Пояснительная записка" внутреннего документа лежит битая ссылка. При этом элемент справочника успешно записан, но ссылка у него почему-то оказалась другая, а не та которую указали в методе:
ПояснительнаяЗапискаОбъект.УстановитьСсылкуНового(ПояснительнаяЗапискаСсылка);
Почему же так произошло ?
Все дело в одной особенности работы платформы, а именно:
При переносе объекта в данные формы платформой, или при вызове методов ЗначениеВДанныеФормы(), ЗначениеВРеквизитФормы(), переносятся только данные объекта. Внутренние состояние объекта в данные формы не переносится. Например, значение ссылки нового, которая установлена в объект методом УстановитьСсылкуНового(), будет утеряна в процессе преобразования объекта в данные формы и обратно.
Упрощённо ПередЗаписьюНаСервере должен выглядеть так:
&НаСервере
Процедура ПередЗаписьюНаСервере(
Отказ,
ТекущийОбъект,
ПараметрыЗаписи)
ПояснительнаяЗапискаОбъект =
РеквизитФормыВЗначение(
"ПояснительнаяЗапискаОбъект",
Тип("СправочникОбъект.ПояснительныеЗаписки"));
Если ПояснительнаяЗапискаОбъект.ЭтоНовый() Тогда
ПояснительнаяЗапискаОбъект.УстановитьСсылкуНового(
ТекущийОбъект.ПояснительнаяЗаписка);
КонецЕсли;
ПараметрыЗаписи.Вставить(
"ПояснительнаяЗапискаОбъект",
ПояснительнаяЗапискаОбъект);
КонецПроцедуры
Такие особенности платформы нередко встречаются в процессе разработки. А с какими особенностями при разработке сталкивались вы? Поделитесь своими примерами в комментариях.