Как изменить реквизиты в табличной части документа на основании данных из шапки?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Сфера услуг, туризм и социальный сектор
← На главную

При переходе с платформы «1С:Предприятие 7.7» на версию 8.3 программисты часто сталкиваются с концептуальными изменениями в работе с данными. Одной из типичных задач является массовое обновление строк в табличной части документа. Например, когда необходимо во всех строках документа ОтпускТоваровВОтделение установить значение реквизита АналитикаРасходов равным значению Отделение из шапки этого же документа. Рассмотрим подробнее, почему попытка сделать это через консоль запросов обречена на провал и какие инструменты на самом деле нужно использовать.

Разберем причину ошибки: почему запрос не работает на изменение

Проанализируем ситуацию, описанную в теме. Автор пытается использовать конструкцию ВЫБРАТЬ... ИТОГИ для присваивания значений. Важно понимать: язык запросов 1С предназначен исключительно для чтения данных. В отличие от стандартного SQL, где существуют операторы UPDATE, INSERT и DELETE, встроенный язык запросов 1С реализует только операцию SELECT.

Секция ИТОГИ, которую автор пытался применить, служит для группировки данных и вычисления агрегатных функций (сумма, количество, среднее), а не для изменения состояния объектов в базе данных. Попытка обращения к Документ.ОтпускТоваровВОтделение.Отделение внутри запроса без связи с конкретной таблицей вызывает ошибку «Поле не найдено», так как платформа воспринимает это как обращение к абстрактному типу, а не к данным конкретного экземпляра документа.

Решение №1: Программный перебор объектов (правильный подход)

Выясним, как правильно реализовать задачу на встроенном языке 1С. В восьмой версии платформы для изменения данных необходимо использовать объектную модель. Это означает, что мы должны сначала получить ссылку на документ, затем превратить её в объект, внести изменения и явно вызвать метод записи.

Рассмотрим алгоритм действий по шагам:

  1. Создаем запрос для получения списка всех нужных документов (например, за определенный период или по конкретному складу).
  2. Обходим результат запроса в цикле.
  3. Для каждого документа получаем объект через метод ПолучитьОбъект().
  4. Запускаем цикл по строкам табличной части.
  5. Присваиваем значение и записываем объект.

Посмотрим на пример кода, который решает задачу:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ОтпускТоваровВОтделение.Ссылка КАК Ссылка
    |ИЗ
    |	Документ.ОтпускТоваровВОтделение КАК ОтпускТоваровВОтделение";

РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    // Получаем объект документа для редактирования
    ДокОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
    
    // Проходим по строкам табличной части "Товары"
    Для Каждого СтрокаТЧ Из ДокОбъект.Товары Цикл
        // Присваиваем реквизиту ТЧ значение из шапки документа
        СтрокаТЧ.АналитикаРасходов = ДокОбъект.Отделение;
    КонецЦикла;
    
    // Записываем изменения. 
    // Если документ должен остаться проведенным, используем РежимЗаписиДокумента.Проведение
    Попытка
        ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
    Исключение
        Сообщить("Не удалось записать документ: " + ДокОбъект.Ссылка);
    КонецПопытки;
КонецЦикла;

Решение №2: Использование стандартной обработки «Групповое изменение реквизитов»

Если вы не хотите писать код, проанализируем возможности стандартных инструментов. В большинстве современных конфигураций (БП, УТ, ERP, Медицина), построенных на базе Библиотеки стандартных подсистем (БСП), есть обработка «Групповое изменение реквизитов».

Чтобы решить нашу задачу через этот инструмент, выполните следующие действия:

  1. Откройте обработку (обычно находится в разделе «Администрирование» — «Обслуживание» — «Корректировка данных»).
  2. Выберите тип объекта: Документ.ОтпускТоваровВОтделение.
  3. Нажмите кнопку «Дополнительные параметры» и установите флаг «Показывать служебные реквизиты» (это позволит видеть табличные части).
  4. В списке реквизитов найдите вашу табличную часть (например, Товары).
  5. Однако, штатный функционал часто позволяет лишь установить фиксированное значение для всех строк. Если требуется логика «взять значение из шапки именно этого документа», вам может потребоваться режим «Выполнить произвольный алгоритм», который доступен в консолях инструментов разработчика (например, от ИРБИС или других авторов).

Важные нюансы при массовом изменении данных

Проанализируем технические моменты, которые критичны при работе с большим объемом документов:

1. Режим записи и проведения. Если вы просто вызываете метод Записать(), то данные в базе изменятся, но движения по регистрам (остатки, затраты) могут остаться старыми. Если АналитикаРасходов влияет на отчеты по затратам, документ обязательно нужно перепроводить, используя РежимЗаписиДокумента.Проведение. Будьте осторожны: перепроведение старых периодов может «подвинуть» границу последовательности или изменить финансовые результаты прошлых месяцев.

2. Обмен данными. При массовой корректировке часто используют свойство ОбменДанными.Загрузка = Истина. Рассмотрим, что это дает:

3. Транзакции. При обработке тысяч документов рекомендуется фиксировать транзакцию порциями (например, по 100-500 документов), чтобы избежать переполнения лога транзакций базы данных и не блокировать работу других пользователей на длительное время.

Таким образом, мы выяснили, что задача автоматического заполнения табличной части решается исключительно через программный обход коллекции строк объекта. Использование «чистых» запросов для этой цели в архитектуре «1С:Предприятие 8» невозможно по определению.

← На главную