Довольно часто в практике программиста 1С возникает задача массовой или точечной корректировки данных. Рассмотрим интересную ситуацию: необходимо программно изменить вид соглашения с клиентом с «индивидуального» на «типовое» в конфигурациях 1С:Управление торговлей 11.5, 1С:Комплексная автоматизация 2.5 или 1С:ERP 2.5. На первый взгляд задача кажется тривиальной, но при ее решении можно столкнуться с неочевидными архитектурными особенностями системы.
Проанализируем типичную ошибку, с которой сталкиваются разработчики, и разберем по шагам правильный алгоритм преобразования карточки соглашения.
Посмотрим на пример кода, который часто пытаются использовать для решения данной задачи. Логика разработчика понятна: найти реквизиты, отвечающие за вид соглашения, установить им значение «Типовое», включить загрузку без проверок и сохранить объект.
Объект = СсылкаНаСоглашение.ПолучитьОбъект();
Объект.ОбменДанными.Загрузка = Истина;
Объект.ВидСоглашенияДляОграниченияЧтения = Перечисления.ВидыСоглашенийСКлиентамиДляОграниченияЧтения.Типовые;
Объект.ВидСоглашенияДляОграниченияИзменения = Перечисления.ВидыСоглашенийСКлиентамиДляОграниченияИзменения.Типовые;
Объект.Записать();
Выясним причину, почему этот код не дает нужного результата. Разработчик попытался изменить реквизиты ВидСоглашенияДляОграниченияЧтения и ВидСоглашенияДляОграниченияИзменения. Однако эти поля в справочнике СоглашенияСКлиентами являются сугубо служебными. Они используются исключительно подсистемой прав доступа (RLS) для разграничения видимости на уровне записей. Архитектура программы не опирается на них для определения фактического статуса и логики работы самого соглашения. Интерфейс и бизнес-логика конфигурации все равно будут видеть объект как индивидуальное соглашение.
Чтобы индивидуальное соглашение стало полноценным типовым, нам необходимо учесть структуру метаданных справочника и очистить все связи, которые «привязывают» соглашение к конкретному клиенту. Разберем необходимые действия по шагам.
Типовое. При программном изменении именно его необходимо установить в значение Истина.Партнер и Контрагент. Если форма 1С при открытии увидит заполненного партнера, она автоматически переключится в режим работы с индивидуальным соглашением.ТиповоеСоглашение. Архитектура 1С не предполагает, что одно типовое соглашение подчинено другому типовому таким образом. Этот реквизит необходимо обнулить.СегментПартнеров (например, указать сегмент «Оптовые клиенты» или «Дилеры»).Соберем все описанные правила в единый скрипт. Рассмотрим подробнее, как должен выглядеть рабочий код для корректной трансформации:
Объект = СсылкаНаИндивидуальноеСоглашение.ПолучитьОбъект();
// Включаем загрузку, чтобы избежать лишних проверок при записи
Объект.ОбменДанными.Загрузка = Истина;
// 1. Устанавливаем признак типового соглашения
Объект.Типовое = Истина;
// 2. Корректируем служебные реквизиты RLS (для целостности данных)
Объект.ВидСоглашенияДляОграниченияЧтения = Перечисления.ВидыСоглашенийСКлиентамиДляОграниченияЧтения.Типовые;
Объект.ВидСоглашенияДляОграниченияИзменения = Перечисления.ВидыСоглашенийСКлиентамиДляОграниченияИзменения.Типовые;
// 3. Отвязываем соглашение от конкретного клиента
Объект.Партнер = Справочники.Партнеры.ПустаяСсылка();
Объект.Контрагент = Справочники.Контрагенты.ПустаяСсылка();
// 4. Очищаем ссылку на базовое типовое соглашение
Объект.ТиповоеСоглашение = Справочники.СоглашенияСКлиентами.ПустаяСсылка();
// 5. Опционально: назначаем сегмент партнеров
Объект.СегментПартнеров = Справочники.СегментыПартнеров.НайтиПоНаименованию("Оптовые клиенты");
// Записываем изменения
Объект.Записать();
Важное замечание: При массовой обработке данных всегда тестируйте подобный код на копии базы. Использование свойства ОбменДанными.Загрузка отключает многие проверки модуля объекта, что позволяет быстро записать элемент, но возлагает всю ответственность за ссылочную целостность на плечи программиста.
Если задача носит разовый характер, проще всего поступить так, как было сделано в итоге: пометить текущее индивидуальное соглашение на удаление и создать новое типовое соглашение руками пользователя.
Для пользователей, которым регулярно требуется менять вид соглашения, существуют готовые решения. В сообществе программистов 1С разработаны расширения конфигурации, которые добавляют в подменю «Еще» карточки соглашения кнопку «Преобразовать соглашение в типовое / индивидуальное». Такие расширения под капотом используют ровно тот же алгоритм, который мы рассмотрели выше: они автоматически подменяют служебные поля, очищают контрагентов и перезаписывают объект, избавляя от необходимости писать скрипты и внешние обработки вручную.