Надо помнить, что если секции GROUP BY нет, то запрос с агрегатными функциями все равно вернет единственную строку данных, даже если условия в секции WHERE не выполнились.
Вот пример функции из типового решения 1С с этой ошибкой:
Вот пример функции из типового решения 1С с этой ошибкой:
Функция ПолучитьДатуПоследнегоДокументаОснования() УстановитьПривилегированныйРежим(Истина); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | МАКСИМУМ(ДанныеПервичныхДокументов.ДатаРегистратора) КАК Дата |ИЗ | РегистрСведений.ДанныеПервичныхДокументов КАК ДанныеПервичныхДокументов |ГДЕ | ДанныеПервичныхДокументов.Организация = &Организация | И ДанныеПервичныхДокументов.Документ В (&ДокументыОснования)"; Запрос.УстановитьПараметр("ДокументыОснования", ДокументыОснования.Выгрузить().ВыгрузитьКолонку("ДокументОснование")); Запрос.УстановитьПараметр("Организация", Организация); Результат = Запрос.Выполнить(); УстановитьПривилегированныйРежим(Ложь); Если Результат.Пустой() Тогда Возврат Дата(1,1,1); //вот эта ветка никогда не выполнится Иначе Возврат Результат.Выгрузить()[0].Дата; //здесь будет NULL, если условие в секции ГДЕ не выполнится КонецЕсли; КонецФункции
Видимо предполагается, что запрос может быть пустым и в этом случае результатом будет пустая дата. Считается, что результатом функции будет значение с типом дата. Но если условие не выполнится, то запрос не будет пустым! А вот результатом его будет NULL, которое и передается как результат вместо даты. Что тут надо сделать:
- Надо избавиться от NULL через COALESCE. У функции COUNT нет такой проблемы.
- Воспользоваться чудесным свойством такого отчета: такой отчет всегда выдает единственную строку! Здесь не надо проверки условия на пустой результат запроса! Я часто пользуюсь этим свойством.
Функция ПолучитьДатуПоследнегоДокументаОснования() УстановитьПривилегированныйРежим(Истина); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ЕСТЬNULL(МАКСИМУМ(ДанныеПервичныхДокументов.ДатаРегистратора), ДАТАВРЕМЯ(1,1,1)) КАК Дата |ИЗ | РегистрСведений.ДанныеПервичныхДокументов КАК ДанныеПервичныхДокументов |ГДЕ | ДанныеПервичныхДокументов.Организация = &Организация | И ДанныеПервичныхДокументов.Документ В (&ДокументыОснования)"; Запрос.УстановитьПараметр("ДокументыОснования", ДокументыОснования.Выгрузить().ВыгрузитьКолонку("ДокументОснование")); Запрос.УстановитьПараметр("Организация", Организация); Результат = Запрос.Выполнить(); УстановитьПривилегированныйРежим(Ложь); Возврат Результат.Выгрузить()[0].Дата; КонецФункции
Для тех, кто не хочет исправлять типовую, а использует расширения (как я):
&Вместо("ПолучитьДатуПоследнегоДокументаОснования") Функция ИТ_ПолучитьДатуПоследнегоДокументаОснования() Результат = ПродолжитьВызов(); Если Не ЗначениеЗаполнено(Результат) Тогда Результат = Дата(1,1,1); КонецЕсли; Возврат Результат; КонецФункции