Как исправить некорректный расчет в СКД, когда вычисляемое поле должно возвращать другое значение при отрицательном результате?

Программист 1С v8.3 (Управляемые формы) Управленческий учет
← На главную

При работе с Системой Компоновки Данных (СКД) в 1С мы часто сталкиваемся с необходимостью выполнения сложных вычислений, включающих условную логику. Одна из распространенных задач — это корректировка результата вычисления, если он оказывается отрицательным, путем замены его на другое, заранее определенное значение. Давайте рассмотрим такую ситуацию на примере.

1. Анализируем исходную задачу и формулу

Предположим, у нас есть поле в отчете СКД, назовем его условно "Руб.", которое рассчитывается по следующей формуле:


НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход

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

Таким образом, мы имеем следующие компоненты:

  1. Исходные данные: Поля НачОстаток, СуммаПриход, СуммаРасход, КонОстаток, которые доступны в наборе данных СКД.
  2. Базовая формула расчета: ПромежуточныйРасчет = ((НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход. Именно эта формула должна давать значение для поля "Руб.".
  3. Условие корректировки: Если значение поля КонОстаток (в соответствии с предоставленными данными поиска) становится меньше 0. Обратите внимание, что в исходном сообщении пользователь упомянул "Поле 'Руб.' меньше 0", но пример с числом 141 084,55 соответствует значению поля НачОстаток, а в предоставленной дополнительной информации в качестве условия фигурирует КонОстаток < 0. Мы будем использовать КонОстаток < 0 в качестве условия, а НачОстаток в качестве значения для замены, как это указано в расширенной формулировке задачи.
  4. Значение для замены при выполнении условия: НачОстаток.

2. Использование условных выражений в вычисляемых полях СКД

Для реализации подобной логики в СКД нам необходимо использовать конструкцию условного выражения ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ. Эта конструкция позволяет выполнить различные действия в зависимости от заданного условия. Мы можем добавить такое вычисляемое поле на вкладке "Вычисляемые поля" в схеме компоновки данных.

Применим эту конструкцию к нашей задаче. Сначала мы определим наш промежуточный расчет, а затем обернем его в условное выражение.

Рассмотрим подробнее шаги:

  1. Перейдите в режим редактирования схемы компоновки данных (СКД).
  2. На вкладке "Вычисляемые поля" добавьте новое поле. Назовите его, например, "РезультатРуб".
  3. В колонке "Выражение" для этого нового поля введите следующую формулу:

ВЫБОР КОГДА КонОстаток < 0
    ТОГДА НачОстаток
ИНАЧЕ
    ((НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход
КОНЕЦ

В этом выражении мы сначала проверяем условие КонОстаток < 0. Если это условие истинно, то поле "РезультатРуб" примет значение из НачОстаток. В противном случае (блок ИНАЧЕ), будет выполнен наш основной расчет ((НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход, и его результат будет присвоен полю "РезультатРуб".

Важно: Убедитесь, что все поля, участвующие в выражении (КонОстаток, НачОстаток, СуммаПриход, СуммаРасход), доступны в выбранном наборе данных СКД. Если какого-то поля не хватает, его необходимо добавить в запрос или определить как параметр/вычисляемое поле, если это применимо.

3. Разбираем синтаксис ВЫБОР КОГДА

Язык выражений СКД, хоть и похож на язык запросов, имеет свои особенности. Конструкция ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ является одной из базовых для реализации условной логики. Давайте разберем её структуру:


ВЫБОР
    КОГДА [Условие1] ТОГДА [Значение1]
    КОГДА [Условие2] ТОГДА [Значение2]
    ...
    ИНАЧЕ [ЗначениеПоУмолчанию]
КОНЕЦ

Здесь:

В нашем случае, мы используем простейшую форму с одним условием КОГДА и одним блоком ИНАЧЕ.

Альтернативный оператор ? (тернарный)

В СКД также существует краткая форма записи условного выражения, аналогичная тернарному оператору во многих языках программирования. Эта форма использует символ вопросительного знака ? и имеет следующий синтаксис:


?(Условие, ЗначениеЕслиИстина, ЗначениеЕслиЛожь)

Используя этот оператор, наше выражение для поля "РезультатРуб" можно записать так (пример, аналогичный предложенному в сообщении 7):


?(КонОстаток < 0, НачОстаток, ((НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход)

Оба варианта — ВЫБОР КОГДА и ? — функционально эквивалентны для простых случаев и выбор между ними остается за вами, исходя из предпочтений читаемости кода.

4. Предотвращаем проблемы с NULL значениями

Одним из частых источников ошибок при работе с вычислениями в 1С и СКД являются неопределенные значения (NULL). Если какое-либо из полей, используемых в нашей формуле (например, НачОстаток, СуммаПриход, СуммаРасход, КонОстаток), может содержать NULL, это может привести к непредсказуемым результатам или даже ошибкам в расчетах. Например, NULL + 10 или NULL < 0 часто возвращают NULL, что может нарушить логику нашего условного выражения.

Для решения этой проблемы рекомендуется использовать функцию ЕСТЬNULL(Поле, ЗначениеПоУмолчанию). Эта функция заменяет значение NULL на указанное ЗначениеПоУмолчанию (чаще всего 0) перед выполнением арифметических операций или сравнений.

Давайте применим ЕСТЬNULL к нашей формуле, чтобы сделать ее более надежной:


ВЫБОР КОГДА ЕСТЬNULL(КонОстаток, 0) < 0
    ТОГДА ЕСТЬNULL(НачОстаток, 0)
ИНАЧЕ
    ((ЕСТЬNULL(НачОстаток, 0) + ЕСТЬNULL(СуммаПриход, 0)) * 70 / 100) - ЕСТЬNULL(СуммаРасход, 0)
КОНЕЦ

В этом усовершенствованном выражении мы гарантируем, что все участвующие числовые поля будут иметь числовое значение (0, если исходное поле было NULL), что предотвратит ошибки и обеспечит корректность расчетов в любых условиях.

5. Отладка и проверка результатов

Если после внедрения формулы вы по-прежнему сталкиваетесь с некорректными результатами, или вам необходимо понять, на каком этапе происходит отклонение, мы рекомендуем выполнить следующие шаги для отладки:

  1. Выводите промежуточные значения: Добавьте в отчет СКД отдельные вычисляемые поля для каждого компонента вашей сложной формулы. Например, создайте поля "ПромежуточныйНачОстаток = ЕСТЬNULL(НачОстаток, 0)", "ПромежуточныйСуммаПриход = ЕСТЬNULL(СуммаПриход, 0)", "ПромежуточныйРасчет = ((НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход" (без условия). Выводя эти поля в отчет, мы сможем пошагово отследить значения и увидеть, какой именно компонент или часть выражения дает неожиданный результат.
  2. Проверяйте условия отдельно: Создайте отдельное вычисляемое поле, которое будет показывать результат условия, например, "УсловиеОтработало = КонОстаток < 0". Это поможет нам понять, правильно ли срабатывает логика КОГДА.
  3. Используйте консоль запросов/СКД: Если вы работаете с запросом в СКД, используйте консоль запросов или консоль СКД для тестирования частей выражения и проверки их поведения с различными исходными данными. Это позволит нам изолировать проблему от общего отчета.
  4. Сравнение с ожидаемым результатом: Для каждого проблемного случая вручную рассчитайте ожидаемый результат и сравните его с тем, что выдает отчет. Это поможет нам выявить конкретные строки или ситуации, где логика расходится с ожиданиями.

Такой пошаговый подход к отладке позволяет точно определить источник проблемы и оперативно внести необходимые корректировки.

6. Расширенные возможности (для сложных сценариев)

В некоторых случаях, когда стандартных вычисляемых полей СКД и простых условных выражений может быть недостаточно (например, если нам нужно влиять на расчет итогов по группам или выполнять более сложные агрегации с учетом условий), мы можем рассмотреть следующие подходы:

  1. Функция ВычислитьВыражение(): Эта функция СКД позволяет вычислять выражение в контексте определенной группировки. Она полезна, когда логика зависит от итоговых значений или требуется более сложная агрегация. Например, ВычислитьВыражение("Сумма(Поле)", "Группировка", "Истина"). Однако для нашей текущей задачи она не является необходимой.
  2. Модификация текста запроса программно: Для очень сложных и нестандартных сценариев, когда возможности СКД исчерпаны, мы можем программно изменить текст запроса в процедуре ПриКомпоновкеРезультата модуля объекта отчета. Этот подход дает максимальную гибкость, но усложняет отчет, делает его менее настраиваемым пользователем и требует более глубоких знаний в программировании на 1С.

Для нашей текущей задачи с условной заменой отрицательного значения, функционала вычисляемых полей и конструкции ВЫБОР КОГДА оказывается вполне достаточно, и использование более сложных механизмов не требуется.

Таким образом, мы успешно решили задачу по корректировке вычисляемого поля в СКД. Мы научились применять условные выражения ВЫБОР КОГДА (или его краткий аналог ?), учитывать особенности работы с NULL значениями с помощью функции ЕСТЬNULL и эффективно отлаживать сложные расчеты. Эти знания позволят нам создавать более гибкие и надежные отчеты в 1С.

← На главную