Как исправить ошибку деления на дату в операндах запросов 1С:Управление холдингом?

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

При работе в системе 1С:Управление холдингом (УХ) специалисты часто сталкиваются с необходимостью динамического расчета показателей в экземплярах отчетов. Одним из наиболее гибких инструментов для этого являются операнды типа «Запрос». Однако при их настройке может возникнуть специфическая ошибка: система отказывается выполнять арифметические операции, выдавая сообщение о попытке деления числа на дату (например, на дата(1,1,1)). Давайте подробно разберем, почему это происходит и как правильно сконфигурировать запрос, чтобы избежать подобных коллизий.

Анализируем причину возникновения ошибки

Рассмотрим стандартную ситуацию: нам необходимо рассчитать показатель, который зависит от количества дней в выбранном периоде. Программист пишет запрос к справочнику Периоды или использует системные даты, чтобы вычислить разницу. Ошибка Результат = ... / дата(1,1,1) в контексте 1С:УХ чаще всего сигнализирует не о логической ошибке в формуле, а о конфликте имен в метаданных операнда.

Выясним причину: когда движок вычисления формул 1С:УХ обрабатывает операнд-запрос, он сопоставляет параметры запроса (например, &ДатаОкончания) и выбранные поля. Если имя результирующего поля (алиас после слова КАК) совпадает с именем любого параметра, система может подставить в формулу значение параметра (тип Дата) вместо вычисленного числового значения. В итоге вместо числа 30 или 31 в знаменатель попадает значение 01.01.0001, что и вызывает исключение.

Решение №1: Устранение конфликта имен (Alias)

Самый простой и эффективный способ решить проблему — переименовать выходное поле в запросе так, чтобы оно было уникальным и не пересекалось с именами используемых параметров. Проанализируем пример кода, который вызывает ошибку:


ВЫБРАТЬ
    (ДЕНЬ(Периоды.ДатаОкончания) - ДЕНЬ(Периоды.ДатаНачала)) / 86400 КАК ДатаОкончания
ИЗ
    Справочник.Периоды КАК Периоды
ГДЕ
    Периоды.ДатаНачала = &ДатаНачала
    И Периоды.ДатаОкончания = &ДатаОкончания

В данном примере поле называется так же, как параметр &ДатаОкончания. Чтобы исправить ситуацию, переименуем поле в КоличествоДней. Также воспользуемся более надежной функцией для расчета разницы дат.


ВЫБРАТЬ
    РАЗНОСТЬДАТ(&ДатаНачала, &ДатаОкончания, ДЕНЬ) КАК КоличествоДней

Теперь в формуле операнда необходимо будет обращаться именно к полю КоличествоДней. Это гарантирует, что система получит тип Число.

Решение №2: Правильное вычисление дней в месяце через РАЗНОСТЬДАТ

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


ВЫБРАТЬ
    РАЗНОСТЬДАТ(&ДатаНачала, ДОБАВИТЬКДАТЕ(&ДатаОкончания, СЕКУНДА, 1), ДЕНЬ) КАК ДнейВПериоде

Этот метод хорош тем, что он корректно обрабатывает временные границы. Если ваша задача — получить именно количество дней в месяце, к которому относится дата отчета, можно использовать конструкцию без обращения к физическим таблицам справочников:


ВЫБРАТЬ
    ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) КАК ДнейВМесяце

Это выражение всегда вернет число (28, 29, 30 или 31), и оно максимально производительно, так как не обращается к базе данных.

Решение №3: Обработка пустых значений и NULL

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

Посмотрим на пример защищенного запроса:


ВЫБРАТЬ
    ЕСТЬNULL(МАКСИМУМ(РАЗНОСТЬДАТ(&ДатаНачала, &ДатаОкончания, ДЕНЬ)), 0) КАК РезультатЧислом

Почему это важно:

  1. Функция МАКСИМУМ гарантирует, что запрос вернет ровно одну строку (скалярный результат), даже если исходная таблица пуста.
  2. Функция ЕСТЬNULL заменит отсутствие данных на 0 (или 1, если вы планируете использовать это число в качестве делителя, чтобы избежать ошибки деления на ноль).

Рекомендации по настройке операнда в интерфейсе 1С:УХ

Помимо написания кода запроса, обратим внимание на настройки самого операнда в системе Управление холдингом:

Соблюдение этих правил — уникальные имена полей, использование РАЗНОСТЬДАТ и обязательная обработка NULL — позволит вам создавать отказоустойчивые отчеты в 1С:УХ без ошибок приведения типов.

← На главную