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