Как правильно формировать движения документа в 1С с помощью запроса?

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

При разработке механизмов проведения документов в 1С часто возникает вопрос: стоит ли использовать запросы для получения данных табличных частей или обращаться напрямую к объекту? Хотя данные документа доступны в контексте процедуры ОбработкаПроведения, использование запросов является профессиональным стандартом, позволяющим оптимизировать процесс и упростить работу со сложными данными. Рассмотрим подробнее, как это реализовать правильно.

Основные принципы формирования движений через запрос

Для того чтобы система работала корректно и эффективно, необходимо придерживаться нескольких правил при написании кода:

  1. Ограничение по ссылке: Никогда не делайте запрос к табличным частям без фильтрации по Ссылка. Иначе запрос выберет данные всех документов в системе, что приведет к дублированию движений и серьезным ошибкам в учете.
  2. Пакетный подход: В сложных конфигурациях принято собирать данные одним большим запросом, объединяя информацию из документа и регистров, чтобы избежать множественных обращений к базе данных внутри транзакции.
  3. Обход результата: Использование цикла Пока Выборка.Следующий() Цикл является единственно верным способом обработки данных запроса для создания записей в регистрах.

Разберем по шагам создание процедуры проведения

Представим, что мы формируем движения по регистру накопления на основе данных табличной части Товары. Рассмотрим оптимальный алгоритм действий:

Во-первых, определим текст запроса. Важно выбрать только те поля, которые действительно потребуются для заполнения движений. Всегда используйте параметр для фильтрации по текущему документу.


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ТЧ.Номенклатура КАК Номенклатура,
    |    ТЧ.Количество КАК Количество,
    |    ТЧ.Цена КАК Цена,
    |    ТЧ.НаценкаВРознице КАК Наценка,
    |    ТЧ.Ссылка.Склад КАК Склад
    |ИЗ
    |    Документ.ПриходныйОрдер.Товары КАК ТЧ
    |ГДЕ
    |    ТЧ.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатЗапроса = Запрос.Выполнить();

Как правильно организовать цикл для формирования движений

После получения результата запроса нам необходимо создать выборку и пройтись по каждой строке. Важно не забыть установить свойство Записывать в значение Истина для набора записей регистра.

Рассмотрим пример реализации цикла:


// Включаем автоматическую запись движений
Движения.СебестоимостьТовара.Записывать = Истина;

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

Пока Выборка.Следующий() Цикл
    // Добавляем новую запись в регистр
    Движение = Движения.СебестоимостьТовара.Добавить();
    
    // Заполняем поля движения
    Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
    Движение.Период = Дата;
    Движение.Склад = Выборка.Склад;
    Движение.Номенклатура = Выборка.Номенклатура;
    Движение.Количество = Выборка.Количество;
    
    // Вычисляем значение на основе данных
    Движение.Себестоимость = Выборка.Цена * 100 / Выборка.Наценка;
КонецЦикла;

Важные рекомендации по оптимизации

Проанализируем распространенные ошибки. Метод ЗаполнитьЗначенияСвойств крайне удобен, однако его следует применять с осторожностью. Он копирует значения между объектами только тогда, когда имена свойств (реквизитов) в источнике и приемнике в точности совпадают. Если структура данных в запросе отличается от структуры регистра, лучше заполнять поля явно, как показано в примере выше.

Также помните о периоде записи. Для регистров накопления это критически важный реквизит. Обычно мы присваиваем ему Дата документа, что обеспечивает корректное отображение движений во времени.

Использование конструктора запросов и конструктора движений в конфигураторе — это отличный способ обучения. Платформа самостоятельно сгенерирует скелет кода, который будет соответствовать стандартам разработки 1С. Мы рекомендуем после автоматической генерации кода обязательно анализировать его структуру, чтобы понимать, как именно платформа управляет наборами записей и транзакциями чтения.

Следуя этим простым правилам, вы сможете писать производительный и чистый код, который будет легко поддерживать и развивать в будущем.

← На главную