При работе в системе 1С:Управление холдингом (УХ) специалисты часто сталкиваются с необходимостью динамического расчета показателей в экземплярах отчетов. Одним из наиболее гибких инструментов для этого являются операнды типа «Запрос». Однако при их настройке может возникнуть специфическая ошибка: система отказывается выполнять арифметические операции, выдавая сообщение о попытке деления числа на дату (например, на дата(1,1,1)). Давайте подробно разберем, почему это происходит и как правильно сконфигурировать запрос, чтобы избежать подобных коллизий.
Рассмотрим стандартную ситуацию: нам необходимо рассчитать показатель, который зависит от количества дней в выбранном периоде. Программист пишет запрос к справочнику Периоды или использует системные даты, чтобы вычислить разницу. Ошибка Результат = ... / дата(1,1,1) в контексте 1С:УХ чаще всего сигнализирует не о логической ошибке в формуле, а о конфликте имен в метаданных операнда.
Выясним причину: когда движок вычисления формул 1С:УХ обрабатывает операнд-запрос, он сопоставляет параметры запроса (например, &ДатаОкончания) и выбранные поля. Если имя результирующего поля (алиас после слова КАК) совпадает с именем любого параметра, система может подставить в формулу значение параметра (тип Дата) вместо вычисленного числового значения. В итоге вместо числа 30 или 31 в знаменатель попадает значение 01.01.0001, что и вызывает исключение.
Самый простой и эффективный способ решить проблему — переименовать выходное поле в запросе так, чтобы оно было уникальным и не пересекалось с именами используемых параметров. Проанализируем пример кода, который вызывает ошибку:
ВЫБРАТЬ
(ДЕНЬ(Периоды.ДатаОкончания) - ДЕНЬ(Периоды.ДатаНачала)) / 86400 КАК ДатаОкончания
ИЗ
Справочник.Периоды КАК Периоды
ГДЕ
Периоды.ДатаНачала = &ДатаНачала
И Периоды.ДатаОкончания = &ДатаОкончания
В данном примере поле называется так же, как параметр &ДатаОкончания. Чтобы исправить ситуацию, переименуем поле в КоличествоДней. Также воспользуемся более надежной функцией для расчета разницы дат.
ВЫБРАТЬ
РАЗНОСТЬДАТ(&ДатаНачала, &ДатаОкончания, ДЕНЬ) КАК КоличествоДней
Теперь в формуле операнда необходимо будет обращаться именно к полю КоличествоДней. Это гарантирует, что система получит тип Число.
Разберем подробнее, как лучше всего получать количество дней. Использование разности дней между началом и концом месяца иногда может давать погрешность в 1 день (в зависимости от того, включены ли границы). Рассмотрим наиболее универсальный способ получения количества дней в периоде текущего отчета:
ВЫБРАТЬ
РАЗНОСТЬДАТ(&ДатаНачала, ДОБАВИТЬКДАТЕ(&ДатаОкончания, СЕКУНДА, 1), ДЕНЬ) КАК ДнейВПериоде
Этот метод хорош тем, что он корректно обрабатывает временные границы. Если ваша задача — получить именно количество дней в месяце, к которому относится дата отчета, можно использовать конструкцию без обращения к физическим таблицам справочников:
ВЫБРАТЬ
ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) КАК ДнейВМесяце
Это выражение всегда вернет число (28, 29, 30 или 31), и оно максимально производительно, так как не обращается к базе данных.
Еще одна причина появления дата(1,1,1) в расчетах — это пустой результат запроса. Если запрос по заданным условиям ГДЕ не нашел ни одной строки, операнд может вернуть NULL или неопределенное значение, которое при попытке приведения к типу в формуле превращается в пустую дату. Чтобы обезопасить расчеты, проанализируем ситуацию и добавим агрегатную функцию и ЕСТЬNULL.
Посмотрим на пример защищенного запроса:
ВЫБРАТЬ
ЕСТЬNULL(МАКСИМУМ(РАЗНОСТЬДАТ(&ДатаНачала, &ДатаОкончания, ДЕНЬ)), 0) КАК РезультатЧислом
Почему это важно:
МАКСИМУМ гарантирует, что запрос вернет ровно одну строку (скалярный результат), даже если исходная таблица пуста.ЕСТЬNULL заменит отсутствие данных на 0 (или 1, если вы планируете использовать это число в качестве делителя, чтобы избежать ошибки деления на ноль).Помимо написания кода запроса, обратим внимание на настройки самого операнда в системе Управление холдингом:
&ДатаНачала и &ДатаОкончания заполняются из реквизитов периода отчета или соответствующих переменных контекста.?(ОперандДней = 0, 0, Сумма / ОперандДней).Соблюдение этих правил — уникальные имена полей, использование РАЗНОСТЬДАТ и обязательная обработка NULL — позволит вам создавать отказоустойчивые отчеты в 1С:УХ без ошибок приведения типов.