Разработка и Конфигурация · 10 мин
Как в запросе 1С указать вид движения
Как указать вид движения в запросе 1С: отбор по ВидДвиженияНакопления, значения Приход и Расход, примеры кода для регистров накопления и бухгалтерии, типовые ошибки.
Вид движения — системное свойство записей регистров накопления и бухгалтерии, которое разделяет движения на приходные и расходные (либо дебетовые и кредитовые). При построении запросов к физическим таблицам регистра разработчику регулярно требуется отобрать только один тип движений: например, получить все поступления товара без отгрузок или только списания со склада. Для этого в запросе используется поле ВидДвижения и перечисление ВидДвиженияНакопления.
Ошибки с видом движения — частая причина неверных отчётов: если забыть отбор, запрос вернёт и приход, и расход, а суммирование даст остаток вместо оборота. Ниже разобраны все практические способы указать вид движения: в условии ГДЕ, через параметр, в виртуальных таблицах, а также особенности для регистров бухгалтерии и сведений о проверке результата.
Что такое вид движения и где он хранится
Каждая запись регистра накопления вида «Остатки» обязательно содержит служебное поле ВидДвижения. Оно принимает одно из двух значений перечисления ВидДвиженияНакопления: Приход или Расход. Платформа заполняет это поле автоматически при проведении документа, но в запросах к физической таблице регистра оно доступно для чтения и отбора.
В регистрах бухгалтерии аналогичную роль играет поле ВидДвижения со значениями перечисления ВидДвиженияБухгалтерии: Дебет и Кредит. В регистрах сведений и регистрах накопления вида «Обороты» поля вида движения нет — там движения не разделяются на приход и расход, поэтому попытка обратиться к такому полю вызовет ошибку запроса.
Отбор по виду движения в условии ГДЕ
Самый распространённый способ — указать значение прямо в тексте запроса через конструкцию ЗНАЧЕНИЕ(). Она позволяет обратиться к значению перечисления без передачи параметра:
ВЫБРАТЬ
Движения.Номенклатура,
СУММА(Движения.Количество) КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Движения
ГДЕ
Движения.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
СГРУППИРОВАТЬ ПО
Движения.Номенклатура
Такой запрос вернёт только приходные движения — фактические поступления товара. Если заменить Приход на Расход, получим отгрузки и списания. Сумма по одному виду движения — это оборот, а разность прихода и расхода даёт изменение остатка за период.
Обратите внимание: значение внутри ЗНАЧЕНИЕ() пишется без кавычек и без префикса «Перечисление». Указывается имя менеджера перечисления и через точку — имя значения, как оно задано в метаданных.
ВЫБРАТЬ * ИЗ РегистрНакопления.ТоварыНаСкладах КАК Т ГДЕ Т.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход)Передача вида движения через параметр запроса
Когда вид движения определяется логикой программы (например, пользователь выбрал на форме «поступления» или «списания»), удобнее передать значение параметром. В тексте запроса условие записывается через амперсанд:
ГДЕ Движения.ВидДвижения = &ВидДвижения
А в коде модуля параметр устанавливается через перечисление:
Запрос.УстановитьПараметр("ВидДвижения", Перечисления.ВидДвиженияНакопления.Приход);
Для регистра бухгалтерии аналогично используется Перечисления.ВидДвиженияБухгалтерии.Дебет или .Кредит. Типы параметра и поля должны совпадать: если передать строку «Приход» вместо значения перечисления, сравнение не сработает и запрос вернёт пустой результат либо ошибку в зависимости от контекста.
Вид движения в виртуальных таблицах остатков и оборотов
В виртуальных таблицах ОстаткиИОбороты и Обороты поле ВидДвижения отсутствует — платформа уже агрегировала данные. Вместо отбора по виду движения используются готовые вычисляемые поля: КоличествоПриход, КоличествоРасход, КоличествоОборот, а также начальные и конечные остатки.
Поэтому если задача — получить сумму поступлений за период, правильнее обратиться к виртуальной таблице оборотов и взять поле прихода, чем группировать физическую таблицу с отбором по виду движения. Это и короче, и быстрее, поскольку виртуальные таблицы используют предрасчитанные итоги:
ВЫБРАТЬ
Обороты.Номенклатура,
Обороты.КоличествоПриход,
Обороты.КоличествоРасход
ИЗ
РегистрНакопления.ТоварыНаСкладах.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Обороты
Отбор по виду движения в физической таблице оправдан, когда нужны сами движения построчно: с регистраторами, периодами, номерами строк — например, для расшифровки отчёта или анализа конкретных документов.
Сравнение вариантов
Подходит для построчной выборки движений с регистраторами. Медленнее на больших объёмах, требует группировки для итогов
Подходит для суммовых показателей за период. Быстрее за счёт итогов, но без детализации до документов
Подходит, когда нужны и остатки, и приход с расходом одним запросом. Не даёт детализации по отдельным записям
Особенности для регистров бухгалтерии
В регистрах бухгалтерии поле вида движения называется так же — ВидДвижения, но тип другой: перечисление ВидДвиженияБухгалтерии. Отбор записывается аналогично:
ГДЕ Проводки.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Дебет)
На практике к физической таблице регистра бухгалтерии с отбором по виду движения обращаются редко: чаще используют виртуальные таблицы Обороты, Остатки и ОборотыДтКт, где суммы уже разделены на дебетовые и кредитовые (СуммаОборотДт, СуммаОборотКт). Построчная выборка с отбором по виду движения нужна в основном для аудита проводок конкретного документа.
Как задать вид движения при записи из кода
Хотя вопрос касается запросов, полезно понимать, как поле заполняется: это помогает при отладке, когда в регистре не оказывается ожидаемых движений. При программном формировании движений вид задаётся при добавлении записи набора:
Движение = Движения.ТоварыНаСкладах.ДобавитьПриход();
// или
Движение = Движения.ТоварыНаСкладах.ДобавитьРасход();
// альтернатива — явное присвоение:
Движение = Движения.ТоварыНаСкладах.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
Если в запросе не находятся приходные движения по документу, первым делом проверьте в модуле проведения, каким методом добавляются записи: возможно, разработчик использовал ДобавитьРасход() там, где логически ожидался приход.
- 1Определите вид регистра: накопления (остатки) — ВидДвиженияНакопления, бухгалтерии — ВидДвиженияБухгалтерии
- 2Добавьте в запрос условие ГДЕ Таблица.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход) или передайте значение параметром
- 3Выполните запрос в консоли запросов и сверьте количество строк и суммы с движениями известного документа
- 4Если нужны только итоги — перепишите запрос на виртуальную таблицу Обороты с полями Приход/Расход
Проверка результата и отладка
Надёжный способ проверить корректность отбора — выполнить запрос в консоли запросов (встроенной в режиме предприятия через «Функции для технического специалиста» или внешней обработкой) и сопоставить результат с движениями конкретного документа. Откройте документ поступления, посмотрите его движения по регистру и убедитесь, что запрос с отбором «Приход» возвращает именно эти строки.
Контрольный приём: выполните запрос дважды — с отбором по приходу и по расходу — и сравните суммы с полями КоличествоПриход и КоличествоРасход виртуальной таблицы оборотов за тот же период. Совпадение подтверждает, что отбор написан верно и ничего не потеряно.
Как проверить результат
Все записи имеют один вид движения, заданный в условии
В выборке смешаны приход и расход — условие не применилось
Сумма совпадает с полем Приход (или Расход) таблицы Обороты
Сумма меньше или больше — потеряны записи или ошибка в соединениях
Регистр действительно не содержит движений этого вида за период
Движения есть, но запрос пуст — проверьте тип параметра и имя значения перечисления
Часто задаваемые вопросы
Можно ли отобрать сразу оба вида движения в одном запросе?
Да. Либо вообще уберите условие по виду движения, либо используйте конструкцию В (ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход), ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход)). Для раздельных итогов сгруппируйте результат по полю ВидДвижения.
Почему запрос с условием по виду движения возвращает пустой результат?
Чаще всего причина в несовпадении типов: в параметр передана строка вместо значения перечисления. Также проверьте, что регистр вообще содержит движения за выбранный период и что в ЗНАЧЕНИЕ() указано правильное имя значения без кавычек.
Есть ли вид движения у регистра сведений?
Нет. Регистры сведений хранят произвольные данные без разделения на приход и расход, поэтому поле ВидДвижения у них отсутствует. Обращение к нему в запросе вызовет ошибку «Поле не найдено».
Как получить и приход, и расход одним запросом без группировки по виду движения?
Используйте виртуальную таблицу Обороты или ОстаткиИОбороты регистра накопления: там есть отдельные поля, например КоличествоПриход и КоличествоРасход, которые возвращают оба показателя в одной строке результата.
Чем ДобавитьПриход() отличается от присвоения ВидДвижения в коде?
Функционально ничем: методы ДобавитьПриход() и ДобавитьРасход() — это сокращённая форма, которая добавляет запись и сразу устанавливает соответствующий вид движения. Явное присвоение полю ВидДвижения даёт тот же результат.
Что важно запомнить
Вид движения отбирается условием ГДЕ Таблица.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход или Расход) либо параметром со значением перечисления. Поле существует только у регистров накопления-остатков и бухгалтерии. Для итоговых сумм предпочтительнее виртуальные таблицы оборотов с готовыми полями прихода и расхода.