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