Как в запросе 1С получить значение субконто, если его позиция на разных счетах отличается?

Программист 1С v8.3 (Обычные формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

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

Способ 1: Использование массива видов субконто в параметрах виртуальной таблицы

Это наиболее правильный и производительный метод с точки зрения платформы 1С. Рассмотрим механизм подстановки: когда мы передаем массив конкретных видов субконто в параметры виртуальной таблицы (например, Остатки или ОстаткиИОбороты), система выполняет автоматическое переназначение индексов.

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


// Формируем массив нужных видов субконто
ВидыСубконто = Новый Массив;
ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ОсновныеСредства);
ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.НематериальныеАктивы);
ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура);

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ХозрасчетныйОстатки.Субконто1 КАК ОбъектУчета,
    |   ХозрасчетныйОстатки.СуммаОстаток КАК Остаток
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет В ИЕРАРХИИ(&СчетаОС), &ВидыСубконто) КАК ХозрасчетныйОстатки";

Запрос.УстановитьПараметр("ВидыСубконто", ВидыСубконто);
Запрос.УстановитьПараметр("Период", ДатаОстатков);
Запрос.УстановитьПараметр("СчетаОС", СписокСчетов);

Важно понимать: порядок элементов в массиве &ВидыСубконто строго определяет, что попадет в Субконто1 и Субконто2. Такой подход идеален, когда строится расширенная аналитика по основным средствам. Если на счете нет нужных видов субконто, поле вернет NULL.

Способ 2: Использование конструкции ВЫБОР КОГДА и оператора ССЫЛКА

Если по каким-то причинам использование параметров виртуальной таблицы невозможно или неудобно, можно воспользоваться ручной проверкой типов. Выясним причину популярности этого метода: он нагляден и позволяет гибко обрабатывать исключения, что актуально для таких задач, как автоматическое заполнение инвентаризации ОС.

Посмотрим на пример запроса, где мы проверяем тип значения в первом субконто. Для отладки таких конструкций пригодится консоль запросов УФ 8.3. Если там находятся «Склады», мы берем значение из второго субконто:


ВЫБРАТЬ
    ВЫБОР
        КОГДА ХозрасчетныйОстатки.Субконто1 ССЫЛКА Справочник.Склады
            ТОГДА ХозрасчетныйОстатки.Субконто2
        ИНАЧЕ ХозрасчетныйОстатки.Субконто1
    КОНЕЦ КАК Инвестиция,
    ХозрасчетныйОстатки.СуммаОстатокДт КАК Сумма
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет В ИЕРАРХИИ(&Счета), , ) КАК ХозрасчетныйОстатки

Важный нюанс: при таком подходе часто возникает проблема дублирования строк. Это происходит из-за того, что виртуальная таблица без фильтра по видам субконто разворачивает данные по всей доступной аналитике счета. Если на счете три субконто, а вы выбираете через ВЫБОР только одно, 1С выдаст столько строк, сколько уникальных комбинаций всех трех субконто существует в базе.

Для решения проблемы дублей всегда используйте СГРУППИРОВАТЬ ПО. Это позволит корректно свернуть данные и просуммировать ресурсы (сумму, количество).

Способ 3: Объединение запросов (ОБЪЕДИНИТЬ ВСЕ)

Рассмотрим ситуацию, когда необходимо максимально четко разделить логику получения данных для разных типов счетов. Мы можем создать несколько запросов, в каждом из которых будет жесткое условие на тип субконто, и объединить их результаты.


ВЫБРАТЬ
    ХозрасчетныйОстатки.Субконто1 КАК Объект,
    ХозрасчетныйОстатки.СуммаОстаток КАК Сумма
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, , , Субконто1 ССЫЛКА Справочник.ОсновныеСредства) КАК ХозрасчетныйОстатки

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ХозрасчетныйОстатки.Субконто2 КАК Объект,
    ХозрасчетныйОстатки.СуммаОстаток КАК Сумма
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, , , Субконто2 ССЫЛКА Справочник.ОсновныеСредства) КАК ХозрасчетныйОстатки

Этот метод гарантирует, что мы не пропустим данные, даже если ОС на одном счете стоит первым, а на другом — вторым субконто. Однако помните о производительности: каждое ОБЪЕДИНИТЬ — это фактически отдельное обращение к базе данных. Старайтесь ограничивать выборку счетами через параметр Счет.

Рекомендации по оптимизации

Проанализируем несколько технических моментов, которые помогут сделать ваши запросы быстрее:

  1. Оператор ССЫЛКА против ТИПЗНАЧЕНИЯ: Всегда отдавайте предпочтение оператору ССЫЛКА. Он работает на уровне СУБД значительно быстрее, так как проверяет только идентификатор таблицы, в то время как ТИПЗНАЧЕНИЯ требует получения метаданных типа.
  2. Функция ВЫРАЗИТЬ: Если ваше субконто имеет составной тип, используйте ВЫРАЗИТЬ(Субконто1 КАК Справочник.ОсновныеСредства). Это помогает системе оптимизировать количество соединений с таблицами в SQL-запросе, исключая лишние проверки типов, которые не входят в ВЫРАЗИТЬ.
  3. Фильтрация в параметрах виртуальной таблицы: Старайтесь накладывать условия (например, проверку типа) непосредственно в параметрах виртуальной таблицы, а не в секции ГДЕ. Это позволяет платформе отсечь ненужные данные на раннем этапе формирования выборки.
  4. Группировка: Помните, что использование ВЫБРАТЬ РАЗЛИЧНЫЕ только убирает визуальные дубли, но не позволяет корректно работать с суммами. Используйте СГРУППИРОВАТЬ ПО для всех полей аналитики и агрегатные функции (СУММА) для ресурсов.

Таким образом, самым надежным и профессиональным способом является передача массива ВидыСубконто в параметры виртуальной таблицы. Это избавляет от необходимости писать сложные условия ВЫБОР КОГДА и обеспечивает максимальное быстродействие отчета или обработки.

← На главную