При переходе с платформы «1С:Предприятие 7.7» на версию 8.3 программисты часто сталкиваются с концептуальными изменениями в работе с данными. Одной из типичных задач является массовое обновление строк в табличной части документа. Например, когда необходимо во всех строках документа ОтпускТоваровВОтделение установить значение реквизита АналитикаРасходов равным значению Отделение из шапки этого же документа. Рассмотрим подробнее, почему попытка сделать это через консоль запросов обречена на провал и какие инструменты на самом деле нужно использовать.
Проанализируем ситуацию, описанную в теме. Автор пытается использовать конструкцию ВЫБРАТЬ... ИТОГИ для присваивания значений. Важно понимать: язык запросов 1С предназначен исключительно для чтения данных. В отличие от стандартного SQL, где существуют операторы UPDATE, INSERT и DELETE, встроенный язык запросов 1С реализует только операцию SELECT.
Секция ИТОГИ, которую автор пытался применить, служит для группировки данных и вычисления агрегатных функций (сумма, количество, среднее), а не для изменения состояния объектов в базе данных. Попытка обращения к Документ.ОтпускТоваровВОтделение.Отделение внутри запроса без связи с конкретной таблицей вызывает ошибку «Поле не найдено», так как платформа воспринимает это как обращение к абстрактному типу, а не к данным конкретного экземпляра документа.
Выясним, как правильно реализовать задачу на встроенном языке 1С. В восьмой версии платформы для изменения данных необходимо использовать объектную модель. Это означает, что мы должны сначала получить ссылку на документ, затем превратить её в объект, внести изменения и явно вызвать метод записи.
Рассмотрим алгоритм действий по шагам:
ПолучитьОбъект().Посмотрим на пример кода, который решает задачу:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОтпускТоваровВОтделение.Ссылка КАК Ссылка
|ИЗ
| Документ.ОтпускТоваровВОтделение КАК ОтпускТоваровВОтделение";
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Получаем объект документа для редактирования
ДокОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
// Проходим по строкам табличной части "Товары"
Для Каждого СтрокаТЧ Из ДокОбъект.Товары Цикл
// Присваиваем реквизиту ТЧ значение из шапки документа
СтрокаТЧ.АналитикаРасходов = ДокОбъект.Отделение;
КонецЦикла;
// Записываем изменения.
// Если документ должен остаться проведенным, используем РежимЗаписиДокумента.Проведение
Попытка
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
Исключение
Сообщить("Не удалось записать документ: " + ДокОбъект.Ссылка);
КонецПопытки;
КонецЦикла;
Если вы не хотите писать код, проанализируем возможности стандартных инструментов. В большинстве современных конфигураций (БП, УТ, ERP, Медицина), построенных на базе Библиотеки стандартных подсистем (БСП), есть обработка «Групповое изменение реквизитов».
Чтобы решить нашу задачу через этот инструмент, выполните следующие действия:
Документ.ОтпускТоваровВОтделение.Товары).Проанализируем технические моменты, которые критичны при работе с большим объемом документов:
1. Режим записи и проведения. Если вы просто вызываете метод Записать(), то данные в базе изменятся, но движения по регистрам (остатки, затраты) могут остаться старыми. Если АналитикаРасходов влияет на отчеты по затратам, документ обязательно нужно перепроводить, используя РежимЗаписиДокумента.Проведение. Будьте осторожны: перепроведение старых периодов может «подвинуть» границу последовательности или изменить финансовые результаты прошлых месяцев.
2. Обмен данными. При массовой корректировке часто используют свойство ОбменДанными.Загрузка = Истина. Рассмотрим, что это дает:
ПередЗаписью, ПриЗаписи, ОбработкаПроверкиЗаполнения).3. Транзакции. При обработке тысяч документов рекомендуется фиксировать транзакцию порциями (например, по 100-500 документов), чтобы избежать переполнения лога транзакций базы данных и не блокировать работу других пользователей на длительное время.
Таким образом, мы выяснили, что задача автоматического заполнения табличной части решается исключительно через программный обход коллекции строк объекта. Использование «чистых» запросов для этой цели в архитектуре «1С:Предприятие 8» невозможно по определению.