Счёт в запросе к регистру бухгалтерии 1С 8.3
Содержание
Счёт в запросе указывают тремя способами: условием в секции ГДЕ (Счет = &Счет), параметром «Условие» виртуальной таблицы или литералом ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.<Имя>) для предопределённого счёта. Чтобы в выборку попали субсчета, вместо знака равенства берут В ИЕРАРХИИ(&Счет).
Сам счёт — это элемент плана счетов, а движения лежат в регистре бухгалтерии. В типовой «Бухгалтерии предприятия 3.0» план счетов
и регистр называются одинаково — Хозрасчетный. Дальше разберём, когда какой способ указания счёта выбирать, как фильтровать по аналитике и субсчетам и как не потерять копейки на округлении.
Откуда запрос берёт счета: план счетов и регистр
В запросе участвуют два объекта. План счетов ПланСчетов.Хозрасчетный хранит сами счета и субсчета (41, 41.01, 60, 60.01 и т.д.). Регистр бухгалтерии
РегистрБухгалтерии.Хозрасчетный хранит проводки: дата, счёт дебета, счёт кредита, субконто, суммы.
Поле Счет в регистре — это ссылка на элемент плана счетов. Поэтому в условии вы сравниваете ссылку со ссылкой, а не строку с кодом. Написать ГДЕ Счет = "41" нельзя — типы не совпадут.
Ссылку на нужный счёт удобно заранее получить в коде через ПланыСчетов.Хозрасчетный.НайтиПоКоду("41") и передать в запрос параметром. В коде менеджер плана счетов пишется во множественном числе — ПланыСчетов, а в тексте запроса, в функции ЗНАЧЕНИЕ(), — в единственном: ПланСчетов. Это частый источник ошибки «поле не найдено».
У регистра есть основная таблица движений и несколько виртуальных: Остатки, Обороты, ОстаткиИОбороты, ДвиженияССубконто. Для остатков и оборотов почти всегда берут виртуальные таблицы — они быстрее и уже агрегированы.
К реквизитам счёта в запросе обращаются через точку от поля Счет: Хозрасчетный.Счет.Код, Хозрасчетный.Счет.Наименование, Хозрасчетный.Счет.Вид (активный, пассивный, активно-пассивный), Хозрасчетный.Счет.Забалансовый. Это удобно, когда в отчёт нужен код или наименование счёта либо отбор по его виду, а не по конкретной ссылке.
Три способа указать счёт в тексте запроса
Условие в секции ГДЕ
Самый прямой вариант. Подходит, когда вы читаете основную таблицу движений или уже выбрали данные из виртуальной таблицы:
ВЫБРАТЬ
Хозрасчетный.Период,
Хозрасчетный.Счет,
Хозрасчетный.Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
Хозрасчетный.Счет = &Счет
Параметр &Счет устанавливают в коде: Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.НайтиПоКоду("41"));.
Параметр «Условие» виртуальной таблицы
У виртуальных таблиц есть параметр для отбора — его заполняют условием по счёту. Так отбор применяется до агрегации, и движок обрабатывает меньше данных:
ВЫБРАТЬ
ХозрасчетныйОстатки.Счет,
ХозрасчетныйОстатки.СуммаОстаток
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(
&НаДату,
Счет В ИЕРАРХИИ(&Счет)) КАК ХозрасчетныйОстатки
Первый параметр здесь — момент времени, второй — условие отбора. Внутри условия обращаются к полю Счет без имени таблицы.
Литерал предопределённого счёта
Если счёт известен на этапе разработки и он предопределён в плане счетов, можно обойтись без параметра:
ГДЕ
Хозрасчетный.Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Товары)
Имя предопределённого счёта (Товары, а не код 41) смотрят в конфигураторе: План счетов Хозрасчетный → вкладка «Прочее» → «Предопределённые». Код счёта и имя предопределённого — разные вещи: в ЗНАЧЕНИЕ() идёт имя, а не «41».
Какой способ выбрать — зависит от задачи:
&Счет и сравнивайте через = или В ИЕРАРХИИ. Код гибкий, запрос не меняется при смене счёта.ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.<Имя>). Не нужен ни параметр, ни поиск по коду.Остатки/Обороты, а не секцию ГДЕ поверх основной таблицы — так быстрее.Из какой таблицы брать счёт: основная и виртуальные
Указание счёта почти всегда идёт вместе с выбором таблицы. От неё зависит, какие поля счёта и ресурсы доступны и насколько быстрым будет запрос.
| Таблица | Что отдаёт | Когда брать |
|---|---|---|
Хозрасчетный (основная) | Каждую проводку: счёт Дт, счёт Кт, субконто, сумма | Нужны отдельные движения, журнал проводок |
.Остатки | Остатки по счёту на дату | Сальдо, остатки товаров, задолженность |
.Обороты | Обороты за период | Движение по счёту за месяц, квартал |
.ОстаткиИОбороты | Сальдо на начало/конец + обороты | Оборотно-сальдовая ведомость |
.ОборотыДтКт | Обороты в разрезе корреспонденции | Анализ связки «дебет — кредит» |
.ДвиженияССубконто | Движения с колонками Субконто1..3 | Детализация проводок по аналитике |
Главное правило: не считайте остатки по основной таблице вручную — берите виртуальную Остатки. Самостоятельное суммирование движений с начала учёта и медленнее, и легко даёт расхождение с типовыми отчётами.
Полный пример получения ссылки на счёт в коде и подстановки в запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Счет,
| Остатки.СуммаОстаток
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(
| &НаДату,
| Счет В ИЕРАРХИИ(&Счет)) КАК Остатки";
Запрос.УстановитьПараметр("НаДату", КонецДня(ТекущаяДата()));
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.НайтиПоКоду("41"));
Результат = Запрос.Выполнить();
Если НайтиПоКоду вернёт пустую ссылку, значит счёта с таким кодом в плане нет — проверьте код и регистр (в УТ и ERP регистр бухгалтерии может называться иначе или отсутствовать). Код счёта в типовых конфигурациях чувствителен к ведущим пробелам и точкам: ищите ровно так, как счёт записан в плане, то есть 41, а не 41.01, если нужна группа.
Как захватить субсчета: конструкция В ИЕРАРХИИ
Счёт 41 в плане счетов — группа, под ней субсчета 41.01, 41.02, 41.11, 41.12. Если написать Счет = &Счет и передать счёт 41, в выборку попадут только проводки ровно по 41, а не по субсчетам. Обычно это не то, что нужно.
Чтобы собрать данные по счёту вместе со всеми его субсчетами, используют иерархическое условие:
ГДЕ
Хозрасчетный.Счет В ИЕРАРХИИ(&Счет)
В ИЕРАРХИИ(&Счет) вернёт сам счёт и все уровни субсчетов под ним. Если нужен список конкретных счетов, передают массив:
ГДЕ
Хозрасчетный.Счет В (&СписокСчетов)
В параметр СписокСчетов кладут Массив ссылок на счета.
В ИЕРАРХИИ обходит дерево субсчетов и обходится дороже, чем простое =. Если точно знаете, что движения есть только на одном субсчёте, укажите его напрямую — запрос отработает быстрее.
Отдельный частый случай — отбор по счёту дебета и кредита одновременно (корреспонденция). Для анализа связки «дебет — кредит» берут таблицу ОборотыДтКт, где есть оба поля — СчетДт и СчетКт:
ВЫБРАТЬ
ОборотыДтКт.СчетДт,
ОборотыДтКт.СчетКт,
ОборотыДтКт.СуммаОборот
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(
&Начало,
&Конец,
,
СчетДт В ИЕРАРХИИ(&СчетДт),
СчетКт В ИЕРАРХИИ(&СчетКт)) КАК ОборотыДтКт
Так, например, получают сумму поступления товаров — обороты по дебету 41 в корреспонденции с кредитом 60. Если нужен оборот по счёту без разбивки на корреспонденцию, хватает обычной таблицы Обороты.
Фильтр по аналитике: субконто и виды субконто
Счёт сам по себе — это верхний уровень. Детализация идёт через субконто: номенклатура, контрагенты, договоры, статьи затрат. У регистра Хозрасчетный до трёх субконто на проводку.
Проще всего работать с аналитикой через виртуальную таблицу ДвиженияССубконто — в ней есть колонки Субконто1, Субконто2, Субконто3:
ВЫБРАТЬ
Движения.Счет,
Движения.Субконто1 КАК Номенклатура,
Движения.Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто КАК Движения
ГДЕ
Движения.Счет В ИЕРАРХИИ(&Счет)
И Движения.Субконто1 = &Номенклатура
Порядок субконто у каждого счёта свой и задан в настройке видов субконто плана счетов. У счёта 41 первое субконто — «Номенклатура», у счёта 60 — «Контрагенты». Не считайте, что Субконто1 везде означает одно и то же: у разных счетов это разные справочники.
Если нужен отбор по аналитике прямо в виртуальных таблицах Остатки/Обороты, в них передают перечень видов субконто. По умолчанию эти таблицы субконто не разворачивают — пока не укажешь виды субконто, колонок Субконто1..3 в выборке не будет. Проще всего заполнять их в конструкторе запроса: откройте таблицу Остатки, перейдите на вкладку работы с субконто и отметьте нужные виды. Конструктор сам подставит параметр и добавит поля.
Важная оговорка: виды субконто имеет смысл запрашивать те, что действительно заведены у выбранных счетов. Если счёт ведётся без аналитики, запрос субконто по нему вернёт пустые значения. Когда счета в выборке разнородные (у одного аналитика есть, у другого нет), безопаснее сначала получить данные, а условие по субконто наложить снаружи, в секции ГДЕ — так не перепутаете позиции аналитики у разных счетов.
Валютные и количественные счета
На счетах с признаком количественного или валютного учёта, кроме суммы в рублях, есть свои ресурсы:
- 💰
СуммаОстаток/СуммаОборот— сумма в рублях (валюта учёта); - 💱
ВалютнаяСуммаОстаток/ВалютнаяСуммаОборот— сумма в валюте счёта (например, по 52 или 60 в у.е.); - 📦
КоличествоОстаток/КоличествоОборот— количество (по товарным и материальным счетам).
Для валютных счетов есть измерение Валюта — по нему можно фильтровать и группировать:
ВЫБРАТЬ
Остатки.Счет,
Остатки.Валюта,
Остатки.ВалютнаяСуммаОстаток,
Остатки.СуммаОстаток
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(
&НаДату,
Счет В ИЕРАРХИИ(&Счет)) КАК Остатки
ГДЕ
Остатки.Валюта = &Валюта
Если запросить ВалютнаяСуммаОстаток по счёту без валютного признака, поле вернёт 0 или NULL. Проверяйте в плане счетов, какие признаки учёта включены у счёта, прежде чем тянуть эти ресурсы в отчёт.
Количество запрашивают так же — ресурсом КоличествоОстаток. По счетам без количественного учёта он тоже будет пустым, и это нормально.
Оптимизация запроса и ошибки округления
Две частые проблемы при работе со счетами в запросах — медленный запрос и «уплывшие» копейки.
Чтобы запрос не тормозил:
- 🚀 остатки и обороды берите из виртуальных таблиц
Остатки/Обороты, а не считайте по основной таблице движений вручную; - 🎯 отбор по счёту задавайте в параметре «Условие» виртуальной таблицы — отбор применяется до агрегации;
- 🔗 счёт передавайте готовой ссылкой через параметр, не ищите его по коду внутри запроса;
- 🌳
В ИЕРАРХИИиспользуйте там, где реально нужны субсчета, а не «на всякий случай».
С округлением аккуратнее. Суммы в регистре хранятся с двумя знаками после запятой, количество — обычно с тремя. Проблемы начинаются, когда в запросе делят сумму на количество, чтобы получить себестоимость единицы:
Деление сумм и количеств прямо в тексте запроса даёт неконтролируемое округление. Один и тот же расчёт в запросе и в коде может разойтись на копейки, и в отчёте «не сойдётся» итог.
Что помогает:
- Не делите суммы в запросе. Выберите
СуммаОстатокиКоличествоОстатокотдельными полями, а цену за единицу посчитайте в коде черезОкр(Сумма / Количество, 2). - Контролируйте разрядность через
ВЫРАЗИТЬ:ВЫРАЗИТЬ(Остатки.КоличествоОстаток КАК ЧИСЛО(15, 3)). - При сравнении остатка с нулём помните про копейки:
КоличествоОстаток > 0надёжнее, чем проверка суммы, если по счёту ведётся количественный учёт.
Частые вопросы
Почему условие `Счет = "41"` не работает?
Счет — это ссылка на элемент плана счетов, а "41" — строка. Типы не совпадают, и запрос вернёт ошибку либо пустой результат. Получите ссылку через НайтиПоКоду("41") и передайте параметром.В чём разница между `В ИЕРАРХИИ` и `В`?
В ИЕРАРХИИ(&Счет) берёт счёт и все его субсчета по дереву плана счетов. В (&Список) берёт только те счета, что явно перечислены в массиве. Для «41 со всеми субсчетами» нужна иерархия, для «41.01 и 41.02» — список.Как отобрать и по дебету, и по кредиту сразу?
ОборотыДтКт с полями СчетДт и СчетКт.Почему валютная сумма выходит нулевой?
ВалютнаяСуммаОстаток заполнен только по счетам с признаком валютного учёта. Если счёт ведётся без валюты, поле пустое. Проверьте признаки учёта счёта в плане счетов.Можно ли указать счёт литералом без параметра?
ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.<ИмяПредопределённого>). В функции идёт имя предопределённого элемента из конфигуратора, а не код счёта.