Работа с бухгалтерскими счетами в запросах 1С:Предприятие — одна из ключевых задач при разработке отчетов, обработок и автоматизации учетных процессов. Даже опытные программисты иногда сталкиваются с нюансами синтаксиса или логическими ошибками при фильтрации данных по счетам. Эта статья поможет разобраться, как корректно формировать запросы с указанием счетов, избегая типичных ошибок и используя все возможности платформы.
Мы рассмотрим не только базовый синтаксис (Где Счет = &Счет), но и продвинутые техники: работу с субсчетами, аналитикой, виртуальными таблицами и динамическими параметрами. Особое внимание уделено разнице между счетами в бухгалтерском и налоговом учете, а также оптимизации запросов для крупных баз данных. Все примеры приведены для актуальных версий платформы 1С:Предприятие 8.3 (включая 8.3.23+).
1. Базовый синтаксис: как указать счет в условии запроса
Самый простой способ отфильтровать данные по счету — использовать оператор равенства в секции Где. Например, чтобы получить все проводки по счету 60.01 ("Расчеты с поставщиками"), достаточно написать:
Выбрать
Проводка.Счет,
Проводка.Субконто1,
Проводка.Сумма
Из
РегистрБухгалтерии.Хозрасчетный Как Проводка
Где
Проводка.Счет = &Счет
Здесь &Счет — это параметр запроса, который можно передать из кода 1С или ввести вручную при выполнении. 01").
- 🔹 Тип данных: параметр
&Счетдолжен иметь типСчетБухгалтерскогоУчетаилиПланСчетов.Ссылка - 🔹 Субсчета: если нужно выбрать все субсчета (например, 60.01, 60.02), используйте оператор
ПодчиненилиВ Иерархии - 🔹 Производительность: фильтрация по счету на уровне СУБД (в секции
Где) работает быстрее, чем в коде 1С после получения данных
⚠️ Внимание: Если в запросе используете виртуальные таблицы (например, РегистрБухгалтерии.Хозрасчетный.Обороты()), учтите, что фильтрация по счету в них может работать иначе — некоторые таблицы требуют явного указания периода.
2. Работа с субсчетами и иерархией планов счетов
Часто требуется выбрать данные не по одному счету, а по всей группе субсчетов. Например, получить все проводки по счету 60 ("Расчеты с поставщиками и подрядчиками"), включая 60.01, 60.02, 60.31 и т.д. Для этого используйте операторы Подчинен или В Иерархии:
Где
Проводка.Счет Подчинен &РодительскийСчет
Где &РодительскийСчет — это ссылка на счет верхнего уровня (например, 60). Альтернативный вариант с явным указанием маски:
Где
Левиз(Проводка.Счет.Код, 5) = "60.01"
Этот подход полезен, если нужно отфильтровать счета по части кода (например, все счета, начинающиеся на "10.06"). Однако он менее гибок, чем работа с иерархией, так как не учитывает изменения в плане счетов.
| Оператор | Пример использования | Когда применять |
|---|---|---|
= |
Проводка.Счет = &Счет |
Точное совпадение по одному счету |
Подчинен |
Проводка.Счет Подчинен &Родитель |
Выбор всех субсчетов заданного счета |
В Иерархии |
Проводка.Счет В Иерархии (&СписокСчетов) |
Фильтрация по нескольким родительским счетам |
Левиз() |
Левиз(Проводка.Счет.Код, 5) = "10.06" |
Фильтрация по части кода счета (устаревший метод) |
3. Фильтрация по счетам в виртуальных таблицах
Виртуальные таблицы (Обороты(), Остатки(), ОборотыИОстатки()) имеют особенности при фильтрации по счетам. Например, запрос оборотов по счету 51 ("Расчетный счет") может выглядеть так:
Выбрать
Обороты.Счет Как Счет,
Обороты.Субконто1 Как Контрагент,
Сумма(Обороты.СуммаОборот) Как СуммаОборот
Из
РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода,) Как Обороты
Где
Обороты.Счет = &Счет51
Сгруппировать По
Обороты.Счет,
Обороты.Субконто1
Критическая особенность: в виртуальных таблицах фильтрация по счету должна идти ДО применения агрегирующих функций (например, Сумма()), иначе СУБД может проигнорировать условие. Это связано с оптимизацией выполнения запросов в 1С.
- 📌 Период обязателен: виртуальные таблицы требуют указания периода (
&НачалоПериода, &КонецПериода), даже если фильтрация идет только по счету - 📌 Производительность: фильтрация по счету в виртуальных таблицах может быть медленнее, чем в обычных запросах к регистру бухгалтерии
- 📌 Аналитика: если нужны данные по субконто (контрагенты, номенклатура), их тоже нужно указать в секции
ГдеилиСгруппировать По
Для ускорения запросов к виртуальным таблицам сначала фильтруйте данные по периоду, затем по счету, и только потом применяйте агрегирующие функции.
4. Работа с аналитикой: счета + субконто
В бухгалтерских запросах часто требуется не только фильтрация по счету, но и по аналитике (субконто). Например, получить все проводки по счету 62.01 ("Расчеты с покупателями") для конкретного контрагента. Синтаксис будет таким:
Где
Проводка.Счет = &Счет62_01
И Проводка.Субконто1 = &Контрагент
Где &Контрагент — ссылка на элемент справочника "Контрагенты". Если аналитика многоуровневая (например, счета 10-го плана могут иметь субконто "Номенклатура", "Склады", "Партии"), используйте соответствующие поля:
Где
Проводка.Счет = &Счет10_01
И Проводка.Субконто1 = &Номенклатура
И Проводка.Субконто2 = &Склад
Для динамической фильтрации по нескольким субконто удобно использовать массив параметров:
Где
Проводка.Счет = &Счет
И Проводка.Субконто1 В (&МассивКонтрагентов)
⚠️ Внимание: При работе с аналитикой учитывайте, что структура субконто зависит от настройки плана счетов. Например, у счета 60.01 субконто1 — это "Контрагенты", а у счета 10.01 — "Номенклатура". Проверяйте структуру в конфигураторе (План счетов → Субконто).
Уточнить структуру субконто для данного счета в плане счетов|
Проверить типы данных параметров (ссылка на справочник)|
Учесть, что нумерация субконто (Субконто1, Субконто2..) зависит от конфигурации|
Для виртуальных таблиц указать субконто в секции "Где" ДО агрегации-->
5. Динамическое формирование списка счетов
В реальных задачах часто требуется формировать список счетов динамически — например, на основе пользовательского ввода или данных из регистров. Рассмотрим два подхода:
1. Передача массива счетов как параметра:
Запрос.УстановитьПараметр("СписокСчетов", МассивСчетов);
..
Где
Проводка.Счет В (&СписокСчетов)
2. Формирование списка счетов прямо в запросе (для простых случаев):
Где
Проводка.Счет В (
ВыборкаСчетов.Счет
Из
ПланСчетов.Бухгалтерский Как ВыборкаСчетов
Где
ВыборкаСчетов.Код НачинаетсяС "10."
)
Второй подход полезен, если нужно выбрать счета по шаблону (например, все счета, начинающиеся на "10."). Однако он менее производителен, чем передача готового массива.
Как передать массив счетов из формы в запрос?
1. В форме создайте реквизит типа "Массив" с типом значений "СчетБухгалтерскогоУчета".
2. Заполните массив выбранными пользователем счетами (например, через поле выбора с множественным выбором).
3. Передайте массив в запрос: Запрос.УстановитьПараметр("МассивСчетов", МассивСчетовИзФормы);
4. В тексте запроса используйте: Проводка.Счет В (&МассивСчетов)
6. Особенности работы с налоговым учетом
В 1С:Бухгалтерия помимо бухгалтерских счетов есть счета налогового учета (план счетов НУ). Они хранятся в отдельном регистре (РегистрБухгалтерии.Налоговый) и имеют свою логику фильтрации. Пример запроса к налоговому регистру:
Выбрать
ПроводкаНУ.СчетНУ Как Счет,
ПроводкаНУ.Сумма Как Сумма
Из
РегистрБухгалтерии.Налоговый Как ПроводкаНУ
Где
ПроводкаНУ.СчетНУ = &СчетНУ
И ПроводкаНУ.Период Между &НачалоПериода И &КонецПериода
Ключевые отличия от бухгалтерского учета:
- 🔸 Используется поле
СчетНУвместоСчет - 🔸 План счетов налогового учета может отличаться от бухгалтерского
- 🔸 В некоторых конфигурациях счета НУ привязаны к бухгалтерским счетам через регистр соответствия
⚠️ Внимание: В конфигурациях с раздельным учетом (например, 1С:ERP или 1С:КА) может потребоваться дополнительная фильтрация по виду учета (Проводка.ВидУчета = ВидУчетаБухгалтерский.Хозрасчетный).
7. Оптимизация запросов по счетам для крупных баз
При работе с большими объемами данных (десятки тысяч проводок) запросы по счетам могут выполняться медленно. Вот ключевые приемы оптимизации:
- 🚀 Индексы: убедитесь, что в плане счетов настроены индексы по полям
Счет,ПериодиСубконто. В конфигураторе проверьте свойства регистра бухгалтерии. - 🚀 Фильтрация на уровне СУБД: переносите условия по счетам и периодам в секцию
Где, а не обрабатывайте данные после выполнения запроса. - 🚀 Виртуальные таблицы: для отчетов по оборотам используйте
ОборотыИОстатки()вместо отдельных запросов кОбороты()иОстатки(). - 🚀 Пакетные запросы: если нужно получить данные по нескольким счетам, лучше выполнить один запрос с условием
В (&МассивСчетов), чем несколько запросов по отдельности.
Пример оптимизированного запроса для получения оборотов по группе счетов:
Выбрать
Обороты.Счет Как Счет,
Сумма(Обороты.СуммаОборот) Как СуммаОборот
Из
РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода,) Как Обороты
Где
Обороты.Счет В (&МассивСчетов)
И Обороты.Организация = &Организация
Сгруппировать По
Обороты.Счет
Для ускорения запросов по счетам всегда фильтруйте данные по периоду и организации (если применимо) — это сокращает объем сканируемых данных.
8. Типичные ошибки и как их избежать
Даже опытные разработчики иногда допускают ошибки при работе со счетами в запросах. Вот наиболее распространенные:
| Ошибка | Причина | Как исправить |
|---|---|---|
| Запрос не возвращает данные | Счет передан как строка ("60.01") вместо ссылки | Используйте ПланыСчетов.Хозрасчетный.НайтиПоКоду("60.01") |
| Медленное выполнение | Фильтрация по субконто применена после агрегации | Перенесите условия в секцию Где |
| Ошибка "Поле не найдено" | Неверное имя субконто (например, Субконто3 вместо Субконто1) |
Проверьте структуру счета в плане счетов |
| Некорректные обороты | Не указан период для виртуальной таблицы | Добавьте параметры &НачалоПериода, &КонецПериода |
Еще одна частая проблема — путаница между бухгалтерскими и налоговыми счетами. Например, запрос к регистру РегистрБухгалтерии.Хозрасчетный не вернет данные, если фильтровать по счету НУ. Всегда проверяйте, какой регистр используется в запросе.
Чтобы избежать ошибок с типами данных, используйте отладчик 1С: поставьте точку останова перед выполнением запроса и проверьте, какой тип имеют параметры (должны быть ссылками на план счетов, а не строками).
Как найти счет по коду в запросе?
Если у вас есть код счета (например, "60.01"), но нужна ссылка для фильтрации, используйте конструкцию:
Где
Проводка.Счет = ПланыСчетов.Хозрасчетный.НайтиПоКоду("60.01")
Или передайте ссылку из кода:
Счет60_01 = ПланыСчетов.Хозрасчетный.НайтиПоКоду("60.01");
Запрос.УстановитьПараметр("Счет", Счет60_01);
Почему запрос по счету работает медленно?
Основные причины:
- Отсутствие индексов на поле
Счетв регистре бухгалтерии. - Фильтрация по субконто применена после агрегации (например, в секции
Имеющие). - Использование функций над полем счета (например,
Левиз(Проводка.Счет.Код, 5)), что блокирует использование индексов. - Большой период выборки (например, запрос оборотов за 5 лет).
Решение: оптимизируйте запрос по приведенным выше рекомендациям и используйте ОбъяснитьЗапрос() для анализа плана выполнения.
Можно ли в одном запросе получить данные по бухгалтерским и налоговым счетам?
Да, но для этого нужно использовать объединение (Объединить) или подзапросы. Пример:
Выбрать
ПроводкаБУ.Счет Как СчетБУ,
ПроводкаБУ.Сумма Как СуммаБУ,
ПроводкаНУ.СчетНУ Как СчетНУ,
ПроводкаНУ.Сумма Как СуммаНУ
Из
РегистрБухгалтерии.Хозрасчетный Как ПроводкаБУ
Левое Соединение РегистрБухгалтерии.Налоговый Как ПроводкаНУ
По ПроводкаБУ.Регистратор = ПроводкаНУ.Регистратор
Где
ПроводкаБУ.Счет = &СчетБУ
И ПроводкаНУ.СчетНУ = &СчетНУ
Обратите внимание, что такой запрос может быть ресурсоемким.
Как получить остатки по счету на конкретную дату?
Используйте виртуальную таблицу Остатки():
Выбрать
Остатки.Счет Как Счет,
Остатки.СуммаОстаток Как Остаток
Из
РегистрБухгалтерии.Хозрасчетный.Остатки(&ДатаОстатка,) Как Остатки
Где
Остатки.Счет = &Счет
Где &ДатаОстатка — дата, на которую нужно получить остатки.
Что делать, если в запросе нужно учесть валютные счета?
Для валютных счетов (например, 52 "Валютный счет") в запросе нужно учитывать:
- Поле
Валютав проводке. - Сумму в валюте (
СуммаВалюта) и курс.
Пример:
Выбрать
Проводка.Счет,
Проводка.Валюта,
Проводка.СуммаВалюта,
Проводка.Курс
Из
РегистрБухгалтерии.Хозрасчетный Как Проводка
Где
Проводка.Счет = &Счет52