При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются со следующей проблемой: создав одно вычисляемое поле, хочется использовать его готовый результат в формуле другого вычисляемого поля. Однако при попытке указать имя первого поля в выражении второго система выдает синтаксическую ошибку.
Давайте разберем, почему возникает это ограничение платформы 1С, и подробно проанализируем четыре эффективных практических метода, которые позволяют обойти эту проблему и построить сложные цепочки расчетов в отчетах.
В СКД расчет всех вычисляемых полей происходит на одном и том же этапе компоновки данных. Платформа рассчитывает их параллельно непосредственно перед выводом данных в результирующий документ. На этом этапе система еще "не знает" итогового значения первого поля, когда приступает к расчету второго. Из-за отсутствия строгой последовательности вычислений (расчета зависимостей) прямое использование одного вычисляемого поля в формуле другого заблокировано на уровне ядра платформы.
Тем не менее, решить эту задачу можно несколькими красивыми способами. Рассмотрим их по шагам.
Самый правильный и производительный подход с точки зрения оптимизации СУБД — перенести базовые математические или логические операции непосредственно в SQL-запрос набора данных. В этом случае результат первого вычисления станет доступен СКД как обычное поле набора данных, и мы сможем беспрепятственно использовать его в любых вычисляемых полях.
Давайте посмотрим на практический пример. Предположим, нам нужно рассчитать сумму продажи, а затем на ее основе вычислить сумму НДС и сумму со скидкой.
Вместо создания вычисляемого поля Сумма мы пишем расчет прямо в запросе СКД:
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот КАК Количество,
ПродажиОбороты.Цена КАК Цена,
ПродажиОбороты.КоличествоОборот * ПродажиОбороты.Цена КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
Теперь поле Сумма является полноценным полем набора данных. На вкладке «Вычисляемые поля» мы можем создать новое поле СуммаНДС и без каких-либо ошибок написать выражение:
Сумма * 0.20
Преимущества метода: Высокая скорость работы, чистота схемы компоновки данных, отсутствие дублирования кода.
Ограничения: Метод не сработает, если первичное выражение рассчитывается с использованием функций СКД (например, ВычислитьВыражение) или строится на данных из разных несвязанных наборов.
Если ваши вычисления достаточно просты или их невозможно перенести в запрос, наиболее быстрым решением «в лоб» будет подстановка выражения первого поля внутрь формулы второго поля.
Проанализируем ситуацию:
Поле1 с выражением: Цена * Количество.Поле2, которое должно умножать результат Поле1 на коэффициент скидки.Поле1 * Коэффициент в выражении для Поле2 мы пишем полную раскрытую формулу: (Цена * Количество) * Коэффициент.Преимущества метода: Простота реализации, не требует изменения структуры запросов или написания программного кода.
Недостатки: Дублирование логики. Если формула расчета первого поля изменится (например, добавятся налоги или дополнительные скидки), вам придется вручную искать и переписывать формулы во всех зависимых вычисляемых полях.
Малоизвестный, но крайне изящный способ обойти ограничение без дублирования формул — задействовать механизм Пользовательских полей на уровне настроек компоновки данных.
Дело в том, что ограничение на обращение к вычисляемым полям действует исключительно на вкладке «Вычисляемые поля» в схеме компоновки. Но в настройках варианта отчета платформа позволяет ссылаться на любые вычисляемые поля.
Разберем этот метод по шагам:
БазоваяСумма) с формулой расчета.[БазоваяСумма] * 0.18.Этот способ позволяет сохранить гибкость и избежать дублирования сложных формул непосредственно на уровне схемы.
Для реализации действительно сложных, многоступенчатых алгоритмов расчета лучше всего использовать вызовы функций из общих модулей конфигурации 1С. Этот метод незаменим, когда в расчетах задействованы условия, циклы или обращения к сторонним функциям системы.
Выполним следующую последовательность действий:
ОбщийМодульОтчетов). Обязательно установим для него свойства «Клиент (управляемое приложение)», «Сервер» и «Вызов сервера».
Функция РассчитатьИтоговуюСтоимость(Цена, Количество, ПроцентСкидки) Экспорт
ПервичнаяСумма = Цена * Количество;
РазмерСкидки = ПервичнаяСумма * (ПроцентСкидки / 100);
Возврат ПервичнаяСумма - РазмерСкидки;
КонецФункции
ОбщийМодульОтчетов.РассчитатьИтоговуюСтоимость(Цена, Количество, Скидка)
С помощью внешних функций можно реализовать даже самые сложные рекурсивные алгоритмы вычислений.
Мы рассмотрели все основные варианты обхода системного ограничения СКД. Выбор конкретного метода зависит от архитектуры вашего отчета: