При работе с регистрами бухгалтерии в 1С разработчики часто сталкиваются с ситуацией, когда одна и та же сущность (например, «Основные средства» или «Номенклатура») на разных счетах учета находится на разных позициях субконто — для автоматизации этой работы полезна обработка автоматического переноса и корректировки остатков по субконто. На счете 01 ОС может быть первым субконто, а на другом счете — вторым или третьим, уступая место «Местам хранения». Рассмотрим способы, которые позволяют универсально извлекать нужные данные вне зависимости от их порядкового номера на конкретном счете.
Это наиболее правильный и производительный метод с точки зрения платформы 1С. Рассмотрим механизм подстановки: когда мы передаем массив конкретных видов субконто в параметры виртуальной таблицы (например, Остатки или ОстаткиИОбороты), система выполняет автоматическое переназначение индексов.
Проанализируем ситуацию: если мы передадим в параметр &ВидыСубконто массив, содержащий только ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ОсновныеСредства, то в теле запроса поле Субконто1 будет всегда содержать ссылку на ОС. Проверить результат можно через консоль запросов для управляемых форм — для этого подойдёт универсальная консоль запросов и компоновки данных для управляемых форм. Разберем по шагам, как это реализовать в коде:
// Формируем массив нужных видов субконто
ВидыСубконто = Новый Массив;
ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ОсновныеСредства);
ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.НематериальныеАктивы);
ВидыСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ХозрасчетныйОстатки.Субконто1 КАК ОбъектУчета,
| ХозрасчетныйОстатки.СуммаОстаток КАК Остаток
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет В ИЕРАРХИИ(&СчетаОС), &ВидыСубконто) КАК ХозрасчетныйОстатки";
Запрос.УстановитьПараметр("ВидыСубконто", ВидыСубконто);
Запрос.УстановитьПараметр("Период", ДатаОстатков);
Запрос.УстановитьПараметр("СчетаОС", СписокСчетов);
Важно понимать: порядок элементов в массиве &ВидыСубконто строго определяет, что попадет в Субконто1 и Субконто2. Такой подход идеален, когда строится расширенная аналитика по основным средствам. Если на счете нет нужных видов субконто, поле вернет NULL.
Если по каким-то причинам использование параметров виртуальной таблицы невозможно или неудобно, можно воспользоваться ручной проверкой типов. Выясним причину популярности этого метода: он нагляден и позволяет гибко обрабатывать исключения, что актуально для таких задач, как автоматическое заполнение инвентаризации ОС.
Посмотрим на пример запроса, где мы проверяем тип значения в первом субконто. Для отладки таких конструкций пригодится консоль запросов УФ 8.3. Если там находятся «Склады», мы берем значение из второго субконто:
ВЫБРАТЬ
ВЫБОР
КОГДА ХозрасчетныйОстатки.Субконто1 ССЫЛКА Справочник.Склады
ТОГДА ХозрасчетныйОстатки.Субконто2
ИНАЧЕ ХозрасчетныйОстатки.Субконто1
КОНЕЦ КАК Инвестиция,
ХозрасчетныйОстатки.СуммаОстатокДт КАК Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет В ИЕРАРХИИ(&Счета), , ) КАК ХозрасчетныйОстатки
Важный нюанс: при таком подходе часто возникает проблема дублирования строк. Это происходит из-за того, что виртуальная таблица без фильтра по видам субконто разворачивает данные по всей доступной аналитике счета. Если на счете три субконто, а вы выбираете через ВЫБОР только одно, 1С выдаст столько строк, сколько уникальных комбинаций всех трех субконто существует в базе.
Для решения проблемы дублей всегда используйте СГРУППИРОВАТЬ ПО. Это позволит корректно свернуть данные и просуммировать ресурсы (сумму, количество).
Рассмотрим ситуацию, когда необходимо максимально четко разделить логику получения данных для разных типов счетов. Мы можем создать несколько запросов, в каждом из которых будет жесткое условие на тип субконто, и объединить их результаты.
ВЫБРАТЬ
ХозрасчетныйОстатки.Субконто1 КАК Объект,
ХозрасчетныйОстатки.СуммаОстаток КАК Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, , , Субконто1 ССЫЛКА Справочник.ОсновныеСредства) КАК ХозрасчетныйОстатки
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ХозрасчетныйОстатки.Субконто2 КАК Объект,
ХозрасчетныйОстатки.СуммаОстаток КАК Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, , , Субконто2 ССЫЛКА Справочник.ОсновныеСредства) КАК ХозрасчетныйОстатки
Этот метод гарантирует, что мы не пропустим данные, даже если ОС на одном счете стоит первым, а на другом — вторым субконто. Однако помните о производительности: каждое ОБЪЕДИНИТЬ — это фактически отдельное обращение к базе данных. Старайтесь ограничивать выборку счетами через параметр Счет.
Проанализируем несколько технических моментов, которые помогут сделать ваши запросы быстрее:
ССЫЛКА. Он работает на уровне СУБД значительно быстрее, так как проверяет только идентификатор таблицы, в то время как ТИПЗНАЧЕНИЯ требует получения метаданных типа.ВЫРАЗИТЬ(Субконто1 КАК Справочник.ОсновныеСредства). Это помогает системе оптимизировать количество соединений с таблицами в SQL-запросе, исключая лишние проверки типов, которые не входят в ВЫРАЗИТЬ.ГДЕ. Это позволяет платформе отсечь ненужные данные на раннем этапе формирования выборки.ВЫБРАТЬ РАЗЛИЧНЫЕ только убирает визуальные дубли, но не позволяет корректно работать с суммами. Используйте СГРУППИРОВАТЬ ПО для всех полей аналитики и агрегатные функции (СУММА) для ресурсов.Таким образом, самым надежным и профессиональным способом является передача массива ВидыСубконто в параметры виртуальной таблицы. Это избавляет от необходимости писать сложные условия ВЫБОР КОГДА и обеспечивает максимальное быстродействие отчета или обработки.