К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как в запросе 1С указать вид движения

Как указать вид движения в запросе 1С: отбор по ВидДвиженияНакопления, значения Приход и Расход, примеры кода для регистров накопления и бухгалтерии, типовые ошибки.

Вид движения — системное свойство записей регистров накопления и бухгалтерии, которое разделяет движения на приходные и расходные (либо дебетовые и кредитовые). При построении запросов к физическим таблицам регистра разработчику регулярно требуется отобрать только один тип движений: например, получить все поступления товара без отгрузок или только списания со склада. Для этого в запросе используется поле ВидДвижения и перечисление ВидДвиженияНакопления.

Ошибки с видом движения — частая причина неверных отчётов: если забыть отбор, запрос вернёт и приход, и расход, а суммирование даст остаток вместо оборота. Ниже разобраны все практические способы указать вид движения: в условии ГДЕ, через параметр, в виртуальных таблицах, а также особенности для регистров бухгалтерии и сведений о проверке результата.

Что такое вид движения и где он хранится

Каждая запись регистра накопления вида «Остатки» обязательно содержит служебное поле ВидДвижения. Оно принимает одно из двух значений перечисления ВидДвиженияНакопления: Приход или Расход. Платформа заполняет это поле автоматически при проведении документа, но в запросах к физической таблице регистра оно доступно для чтения и отбора.

В регистрах бухгалтерии аналогичную роль играет поле ВидДвижения со значениями перечисления ВидДвиженияБухгалтерии: Дебет и Кредит. В регистрах сведений и регистрах накопления вида «Обороты» поля вида движения нет — там движения не разделяются на приход и расход, поэтому попытка обратиться к такому полю вызовет ошибку запроса.

Отбор по виду движения в условии ГДЕ

Самый распространённый способ — указать значение прямо в тексте запроса через конструкцию ЗНАЧЕНИЕ(). Она позволяет обратиться к значению перечисления без передачи параметра:

ВЫБРАТЬ

Движения.Номенклатура,

СУММА(Движения.Количество) КАК Количество

ИЗ

РегистрНакопления.ТоварыНаСкладах КАК Движения

ГДЕ

Движения.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)

СГРУППИРОВАТЬ ПО

Движения.Номенклатура

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

Обратите внимание: значение внутри ЗНАЧЕНИЕ() пишется без кавычек и без префикса «Перечисление». Указывается имя менеджера перечисления и через точку — имя значения, как оно задано в метаданных.

bsl
ВЫБРАТЬ * ИЗ РегистрНакопления.ТоварыНаСкладах КАК Т ГДЕ Т.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход)

Передача вида движения через параметр запроса

Когда вид движения определяется логикой программы (например, пользователь выбрал на форме «поступления» или «списания»), удобнее передать значение параметром. В тексте запроса условие записывается через амперсанд:

ГДЕ Движения.ВидДвижения = &ВидДвижения

А в коде модуля параметр устанавливается через перечисление:

Запрос.УстановитьПараметр("ВидДвижения", Перечисления.ВидДвиженияНакопления.Приход);

Для регистра бухгалтерии аналогично используется Перечисления.ВидДвиженияБухгалтерии.Дебет или .Кредит. Типы параметра и поля должны совпадать: если передать строку «Приход» вместо значения перечисления, сравнение не сработает и запрос вернёт пустой результат либо ошибку в зависимости от контекста.

Типичные ошибки
01
Передача строки "Приход" вместо значения перечисления — сравнение не выполняется, результат пустой
02
Обращение к полю ВидДвижения у оборотного регистра или регистра сведений — ошибка «Поле не найдено»
03
Сравнение поля ВидДвижения с видом движения бухгалтерии в регистре накопления — несовместимые типы перечислений
04
Суммирование количества без отбора по виду движения — вместо оборота получается изменение остатка

Вид движения в виртуальных таблицах остатков и оборотов

В виртуальных таблицах ОстаткиИОбороты и Обороты поле ВидДвижения отсутствует — платформа уже агрегировала данные. Вместо отбора по виду движения используются готовые вычисляемые поля: КоличествоПриход, КоличествоРасход, КоличествоОборот, а также начальные и конечные остатки.

Поэтому если задача — получить сумму поступлений за период, правильнее обратиться к виртуальной таблице оборотов и взять поле прихода, чем группировать физическую таблицу с отбором по виду движения. Это и короче, и быстрее, поскольку виртуальные таблицы используют предрасчитанные итоги:

ВЫБРАТЬ

Обороты.Номенклатура,

Обороты.КоличествоПриход,

Обороты.КоличествоРасход

ИЗ

РегистрНакопления.ТоварыНаСкладах.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Обороты

Отбор по виду движения в физической таблице оправдан, когда нужны сами движения построчно: с регистраторами, периодами, номерами строк — например, для расшифровки отчёта или анализа конкретных документов.

Сравнение вариантов

Физическая таблица + ГДЕ ВидДвижения

Подходит для построчной выборки движений с регистраторами. Медленнее на больших объёмах, требует группировки для итогов

Виртуальная таблица Обороты

Подходит для суммовых показателей за период. Быстрее за счёт итогов, но без детализации до документов

