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