Как исправить синтаксическую ошибку в функции РАЗНОСТЬДАТ в вычисляемых полях СКД

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

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

Проанализируем исходную проблему: автор пытается использовать конструкцию ВЫБОР, внутри которой вызывается функция РАЗНОСТЬДАТ. Основные сложности возникают из-за различий в синтаксисе языка запросов и языка выражений СКД, а также из-за правил оформления логических блоков.

Ошибка 1: Незавершенная конструкция ВЫБОР

В первом сообщении темы мы видим следующий код:


ВЫБОР КОГДА Субконто2.СрокОплаты < РАЗНОСТЬДАТ(&ДатаНачала, &ДатаОкончания, "ДЕНЬ") ТОГДА
КОНЕЦ

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

Правильная структура должна выглядеть так:


ВЫБОР 
    КОГДА Субконто2.СрокОплаты < РАЗНОСТЬДАТ(&ДатаНачала, &ДатаОкончания, "ДЕНЬ") 
        ТОГДА "Просрочено"
    ИНАЧЕ "В сроке"
КОНЕЦ

Ошибка 2: Кавычки в параметрах интервала

Выясним причину споров вокруг использования кавычек в параметре "ДЕНЬ". Здесь кроется главное различие между обычным запросом и вычисляемым полем СКД:

  1. В языке запросов тип интервала пишется как зарезервированное слово без кавычек: РАЗНОСТЬДАТ(&Дата1, &Дата2, ДЕНЬ).
  2. В вычисляемых полях СКД (на закладке "Вычисляемые поля") этот параметр является строкой, поэтому кавычки обязательны: РАЗНОСТЬДАТ(&Дата1, &Дата2, "ДЕНЬ").

Если вы уберете кавычки в вычисляемом поле, система попытается найти поле набора данных с именем ДЕНЬ, не обнаружит его и выдаст ошибку "Поле не найдено".

Типизация параметров и обработка NULL

Рассмотрим подробнее работу с параметрами &ДатаНачала и &ДатаОкончания. Функция РАЗНОСТЬДАТ ожидает на вход значения типа Дата. Если один из параметров не будет заполнен (примет значение NULL), вычисление может завершиться с ошибкой или вернуть пустой результат.

Для обеспечения стабильности работы отчета рекомендуется использовать функцию ЕСТЬNULL. Посмотрим на пример безопасного вычисления:


РАЗНОСТЬДАТ(ЕСТЬNULL(&ДатаНачала, ДАТАВРЕМЯ(1, 1, 1)), ЕСТЬNULL(&ДатаОкончания, ДАТАВРЕМЯ(1, 1, 1)), "ДЕНЬ")

Также важно помнить, что поле Субконто2.СрокОплаты должно иметь числовой тип данных. Если это поле неопределенного типа (например, характеристика), необходимо убедиться, что в запросе-источнике типы субконто определены верно, иначе сравнение "Число < РезультатФункции" может не сработать.

Альтернативный способ расчета разности дат

Проанализируем ситуацию, когда стандартная функция РАЗНОСТЬДАТ по каким-то причинам не подходит. В языке выражений СКД доступна прямая арифметика дат. При вычитании одной даты из другой результат получается в секундах. Чтобы перевести его в дни, достаточно выполнить деление.

Рассмотрим пример:

(&ДатаОкончания - &ДатаНачала) / 86400

Где 86 400 — это количество секунд в сутках (24 * 60 * 60). Этот метод иногда оказывается более гибким, так как позволяет получать дробные значения дней, если время в датах имеет значение.

Использование общих модулей для сложных расчетов

Если ваше условие в ВЫБОР становится слишком громоздким, рекомендуется вынести логику в общий модуль. Это значительно упростит отладку и чтение схемы компоновки данных.

Посмотрим, как это реализовать:

  1. Создайте в конфигураторе общий модуль (например, МойМодуль) с установленными флажками "Сервер", "Внешнее соединение" и "Вызов сервера".
  2. Напишите функцию:
    
    Функция РассчитатьПревышениеСрока(СрокОплаты, Дата1, Дата2) Экспорт
        Разность = (Дата2 - Дата1) / 86400;
        Если СрокОплаты < Разность Тогда
            Возврат Истина;
        КонецЕсли;
        Возврат Ложь;
    КонецФункции
    
  3. В вычисляемом поле СКД вызовите эту функцию: МойМодуль.РассчитатьПревышениеСрока(Субконто2.СрокОплаты, &ДатаНачала, &ДатаОкончания)

Важный момент: использование функций общих модулей в СКД может замедлить формирование отчета на больших объемах данных, так как функция будет вызываться для каждой строки результата. Используйте этот метод осознанно.

Подведем итоги

Для исправления ошибки из сообщения автора необходимо:

Соблюдение этих правил позволит вам создавать сложные и отказоустойчивые отчеты в системе компоновки данных 1С.

← На главную