В разработке отчетов на Системе Компоновки Данных (СКД) часто встречается ситуация: мы создаем простой запрос для выборки данных за период, используем оператор МЕЖДУ, задаем параметры, но при формировании отчета получаем ошибку "Неверные параметры в операции сравнения. Нельзя сравнивать поля неограниченной длины и поля несовместимых типов". При этом мы абсолютно уверены, что и поле в базе данных, и параметры имеют тип "Дата". Если вы занимаетесь программным созданием схем, то избежать подобных ошибок в коде поможет СКДБилдер — специальный модуль-обёртка над объектной моделью, который делает работу с настройками более прозрачной.
Давайте разберемся, почему возникает эта, на первый взгляд, нелогичная ошибка и как правильно настроить отчет, чтобы сравнение дат работало корректно. Как правило, проблема кроется не в тексте запроса, а в настройках самой схемы компоновки данных.
Основная причина этой ошибки — несоответствие типов данных в момент выполнения запроса. Хотя мы можем видеть тип "Дата" в конфигураторе для поля таблицы и задать его для параметров в СКД, в сам запрос в итоге может передаваться значение совершенно другого типа или вообще ничего (NULL).
Проанализируем типичный запрос, который вызывает проблему:
ВЫБРАТЬ
События.Тема КАК ТемаСообщения,
События.НачалоСобытия КАК ДатаСМС
ИЗ
Документ.Событие КАК События
ГДЕ
События.НачалоСобытия МЕЖДУ &ДатаНачала И &ДатаКонца
Система сообщает об ошибке в строке ГДЕ, потому что один из трех операндов (События.НачалоСобытия, &ДатаНачала или &ДатаКонца) на самом деле не является датой. Чаще всего "виноваты" именно параметры &ДатаНачала и &ДатаКонца. Проблема возникает из-за некорректной настройки их получения из формы отчета.
Чтобы отчет заработал, нужно последовательно проверить и настроить всю цепочку: от типа данных в СКД до связи с элементами на форме. Рассмотрим этот процесс по шагам.
В первую очередь убедимся, что в самой схеме компоновки данных у параметров задан верный тип.
&ДатаНачала и &ДатаКонца.Дата.Важный момент: не путайте тип Дата со СтандартнымПериодом. СтандартныйПериод — это не дата, а комплексный объект, который содержит в себе и дату начала, и дату конца. Его нельзя напрямую сравнивать с полем типа Дата в запросе. Если вы по ошибке выберете этот тип, то гарантированно получите ошибку сравнения несовместимых типов.
Для того чтобы пользователь мог вводить даты начала и конца периода, нам нужны соответствующие поля на форме отчета. В управляемых формах это делается через создание реквизитов формы.
ДатаНачала и ДатаКонца.Дата.На этом этапе мы просто создали элементы управления, но они пока никак не связаны с нашим запросом. Для более гибкого управления процессом можно также использовать инструмент Пользовательская СКД, который расширяет возможности построения отчетов на стороне клиента.
Это самый важный и часто пропускаемый шаг. Система должна знать, откуда брать значения для параметров &ДатаНачала и &ДатаКонца в запросе. По умолчанию она этого не знает, и в запрос передаваются пустые значения, что и приводит к ошибке.
ДатаНачала и ДатаКонца).ДатаНачала.ДатаНачала (полный путь может выглядеть как Отчет.ДатаНачала или Объект.ДатаНачала). Выберите его.ДатаКонца, связав его с реквизитом формы ДатаКонца.Теперь при формировании отчета СКД возьмет значения из полей на форме и корректно передаст их в запрос. Ошибка сравнения типов должна исчезнуть. Если вместо нее появилась ошибка "Параметр не заполнен", это хороший знак — значит, связь установлена, но вы просто не ввели значения в поля на форме перед формированием отчета.
При использовании оператора МЕЖДУ есть одна тонкость. Если пользователь выберет в качестве &ДатаКонца, например, 20.10.2023, то по умолчанию время будет 00:00:00. В этом случае в отчет попадут только те документы, у которых время в поле НачалоСобытия равно 00:00:00 20-го октября. Все события, произошедшие в течение этого дня, будут проигнорированы.
Чтобы включить в выборку весь день до конца (до 23:59:59), рекомендуется использовать функцию КОНЕЦПЕРИОДА. Модифицируем наш запрос:
ВЫБРАТЬ
События.Тема КАК ТемаСообщения,
События.НачалоСобытия КАК ДатаСМС
ИЗ
Документ.Событие КАК События
ГДЕ
События.НачалоСобытия МЕЖДУ &ДатаНачала И КОНЕЦПЕРИОДА(&ДатаКонца, ДЕНЬ)
Теперь запрос будет корректно обрабатывать правую границу периода, включая все события за указанный день. В некоторых специфических задачах может потребоваться даже использование двух разных схем в одном отчете, а для высоконагруженных систем будет полезно изучить оптимизацию отчетов с набором данных - объект, где также рассматриваются вопросы работы с несколькими схемами.
Если проблема все еще не решена, лучший способ найти причину — посмотреть, с какими параметрами и с каким текстом СКД в итоге выполняет запрос. Для этого можно использовать:
В заключение, ошибка сравнения дат в СКД — это почти всегда проблема не в синтаксисе запроса, а в настройках передачи параметров. Внимательно пройдя по всем шагам, особенно уделив внимание связи реквизитов формы с параметрами СКД, вы сможете легко решить эту проблему.