При работе с Системой Компоновки Данных (СКД) в 1С мы часто сталкиваемся с необходимостью выполнения сложных вычислений, включающих условную логику. Одна из распространенных задач — это корректировка результата вычисления, если он оказывается отрицательным, путем замены его на другое, заранее определенное значение. Давайте рассмотрим такую ситуацию на примере.
Предположим, у нас есть поле в отчете СКД, назовем его условно "Руб.", которое рассчитывается по следующей формуле:
НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход
Автор темы столкнулся с проблемой, что поле "Руб." выдает некорректный результат, особенно когда итоговое значение становится отрицательным. Наша задача состоит в следующем: если рассчитанное значение поля "Руб." (которое в исходном запросе может быть связано с колонкой "КонОстаток") становится меньше нуля, то вместо этого отрицательного значения должно быть возвращено значение из поля НачОстаток. При этом, если результат расчета неотрицателен, мы должны использовать стандартную формулу.
Таким образом, мы имеем следующие компоненты:
НачОстаток, СуммаПриход, СуммаРасход, КонОстаток, которые доступны в наборе данных СКД.ПромежуточныйРасчет = ((НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход. Именно эта формула должна давать значение для поля "Руб.".КонОстаток (в соответствии с предоставленными данными поиска) становится меньше 0. Обратите внимание, что в исходном сообщении пользователь упомянул "Поле 'Руб.' меньше 0", но пример с числом 141 084,55 соответствует значению поля НачОстаток, а в предоставленной дополнительной информации в качестве условия фигурирует КонОстаток < 0. Мы будем использовать КонОстаток < 0 в качестве условия, а НачОстаток в качестве значения для замены, как это указано в расширенной формулировке задачи.НачОстаток.Для реализации подобной логики в СКД нам необходимо использовать конструкцию условного выражения ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ. Эта конструкция позволяет выполнить различные действия в зависимости от заданного условия. Мы можем добавить такое вычисляемое поле на вкладке "Вычисляемые поля" в схеме компоновки данных.
Применим эту конструкцию к нашей задаче. Сначала мы определим наш промежуточный расчет, а затем обернем его в условное выражение.
Рассмотрим подробнее шаги:
ВЫБОР КОГДА КонОстаток < 0
ТОГДА НачОстаток
ИНАЧЕ
((НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход
КОНЕЦ
В этом выражении мы сначала проверяем условие КонОстаток < 0. Если это условие истинно, то поле "РезультатРуб" примет значение из НачОстаток. В противном случае (блок ИНАЧЕ), будет выполнен наш основной расчет ((НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход, и его результат будет присвоен полю "РезультатРуб".
Важно: Убедитесь, что все поля, участвующие в выражении (КонОстаток, НачОстаток, СуммаПриход, СуммаРасход), доступны в выбранном наборе данных СКД. Если какого-то поля не хватает, его необходимо добавить в запрос или определить как параметр/вычисляемое поле, если это применимо.
Язык выражений СКД, хоть и похож на язык запросов, имеет свои особенности. Конструкция ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ является одной из базовых для реализации условной логики. Давайте разберем её структуру:
ВЫБОР
КОГДА [Условие1] ТОГДА [Значение1]
КОГДА [Условие2] ТОГДА [Значение2]
...
ИНАЧЕ [ЗначениеПоУмолчанию]
КОНЕЦ
Здесь:
ВЫБОР ... КОНЕЦ: Это ключевые слова, обрамляющие все условное выражение.КОГДА [Условие] ТОГДА [Значение]: Мы можем указать одно или несколько таких блоков. СКД последовательно проверяет каждое Условие. Как только находится первое истинное условие, возвращается соответствующее ему Значение, и дальнейшая проверка прекращается.ИНАЧЕ [ЗначениеПоУмолчанию]: Этот блок является необязательным. Если ни одно из условий КОГДА не оказалось истинным, то будет возвращено ЗначениеПоУмолчанию. Если блок ИНАЧЕ отсутствует и ни одно из условий не выполнилось, то будет возвращено значение NULL.В нашем случае, мы используем простейшую форму с одним условием КОГДА и одним блоком ИНАЧЕ.
В СКД также существует краткая форма записи условного выражения, аналогичная тернарному оператору во многих языках программирования. Эта форма использует символ вопросительного знака ? и имеет следующий синтаксис:
?(Условие, ЗначениеЕслиИстина, ЗначениеЕслиЛожь)
Используя этот оператор, наше выражение для поля "РезультатРуб" можно записать так (пример, аналогичный предложенному в сообщении 7):
?(КонОстаток < 0, НачОстаток, ((НачОстаток + СуммаПриход) * 70 / 100) - СуммаРасход)
Оба варианта — ВЫБОР КОГДА и ? — функционально эквивалентны для простых случаев и выбор между ними остается за вами, исходя из предпочтений читаемости кода.
Одним из частых источников ошибок при работе с вычислениями в 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), что предотвратит ошибки и обеспечит корректность расчетов в любых условиях.
Если после внедрения формулы вы по-прежнему сталкиваетесь с некорректными результатами, или вам необходимо понять, на каком этапе происходит отклонение, мы рекомендуем выполнить следующие шаги для отладки:
КОГДА.Такой пошаговый подход к отладке позволяет точно определить источник проблемы и оперативно внести необходимые корректировки.
В некоторых случаях, когда стандартных вычисляемых полей СКД и простых условных выражений может быть недостаточно (например, если нам нужно влиять на расчет итогов по группам или выполнять более сложные агрегации с учетом условий), мы можем рассмотреть следующие подходы:
ВычислитьВыражение(): Эта функция СКД позволяет вычислять выражение в контексте определенной группировки. Она полезна, когда логика зависит от итоговых значений или требуется более сложная агрегация. Например, ВычислитьВыражение("Сумма(Поле)", "Группировка", "Истина"). Однако для нашей текущей задачи она не является необходимой.ПриКомпоновкеРезультата модуля объекта отчета. Этот подход дает максимальную гибкость, но усложняет отчет, делает его менее настраиваемым пользователем и требует более глубоких знаний в программировании на 1С.Для нашей текущей задачи с условной заменой отрицательного значения, функционала вычисляемых полей и конструкции ВЫБОР КОГДА оказывается вполне достаточно, и использование более сложных механизмов не требуется.
Таким образом, мы успешно решили задачу по корректировке вычисляемого поля в СКД. Мы научились применять условные выражения ВЫБОР КОГДА (или его краткий аналог ?), учитывать особенности работы с NULL значениями с помощью функции ЕСТЬNULL и эффективно отлаживать сложные расчеты. Эти знания позволят нам создавать более гибкие и надежные отчеты в 1С.