При разработке обработок для массового изменения данных в конфигурации «1С:Управление торговлей 11» (УТ 11) программисты часто сталкиваются с ситуацией, когда код, успешно работающий в «1С:Бухгалтерии», выдает ошибки или не приносит желаемого результата в интерфейсе пользователя. Одной из таких проблем является изменение наименования контрагента. Разберем подробно, почему возникает ошибка «Поле объекта не доступно для записи» и как правильно синхронизировать данные между связанными справочниками.
Рассмотрим типичную ситуацию. Программист пытается перенести значение из одного реквизита в другой в цикле обхода справочника. Первоначальный ошибочный код выглядел так:
Выборка = Справочники.Контрагенты.Выбрать();
Пока Выборка.Следующий() Цикл
ВыборкаКонтрагенты = Выборка.ПолучитьОбъект();
Выборка.Наименование = Выборка.НаименованиеПолное; // ОШИБКА ЗДЕСЬ
ВыборкаКонтрагенты.Записать();
КонецЦикла;
Проанализируем причину сбоя. В языке 1С:Предприятие переменная Выборка является объектом типа СправочникВыборка. Этот объект предназначен только для чтения данных и навигации по ним. Попытка присвоить значение напрямую свойству выборки Выборка.Наименование всегда приводит к ошибке «Поле объекта не доступно для записи».
Чтобы внести изменения, необходимо работать с объектом типа СправочникОбъект, который мы получаем методом ПолучитьОбъект(). Правильный алгоритм требует обращения именно к переменной, содержащей объект:
Выборка = Справочники.Контрагенты.Выбрать();
Пока Выборка.Следующий() Цикл
ВыборкаКонтрагенты = Выборка.ПолучитьОбъект();
ВыборкаКонтрагенты.Наименование = ВыборкаКонтрагенты.НаименованиеПолное;
ВыборкаКонтрагенты.Записать();
КонецЦикла;
Теперь код технически исправен, однако для УТ 11 этого недостаточно.
Выясним причину, по которой простого изменения справочника Контрагенты мало. В отличие от упрощенных конфигураций, УТ 11 разделяет понятия управленческого учета (справочник Партнеры) и регламентированного учета (справочник Контрагенты).
Даже если в настройках программы отключена опция «Независимо вести партнеров и контрагентов», система все равно создает две записи. Пользователи в списках документов, в подборах и в CRM-системе видят именно справочник Партнеры. Если мы изменим наименование только у контрагента, пользователи не увидят изменений в интерфейсе, так как в формах будет продолжать отображаться старое наименование из связанного партнера.
Проанализируем ситуацию: для корректного отображения данных необходимо обновлять оба справочника. При этом рекомендуется сначала изменять Партнера, так как он часто является «ведущим» объектом в этой паре.
Метод Выбрать() удобен для простых задач, но при работе с большими базами данных он неэффективен. Рассмотрим более профессиональный подход с использованием объекта Запрос. Это позволит нам отобрать только нужные записи и не нагружать оперативную память сервера лишними данными.
Разберем по шагам правильную структуру обработки:
Контрагенты.Партнер).
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК КонтрагентСсылка,
| Контрагенты.Партнер КАК ПартнерСсылка,
| Контрагенты.НаименованиеПолное КАК НовоеНаименование
|ИЗ
| Справочник.Контрагенты КАК Контрагенты";
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Обновляем Контрагента
ОбъектКонтрагент = ВыборкаДетальныеЗаписи.КонтрагентСсылка.ПолучитьОбъект();
ОбъектКонтрагент.Наименование = ВыборкаДетальныеЗаписи.НовоеНаименование;
// Обновляем Партнера, если он заполнен
Если ЗначениеЗаполнено(ВыборкаДетальныеЗаписи.ПартнерСсылка) Тогда
ОбъектПартнер = ВыборкаДетальныеЗаписи.ПартнерСсылка.ПолучитьОбъект();
ОбъектПартнер.Наименование = ВыборкаДетальныеЗаписи.НовоеНаименование;
// Используем режим загрузки для скорости и обхода проверок
ОбъектПартнер.ОбменДанными.Загрузка = Истина;
ОбъектПартнер.Записать();
КонецЕсли;
ОбъектКонтрагент.ОбменДанными.Загрузка = Истина;
ОбъектКонтрагент.Записать();
КонецЦикла;
Посмотрим на важную деталь в коде выше: ОбменДанными.Загрузка = Истина. При массовом программном изменении данных это критически важный параметр. Разберем подробнее, что он дает:
Важно: Используйте этот режим только тогда, когда вы уверены в корректности записываемых данных, так как типовые контроли бизнес-логики будут проигнорированы.
После выполнения программного изменения наименований следует обратить внимание на два момента:
1. Обмен с Бухгалтерией: Помните, что в обмене данными (синхронизации) между УТ 11 и БП 3.0 участвует именно объект Контрагент. Поиск обычно идет по внутреннему идентификатору (GUID). Ваши изменения успешно улетят в бухгалтерию при следующем сеансе обмена. Однако, если в базе «1С:Бухгалтерия» настроен приоритет данных или установлена дата запрета редактирования, изменения могут не примениться или вернуться обратно при двустороннем обмене.
2. Полнотекстовый поиск: Проанализируем ситуацию, когда данные изменены, но при поиске в строке «Поиск» (Ctrl+Alt+F) программа выдает старые результаты. Это происходит из-за того, что индекс полнотекстового поиска обновляется регламентным заданием не мгновенно. После массовых правок рекомендуется зайти в раздел Администрирование — Обслуживание — Полнотекстовый поиск и запустить ручное обновление индекса.
Таким образом, для успешного изменения наименований в УТ 11 мы должны не только исправить синтаксическую ошибку в обращении к объекту, но и обеспечить консистентность данных между справочниками Партнеры и Контрагенты, используя оптимальные методы работы с платформой 1С.