@mishaiba

Выборка.Следующий() — ложь. Не работает выборка. Как починить?

Опять проблема с 1с. Работаю с регистром накопления. Написала следующий запрос и цикл к нему, в отладчике ВыборкаДетальныеЗаписи.Следующий() - ложь, РезультатЗапроса выдает колонки и свойства их содержимого, но значение не показывает, а РезультатЗапроса.Выбрать() - ошибки в значении. Параметры вроде те, выборка должна быть непустой. Почему так происходит - ума не приложу, только учусь. Буду очень благодарна за помощь!
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|  СебестоимостьТоваровОстатки.Номенклатура,
|  СебестоимостьТоваровОстатки.СуммаОстаток как Сумма,
|  СебестоимостьТоваровОстатки.КоличествоОстаток как Количество
|  ИЗ
|   РегистрНакопления.СебестоимостьТоваров.Остатки (
|  &МоментВремени,
|  Номенклатура В
|  ( ВЫБРАТЬ ОказаниеУслугиМатериалы.Материал
| ИЗ Документ.ОказаниеУслуги.Материалы как ОказаниеУслугиМатериалы
| ГДЕ  ОказаниеУслугиМатериалы.Ссылка =&Ссылка ))
| КАК СебестоимостьТоваровОстатки";
Запрос.УстановитьПараметр("МоментВремени",МоментВремени());
Запрос.УстановитьПараметр("Ссылка", Ссылка);

РезультатЗапроса  = Запрос.Выполнить();
СуммаСебестоимости = 0;
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();


Пока ВыборкаДетальныеЗаписи.Следующий() Цикл 
СебестоимостьЕдиницы = ВыборкаДетальныеЗаписи.Сумма / ВыборкаДетальныеЗаписи.Количество;
Движение = Движения.СебестоимостьТоваров.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
ТекСтр = Материалы.Найти(ВыборкаДетальныеЗаписи.Номенклатура, "Материал");
Движение.Количество = ТекСтр.Количество;
Движение.Сумма = СебестоимостьЕдиницы * ТекСтр.Количество;
СуммаСебестоимости = СуммаСебестоимости + СебестоимостьЕдиницы*ТекСтр.Количество;
КонецЦикла;
  • Вопрос задан
  • 1207 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Dementor
программист, архитектор, аналитик
Написала следующий запрос и цикл к нему, в отладчике ВыборкаДетальныеЗаписи.Следующий() - ложь, РезультатЗапроса выдает колонки и свойства их содержимого, но значение не показывает, а РезультатЗапроса.Выбрать() - ошибки в значении.


1. Про результат запроса - все верно, там можно увидеть только структуру и признак заполненности результатами. Чтобы получить содержимое, нужно использовать выборку.

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

При отладке выборки важно понимать, что код в модуле и код в окне Табло или "Вычисления выражения" работает идентично. Сколько раз вы сделаете просмотр результата от вызова Следующий() - на столько позиций вы сместитесь по строкам выборки. Т.е. возможна ситуация, когда вы отладкой загоняете позицию ПОСЛЕ данных и обращение к колонкам запроса выдает ошибку.

Более безопасно делать отладку Выборки с помощью получения количества данных методом Количество(), а потом проверки конкретных строк с помощью метода Получить(Индекс). Теоретически вы даже можете делать обход выборки с помощью обычного цикла по счетчику от 0 до Количество-1, но проще выгрузить результат запроса в ТаблицуЗначений и обходить ее строки - точно никаких заморочек не будет.

2. Лучше не использовать в параметрах виртуальных таблиц подзапросы - это не позволяет платформе обратится к таблицам с предрассчитанными итогами для быстрого получения результатов и пойдет скан по полной физической таблице. Намного эффективнее (и читабельнее), если вы сделаете сначала выборку ваших материалов по оказанной услуге во временную таблицу, а потом сделаете Левое Соединение с таблицей остатков (или внутреннее, если вам в результате не нужны позиции без остатка).

Примерно так:
Запрос.Текст = 
"ВЫБРАТЬ
|	ОказаниеУслугиМатериалы.Материал
|ПОМЕСТИТЬ втМатериалы
|ИЗ
|	Документ.ОказаниеУслуги.Материалы КАК ОказаниеУслугиМатериалы
|ГДЕ
|	ОказаниеУслугиМатериалы.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|	СебестоимостьТоваровОстатки.Номенклатура,
|	ЕСТЬNULL(СебестоимостьТоваровОстатки.СуммаОстаток, 0) КАК Сумма,
|	ЕСТЬNULL(СебестоимостьТоваровОстатки.КоличествоОстаток, 0) КАК Количество
|ИЗ
|	втМатериалы КАК втМатериалы
|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СебестоимостьТоваров.Остатки(&МоментВремени, ) КАК СебестоимостьТоваровОстатки
|		ПО втМатериалы.Материал = СебестоимостьТоваровОстатки.Номенклатура";
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы