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

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

При работе с регистрами бухгалтерии в 1С:Предприятие 8 программисты часто сталкиваются с ситуацией, когда порядок субконто в результатах запроса непредсказуем. Это происходит потому, что по умолчанию Субконто1, Субконто2 и Субконто3 соответствуют порядку, заданному в Плане счетов для конкретного счета. Если в запросе участвуют несколько счетов с разным набором или порядком аналитики, данные в колонках перемешиваются, что делает невозможным построение адекватных отчетов. В этой статье мы разберем, как жестко зафиксировать порядок видов субконто.

Постановка задачи и анализ проблемы

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

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

  1. Начало периода
  2. Конец периода
  3. Периодичность
  4. Условие (фильтр по счету и др.)
  5. Субконто (Виды субконто) — именно этот параметр нас интересует
  6. Условие по субконто
  7. Организация
  8. Сценарий (для некоторых конфигураций)

Механизм сопоставления (Маппинг) через пятый параметр

Пятый параметр виртуальной таблицы принимает массив значений типа ПланВидовХарактеристикСсылка.ВидыСубконтоХозрасчетные. Передавая этот массив, мы выполняем так называемый "маппинг":

Важно понимать: если на конкретном счете нет вида субконто, указанного в массиве, запрос не выдаст ошибку. Вместо этого в соответствующей колонке СубконтоN для этого счета просто будет стоять значение NULL.

Реализация решения в коде

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


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

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

// 3. Устанавливаем параметры запроса
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("ВыбСчет", ПланыСчетов.Хозрасчетный.РасчетыСПоставщиками);
Запрос.УстановитьПараметр("ВидыСубконто", МассивСубконто);

РезультатЗапроса = Запрос.Выполнить();

Разница между фильтрацией и определением порядка

Выясним причину частой ошибки начинающих разработчиков: путаница между пятым и шестым параметрами.

Параметр №5 (Субконто) определяет структуру колонок. Он говорит платформе: "В колонку Субконто1 положи значения Контрагентов". Но он НЕ фильтрует выборку по конкретным контрагентам.

Параметр №6 (Условие) определяет состав данных. Именно здесь нужно писать условия вида Субконто1 = &НужныйКонтрагент.

Проанализируем ситуацию из сообщения форума, где у автора "ничего не показывает". Это происходит из-за того, что если вы передали массив из двух элементов в 5-й параметр, а в 6-м параметре пытаетесь наложить условие на Субконто3, или если вы накладываете условие на Субконто1, не определив его тип в 5-м параметре, результат может быть непредсказуемым или пустым из-за несовпадения типов.

Оптимизация производительности

Использование параметра ВидыСубконто — это не только вопрос удобства, но и важный метод оптимизации SQL-запроса. Рассмотрим, что происходит "под капотом":

  1. Упрощение JOIN: Когда виды субконто указаны явно, платформе не нужно динамически определять типы из метаданных Плана счетов для каждой записи.
  2. Сужение выборки: Платформа обращается только к тем таблицам субконто, которые указаны в массиве, игнорируя лишнюю аналитику, которая может быть привязана к счету, но не нужна в отчете.
  3. Индексация: Запросы с фиксированными видами субконто лучше используют индексы физических таблиц итогов.

Особенности работы в СКД

Если вы разрабатываете отчет в Системе компоновки данных, механизм может работать немного иначе. СКД умеет автоматически подставлять массив видов субконто, если вы используете стандартные поля. Однако при написании сложных выражений в схеме компоновки или при программном формировании настроек, рекомендуется явно инициализировать этот параметр. В СКД это делается через вкладку "Параметры", где для параметра ВидыСубконто можно указать список значений прямо в конструкторе или заполнить его программно в модуле объекта отчета.

Посмотрим, как это сделать программно перед компоновкой:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Получаем параметр из схемы
    ПараметрВидыСубконто = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ВидыСубконто");
    
    Если ПараметрВидыСубконто <> Неопределено Тогда
        МассивВидов = Новый Массив;
        МассивВидов.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.СтатьиЗатрат);
        ПараметрВидыСубконто.Значение = МассивВидов;
        ПараметрВидыСубконто.Использование = Истина;
    КонецЕсли;
    
КонецПроцедуры

Подведение итогов

Для надежной работы с бухгалтерскими итогами всегда придерживайтесь правила: если вам важно, что именно находится в полях Субконто1, Субконто2, обязательно передавайте массив видов субконто в запрос. Это гарантирует типизацию данных, упрощает дальнейшую группировку в Итогах запроса и значительно ускоряет выполнение кода на больших базах данных.

← На главную