Виртуальная таблица ОстаткиИОбороты

Подходит, когда нужны и остатки, и приход с расходом одним запросом. Не даёт детализации по отдельным записям

Особенности для регистров бухгалтерии

В регистрах бухгалтерии поле вида движения называется так же — ВидДвижения, но тип другой: перечисление ВидДвиженияБухгалтерии. Отбор записывается аналогично:

ГДЕ Проводки.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Дебет)

На практике к физической таблице регистра бухгалтерии с отбором по виду движения обращаются редко: чаще используют виртуальные таблицы Обороты, Остатки и ОборотыДтКт, где суммы уже разделены на дебетовые и кредитовые (СуммаОборотДт, СуммаОборотКт). Построчная выборка с отбором по виду движения нужна в основном для аудита проводок конкретного документа.

Как задать вид движения при записи из кода

Хотя вопрос касается запросов, полезно понимать, как поле заполняется: это помогает при отладке, когда в регистре не оказывается ожидаемых движений. При программном формировании движений вид задаётся при добавлении записи набора:

Движение = Движения.ТоварыНаСкладах.ДобавитьПриход();

// или

Движение = Движения.ТоварыНаСкладах.ДобавитьРасход();

// альтернатива — явное присвоение:

Движение = Движения.ТоварыНаСкладах.Добавить();

Движение.ВидДвижения = ВидДвиженияНакопления.Приход;

Если в запросе не находятся приходные движения по документу, первым делом проверьте в модуле проведения, каким методом добавляются записи: возможно, разработчик использовал ДобавитьРасход() там, где логически ожидался приход.

Порядок отбора движений по виду
  1. 1
    Определите вид регистра: накопления (остатки) — ВидДвиженияНакопления, бухгалтерии — ВидДвиженияБухгалтерии
  2. 2
    Добавьте в запрос условие ГДЕ Таблица.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход) или передайте значение параметром
  3. 3
    Выполните запрос в консоли запросов и сверьте количество строк и суммы с движениями известного документа
  4. 4
    Если нужны только итоги — перепишите запрос на виртуальную таблицу Обороты с полями Приход/Расход

Проверка результата и отладка

Надёжный способ проверить корректность отбора — выполнить запрос в консоли запросов (встроенной в режиме предприятия через «Функции для технического специалиста» или внешней обработкой) и сопоставить результат с движениями конкретного документа. Откройте документ поступления, посмотрите его движения по регистру и убедитесь, что запрос с отбором «Приход» возвращает именно эти строки.

Контрольный приём: выполните запрос дважды — с отбором по приходу и по расходу — и сравните суммы с полями КоличествоПриход и КоличествоРасход виртуальной таблицы оборотов за тот же период. Совпадение подтверждает, что отбор написан верно и ничего не потеряно.

Контрольные точки

Как проверить результат

Тип возвращаемых строк
Норма

Все записи имеют один вид движения, заданный в условии

Тревожный признак

В выборке смешаны приход и расход — условие не применилось

Сумма по отбору против виртуальной таблицы
Норма

Сумма совпадает с полем Приход (или Расход) таблицы Обороты

Тревожный признак

Сумма меньше или больше — потеряны записи или ошибка в соединениях

Пустой результат
Норма

Регистр действительно не содержит движений этого вида за период

Тревожный признак

Движения есть, но запрос пуст — проверьте тип параметра и имя значения перечисления

Часто задаваемые вопросы

Можно ли отобрать сразу оба вида движения в одном запросе?

Да. Либо вообще уберите условие по виду движения, либо используйте конструкцию В (ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход), ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход)). Для раздельных итогов сгруппируйте результат по полю ВидДвижения.

Почему запрос с условием по виду движения возвращает пустой результат?

Чаще всего причина в несовпадении типов: в параметр передана строка вместо значения перечисления. Также проверьте, что регистр вообще содержит движения за выбранный период и что в ЗНАЧЕНИЕ() указано правильное имя значения без кавычек.

Есть ли вид движения у регистра сведений?

Нет. Регистры сведений хранят произвольные данные без разделения на приход и расход, поэтому поле ВидДвижения у них отсутствует. Обращение к нему в запросе вызовет ошибку «Поле не найдено».

Как получить и приход, и расход одним запросом без группировки по виду движения?

Используйте виртуальную таблицу Обороты или ОстаткиИОбороты регистра накопления: там есть отдельные поля, например КоличествоПриход и КоличествоРасход, которые возвращают оба показателя в одной строке результата.

Чем ДобавитьПриход() отличается от присвоения ВидДвижения в коде?

Функционально ничем: методы ДобавитьПриход() и ДобавитьРасход() — это сокращённая форма, которая добавляет запись и сразу устанавливает соответствующий вид движения. Явное присвоение полю ВидДвижения даёт тот же результат.

Итог

Что важно запомнить

Вид движения отбирается условием ГДЕ Таблица.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход или Расход) либо параметром со значением перечисления. Поле существует только у регистров накопления-остатков и бухгалтерии. Для итоговых сумм предпочтительнее виртуальные таблицы оборотов с готовыми полями прихода и расхода.