Почему в отладчике 1С появляется «Ошибка чтения значения» при обращении к выборке запроса?

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

При разработкe и отладке программного кода в 1С разработчики часто сталкиваются с ситуацией, когда в окне отладчика при вычислении выражения для поля выборки запроса отображается сообщение «Ошибка чтения значения». Попробуем проанализировать, почему возникает эта ошибка и как её исправить.

Причина возникновения ошибки

Рассмотрим механиков работы с объектом ВыборкаИзРезультатаЗапроса. Когда мы выполняем метод РезультатЗапроса.Выбрать(), система создает объект выборки, однако позиционирование на первой записи еще не происходит. Выборка находится в состоянии «до первой записи».

Если установить точку останова сразу на строке вызова метода Выбрать() или на следующей строке до вызова метода Следующий(), то при попытке вычислить значение поля (например, ВыборкаДетальныеЗаписи.СредКолЧеловек) отладчик выдаст сообщение «Ошибка чтения значения».

Проанализируем пример кода, в котором возникает эта проблема:


РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); // Точка останова здесь!
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    СредКолЧеловек = ВыборкаДетальныеЗаписи.СредКолЧеловек;
КонецЦикла;

Если точка останова стоит на строке ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();, то объект выборки еще не спозиционирован. Чтение полей выборки станет доступным только внутри цикла или после явного вызова метода Следующий().

Как правильно обращаться к полям выборки

Разберем по шагам, как корректно работать с результатом запроса и избегать подобных ошибок при отладке.

  1. Переместите точку останова внутрь цикла. Для того чтобы проанализировать значения полей выборки, точка останова должна находиться на строках внутри цикла Пока ВыборкаДетальныеЗаписи.Следующий() Цикл. В этот момент позиционирование на текущую строку уже выполнено.
  2. Проверяйте имя поля. Убедитесь, что имя обращаемого свойства совпадает с псевдонимом (синонимом) поля в секции ВЫБРАТЬ вашего текста запроса. Например, если в запросе указано КАК СредКолЧеловек, обращение должно быть именно ВыборкаДетальныеЗаписи.СредКолЧеловек, а не ВыборкаДетальныеЗаписи.Значение.
  3. Используйте безопасный выбор без цикла для одной строки. Если запрос гарантированно возвращает итоговое значение или одну строку, цикл использовать не обязательно, но вызвать метод Следующий() всё равно необходимо:

РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий(); // Позиционируемся на первой записи
    СредКолЧеловек = Выборка.СредКолЧеловек; // Теперь значение доступно
Иначе
    СредКолЧеловек = 0;
КонецЕсли;

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

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


ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
// На этой строке в отладчике можно открыть ТаблицаРезультата и увидеть все колонки и строки

Важные нюансы при написании запросов

Посмотрим на дополнительное улучшение самого запроса из примера. При расчете агрегатных полей и делении важно учитывать следующие особенности:

1. Защита от NULL. Если в результате запроса нет строк, агрегатная функция СУММА возвращает NULL. Для предотвращения ошибок рекомендуется использовать функцию ЕСТЬNULL():

ЕСТЬNULL(СУММА(...), 0)

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

← На главную