При работе с регистрами бухгалтерии в 1С:Предприятие 8 программисты часто сталкиваются с ситуацией, когда порядок субконто в результатах запроса непредсказуем. Это происходит потому, что по умолчанию Субконто1, Субконто2 и Субконто3 соответствуют порядку, заданному в Плане счетов для конкретного счета. Если в запросе участвуют несколько счетов с разным набором или порядком аналитики, данные в колонках перемешиваются, что делает невозможным построение адекватных отчетов. В этой статье мы разберем, как жестко зафиксировать порядок видов субконто.
Рассмотрим ситуацию: нам необходимо получить обороты по счету, где первой аналитикой всегда должен выступать "Контрагент", а второй — "Договор". Если мы просто обратимся к виртуальной таблице Обороты, платформа вернет данные в том порядке, который указан в предопределенных настройках счета. Если на одном счете первым идет "Номенклатура", а на другом "Контрагент", программная обработка такого результата станет кошмаром.
Для решения этой задачи в виртуальных таблицах регистров бухгалтерии (Остатки, Обороты, ОстаткиИОбороты) предусмотрен специальный параметр. Проанализируем структуру параметров таблицы Обороты:
Пятый параметр виртуальной таблицы принимает массив значений типа ПланВидовХарактеристикСсылка.ВидыСубконтоХозрасчетные. Передавая этот массив, мы выполняем так называемый "маппинг":
Субконто1 в запросе.Субконто2.Субконто3.Важно понимать: если на конкретном счете нет вида субконто, указанного в массиве, запрос не выдаст ошибку. Вместо этого в соответствующей колонке СубконтоN для этого счета просто будет стоять значение NULL.
Разберем по шагам, как правильно подготовить массив и передать его в запрос. Рассмотрим пример, где мы хотим получить данные в строгом порядке: Контрагенты, затем Договоры.
// 1. Создаем массив нужных видов субконто в требуемом порядке
МассивСубконто = Новый Массив;
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры);
// 2. Формируем текст запроса
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ХозрасчетныйОбороты.Счет КАК Счет,
| ХозрасчетныйОбороты.Субконто1 КАК Контрагент,
| ХозрасчетныйОбороты.Субконто2 КАК Договор,
| ХозрасчетныйОбороты.СуммаОборот КАК Сумма
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Обороты(
| &НачалоПериода,
| &КонецПериода,
| ,
| Счет = &ВыбСчет,
| &ВидыСубконто, // Пятый параметр: здесь задается порядок
| ,
| ,
| ) КАК ХозрасчетныйОбороты";
// 3. Устанавливаем параметры запроса
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("ВыбСчет", ПланыСчетов.Хозрасчетный.РасчетыСПоставщиками);
Запрос.УстановитьПараметр("ВидыСубконто", МассивСубконто);
РезультатЗапроса = Запрос.Выполнить();
Выясним причину частой ошибки начинающих разработчиков: путаница между пятым и шестым параметрами.
Параметр №5 (Субконто) определяет структуру колонок. Он говорит платформе: "В колонку Субконто1 положи значения Контрагентов". Но он НЕ фильтрует выборку по конкретным контрагентам.
Параметр №6 (Условие) определяет состав данных. Именно здесь нужно писать условия вида Субконто1 = &НужныйКонтрагент.
Проанализируем ситуацию из сообщения форума, где у автора "ничего не показывает". Это происходит из-за того, что если вы передали массив из двух элементов в 5-й параметр, а в 6-м параметре пытаетесь наложить условие на Субконто3, или если вы накладываете условие на Субконто1, не определив его тип в 5-м параметре, результат может быть непредсказуемым или пустым из-за несовпадения типов.
Использование параметра ВидыСубконто — это не только вопрос удобства, но и важный метод оптимизации SQL-запроса. Рассмотрим, что происходит "под капотом":
Если вы разрабатываете отчет в Системе компоновки данных, механизм может работать немного иначе. СКД умеет автоматически подставлять массив видов субконто, если вы используете стандартные поля. Однако при написании сложных выражений в схеме компоновки или при программном формировании настроек, рекомендуется явно инициализировать этот параметр. В СКД это делается через вкладку "Параметры", где для параметра ВидыСубконто можно указать список значений прямо в конструкторе или заполнить его программно в модуле объекта отчета.
Посмотрим, как это сделать программно перед компоновкой:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// Получаем параметр из схемы
ПараметрВидыСубконто = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ВидыСубконто");
Если ПараметрВидыСубконто <> Неопределено Тогда
МассивВидов = Новый Массив;
МассивВидов.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.СтатьиЗатрат);
ПараметрВидыСубконто.Значение = МассивВидов;
ПараметрВидыСубконто.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Для надежной работы с бухгалтерскими итогами всегда придерживайтесь правила: если вам важно, что именно находится в полях Субконто1, Субконто2, обязательно передавайте массив видов субконто в запрос. Это гарантирует типизацию данных, упрощает дальнейшую группировку в Итогах запроса и значительно ускоряет выполнение кода на больших базах данных.