Почему в отладчике 1С возникает ошибка чтения значения для выборки и как исправить пустой результат запроса из СКД?

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

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

Причина 1. Особенности поведения объекта «ВыборкаИзРезультатаЗапроса»

Проанализируем механику работы с выборкой результатов запроса. Когда мы получаем выборку с помощью метода Выбрать(), курсор находится перед первой записью. До тех пор, пока не выполнен переход к конкретной строке, объект выборки не содержит активных данных текущей записи.

Попытка просмотреть значения полей в табло отладчика или вычислить выражение до вызова метода Следующий() неизбежно приводит к сообщению «Ошибка чтения значения». Аналогичная ошибка возникает, если результат запроса абсолютно пуст и метод Следующий() возвращает Ложь.

Посмотрим на классический ошибочный подход, при котором данные пытаются прочитать сразу после инициализации выборки:


// Неправильный подход: обращение к полям до позиционирования
Выборка = Запрос.Выполнить().Выбрать();
// В отладчике для Выборка.Номенклатура будет "Ошибка чтения значения"

Разберем правильный алгоритм обхода выборки с проверкой на наличие строк:


РезультатЗапроса = Запрос.Выполнить();

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

Причина 2. Автогенерация параметров и ошибки инициализации периода в СКД

Если выборка обходится через Следующий(), но данных все равно нет, выясним причину формирования пустого результата. Часто при ручном выполнении текста запроса, извлеченного из МакетКомпоновкиДанных, в тексте появляются сгенерированные платформой параметры вида &П, &П2 вместо ожидаемых &НачалоПериода и &КонецПериода.

Это происходит из-за механизма автозаполнения параметров виртуальных таблиц СКД (например, РегистрНакопления.Продажи.Обороты). При этом параметры периода могут принимать пустые значения по следующим причинам:

  1. Несовпадение типов и функций: у типа СтандартныйПериод свойство ДатаОкончания возвращает начало дня (время 00:00:00). Если не применить приведение к концу дня, все движения за последнюю дату периода исключаются из выборки.
  2. Ошибки вычисления зависимых параметров: если в СКД созданы параметры НачалоПериода и КонецПериода, вычисляемые через выражения от составного параметра периода, но для них не включено ограничение доступности, платформа может не рассчитать их автоматически. В итоге в запрос передаются пустые даты (01.01.0001 00:00:00), что дает нулевой оборот.

Решение 1. Корректная настройка параметров дат в схеме компоновки

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

  1. Откроем вкладку «Параметры» в схеме компоновки данных.
  2. Создадим пользовательский параметр (например, ПериодОтчета) с типом данных СтандартныйПериод. Оставим его доступным для пользователя в настройках отчета.
  3. Для системных параметров виртуальной таблицы НачалоПериода и КонецПериода установим флаг «Ограничение доступности», чтобы исключить конфликт пользовательского ввода.
  4. В колонке «Выражение» укажем явный расчет границ времени:
    • Для НачалоПериода: &ПериодОтчета.ДатаНачала
    • Для КонецПериода: КонецПериода(&ПериодОтчета.ДатаОкончания, "ДЕНЬ")
  5. В тексте запроса СКД явно зафиксируем обращение к параметрам виртуальной таблицы:
    
    ВЫБРАТЬ
        ПродажиОбороты.Номенклатура КАК Номенклатура,
        ПродажиОбороты.КоличествоОборот КАК Количество,
        ПродажиОбороты.СуммаОборот КАК Сумма
    ИЗ
        РегистрНакопления.Продажи.Обороты({(&НачалоПериода)}, {(&КонецПериода)}, , ) КАК ПродажиОбороты
    

Решение 2. Штатная программная выгрузка данных СКД в Таблицу Значений

Рассмотрим более надежный способ получения данных из СКД в программном коде. Вместо ручного извлечения SQL-текста из макета компоновки данных и самостоятельной передачи параметров в объект Запрос, рекомендуется использовать стандартный конвейер компоновки данных. Это гарантирует корректное применение всех параметров, условий, группировок и выражений без возникновения побочных системных параметров &П.

Посмотрим на программный пример выгрузки данных СКД в коллекцию значений:


// 1. Инициализируем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(
    ЭтотОбъект.СхемаКомпоновкиДанных, 
    ПараметрыОтчета.НастройкиОтчета, 
    ДанныеРасшифровки
);

// 2. Инициализируем процессор компоновки данных
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

// 3. Выводим результат компоновки в ТаблицуЗначений
ТаблицаРезультат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

// 4. Работаем с готовой таблицей данных
Для Каждого СтрокаДанных Из ТаблицаРезультат Цикл
    ТекущаяНоменклатура = СтрокаДанных.Номенклатура;
    ТекущаяСумма = СтрокаДанных.Сумма;
КонецЦикла;

Такой подход исключает ошибки при чтении выборки, обеспечивает корректную обработку периодов и гарантирует полную совместимость с механизмами СКД в любых конфигурациях 1С.

← На главную