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