Вывод результатов запросов (1С)
Запрос может выдать такие результаты:
Или получаем "ничего" (нет результата)
Или получаем единственное значение (если в запросе сумма или иная агрегатная операция по единственному полю)
в т.ч. единственное значение в результате запросе может быть Null или Неопределено!
Или получаем таблицу результатов
Результаты запроса можно выгрузить:
- в выборку (и после нужно делать обход результатов выборки, там может быть иерархическая структура)
- в таблицу значений
- в дерево значений? Разбираться!
Варианты получения итогов запроса (если не понимать, то будут траблы)
Вариант 1:
В запросе единственное поле выборки — "СуммаПрихода", и единственное возвращаемое значение!
Тогда получаем результат:
ТЗДокументыРСА=ЗапросПриходыЗаДату.Выполнить().Выбрать();
Если ТЗДокументыРСА.Следующий() Тогда Сообщить("РСА Запрос ДАЛ результат");
Сообщить(ТЗДокументыРСА.СуммаПрихода);
КонецЕсли;
Вариант 2-1:
В запросе единственное поле выборки — "СуммаПрихода", а возвращаемых значений может быть несколько!
Тогда получаем результат:
ТЗДокументыРСА=ЗапросПриходыЗаДату.Выполнить().Выбрать();
Пока ТЗДокументыРСА.Следующий() Цикл
Сообщить("РСА Запрос ДАЛ результат");
Сообщить(ТЗДокументыРСА.СуммаПрихода);
КонецЦикла;
Вариант 2-2 (выгрузка результата в таблицу значений)
Если результатов несколько, тогда вариант, когда запрос выгружаем в таблицу значений. И далее варианты:
или перебираем таблицу значений посмотрочно, и читаем реквизиты каждой строки.
ТЗ = Запрос.Выполнить().Выгрузить();
Для Каждого Стр из ТЗ Цикл
Сообщить(Формат(Стр.ДатаСдачи_В_Банк,"ДФ=""дд.ММ.гггг""")+" сумма: " + Строка(Стр.СуммаПринято)); // Выводит: 12.06.2023 сумма: 16 000
// Тут все приведено к строкам, по дате указан формат
КонецЦикла;
или выводим таблицу значений в табличный документ!
// Выводим таблицу значений, полученную из запроса, в табличный документ
ТЗДокументыРСА=ЗапросПриходыЗаДату.Выполнить().Выгрузить();
Если ТЗДокументыРСА.Количество()>0 Тогда
ТабДокумент = Новый ТабличныйДокумент;
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных=Новый ОписаниеИсточникаДанных(ТЗДокументыРСА);
Построитель.Вывести(ТабДокумент);
ТабДокумент.Показать("Долг приход минус возврат должен быть");
Иначе
Сообщить("Запрос не дал данных");
КонецЕсли;
При получении данных из таблиц значений помнить:
в ТЗ индексы строк начинаются с нуля!
ВремСумма=ТЗДокументыРСА.Получить(0); // может выдавать пустое значение из результата запроса (NULL или Неопределено)? И как проверить? Само присвоение ошибки не вызывает!
Получение реквизитов из строк делается по имени полей в запросе.
Запрос может выдавать пустое значение! Тогда результат запроса (значение или таблица значений — они будут не пустые), но само значение в результате или таблице значений будет — пустое! Нужно сделать шаблон, чтобы проверять получаемые значения на NULL или Неопределено.
Синтакс-помощник по получению результатов запроса
РезультатЗапроса (QueryResult)
Выбрать (Select)
Синтаксис:
Выбрать(<ТипОбхода>, <Группировки>, <ГруппировкиДляЗначенийГруппировок>)
Параметры:
<ТипОбхода> (необязательный)
Тип: ОбходРезультатаЗапроса.
Задает тип обхода записей в получаемой выборке.
Значение по умолчанию: Прямой.
<Группировки> (необязательный)
Тип: Строка.
Список группировок по которым будет вестись обход, разделенных запятыми.
Для детальных записей указывается пустая строка. В случае, если группировки не указаны - будет использоваться следующая группировка, указанная в предложении запроса "ИТОГИ".
<ГруппировкиДляЗначенийГруппировок> (необязательный)
Тип: Строка.
Список группировок, из которых будут выбираться значения группировок для обхода, разделенных запятыми. Если указано "Все", то будут выбираться все значения группировок. Если указана пустая строка, то значения для группировок будут выбираться из предыдущей группировки.
Возвращаемое значение:
Тип: ВыборкаИзРезультатаЗапроса.
Описание:
Формирует выборку записей из результата запроса.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
Примечание:
Получение выборок очень большого размера (более 64 Mb) требует наличия достаточного количества свободного места на диске, используемом для размещения временных файлов сервера и клиента.
Пример:
Выборка = РезультатЗапроса.Выбрать(); |
Использование в версии:
Доступен, начиная с версии 8.0.
Описание изменено в версии 8.3.18.
Вот вроде такая же команда "Выбрать()", но работает для вложенных выборок!
ВыборкаИзРезультатаЗапроса (QueryResultSelection)
Выбрать (Select)
Синтаксис:
Выбрать(<ТипОбхода>, <Группировки>, <ГруппировкиДляЗначенийГруппировок>)
Возвращаемое значение:
Тип: ВыборкаИзРезультатаЗапроса.
Описание:
Формирует выборку вложенных записей для текущей записи результата.
Это нужно для позиционирования на первом и последующих элементах
Следующий (Next)
Синтаксис: Следующий()
Возвращаемое значение:
Тип: Булево.
Истина - следующая запись выбрана; Ложь - достигнут конец выборки.
Описание:
Получает следующую запись из результата запроса. Для обхода результата запроса нужно после получения выборки вызвать данный метод для позиционирования на первый элемент и далее вызывать до тех пор, пока не будет возвращено значение Ложь.
ЗАМЕТКИ РСА:
Следующий() возвращает Истина/Ложь по результатам позиционирования на элементе выборки, а не собственно элемент выборки.
Следующий() применяется к выборке из запроса. Пример:
ТЗДокументыРСА=ЗапросПриходыЗаДату.Выполнить().Выбрать();
Если ТЗДокументыРСА.Следующий() Тогда
…
Следующий() нельзя применить к ТаблицеЗначений, куда выгружен результат запроса:
ТЗДокументыРСА=ЗапросПриходыЗаДату.Выполнить().Выгрузить();
Если ТЗДокументыРСА.Следующий() Тогда
…
выдаст ошибку: "Ошибка: Метод объекта не обнаружен (Следующий)"
Потому что для "ТаблицыЗначений" нет метода Следующий().
Выборка данных из ТаблицыЗначений делается так:
ТЗ = Запрос.Выполнить().Выгрузить();
Для каждого Стр из ТЗ Цикл
...
КонецЦикла
При попытке достать результаты запроса, который выводил NULL
(Так получилось, когда в параметры запроса передал дату без приведения к началу дня! В консоли запросов дата ставиться с нулевым временем, потому все работало, а при переносе запроса в модуль 1С из-за неправильного задания параметра получился "облом").
Таблица значений и печать в табличный док — печатало пустую строку, хотя колво элементов равно 1. Надо это учитывать! Если запрос возвращает значение NULL, это все равно — значение!
При выборке, когда возращалось значение NULL, все присвоения срабатывают, но на экране видно "ничего", хотя должен был быть числовой результат! Неприятно!
Вот текст запроса к регистру, который выводит сумму приходов за минусом возвратов поставщику за выбранный день (отбор по выбранной фирме, контрагенту, дате).
ЗапросПриходыЗаДату = Новый Запрос; ЗапросПриходыЗаДату.Текст =" |ВЫБРАТЬ | СУММА(ВЫБОР | КОГДА Взаиморасчеты.Регистратор ССЫЛКА Документ.ПриходнаяНакладная | ТОГДА Взаиморасчеты.СуммаУпр | КОГДА Взаиморасчеты.Регистратор ССЫЛКА Документ.ВозвратТоваровПоставщику | ТОГДА -Взаиморасчеты.СуммаУпр | КОНЕЦ) КАК СуммаПрихода |ИЗ | РегистрНакопления.Взаиморасчеты КАК Взаиморасчеты |ГДЕ | (Взаиморасчеты.Регистратор ССЫЛКА Документ.ПриходнаяНакладная | ИЛИ Взаиморасчеты.Регистратор ССЫЛКА Документ.ВозвратТоваровПоставщику) | И Взаиморасчеты.ДоговорКонтрагента.Владелец = &ВыбКонтрагент | И НАЧАЛОПЕРИОДА(Взаиморасчеты.Период, ДЕНЬ) = &ВыбДата | И Взаиморасчеты.ДоговорКонтрагента.Фирма = &ВыбФирма"; ЗапросПриходыЗаДату.УстановитьПараметр("ВыбФирма", Фирма); ЗапросПриходыЗаДату.УстановитьПараметр("ВыбКонтрагент",Контрагент); ЗапросПриходыЗаДату.УстановитьПараметр("ВыбДата",НачалоДня(ДатаОснования)); ТЗДокументыРСА=ЗапросПриходыЗаДату.Выполнить().Выбрать(); Если ТЗДокументыРСА.Следующий() Тогда Сообщить(ТЗДокументыРСА.СуммаПрихода); КонецЕсли;
Вот ошибочная и правильная строка передачи параметра в запрос:
ЗапросПриходыЗаДату.УстановитьПараметр("ВыбДата",НачалоДня(ДатаОснования)); // Верно
ЗапросПриходыЗаДату.УстановитьПараметр("ВыбДата",ДатаОснования); // Даст значения NULL при выборке доков из регистра
Вот четко пишут, что такое NULL в 1C и как с ним работать
https://www.vdgb.ru/blog/znacheniya-null-est-null-i-estnull/
Таблица значений - перестановка колонок местами
ТЗ.Колонки.Сдвинуть(ИндексКолонки,Сдвиг) // Индексы начинаются с нуля. Сдвиг - положительное или отрицательное число
Форматирование данных, выдаваемых построителем отчета
Ширина колонок
Ширина колонок
Выводить дату без времени (смотри)
Добавить обрамления строк - для этого лучше сделать макет, чем программно задавать границы для каждой области?
Старые заметки про выборки
В 2015
https://1cguide.ru/programmirovanie-1s/vyborka-iz-rezultata-zaprosa.html
Также выборку можно обходить в цикле Пока. Переменная ВыборкаРезультатов при каждой итерации цикла содержит в себе конкретную строку выборки, все ее элементы доступны через точку.
Пока ВыборкаРезультатов.Следующий() Цикл Сообщить(ВыборкаРезультатов.Ссылка); //ваш код по обработке элемента выборки запроса КонецЦикла;
Вот инфа вроде та же https://programmist1s.ru/vyiborka-v-1s/
Работа с выборками 1С https://wiseadvice-it.ru/o-kompanii/blog/articles/kak-sdelat-vyborku-v-1s-8-3/
Вот не сколько получение количества элементов в выборке интересно, сколько логика работы Далиона
Выборка = Запрос.Выполнить().Выбрать(); Если Выборка.Количество() > 0 Тогда
взято отсюда:
Процедура ПроверкаНаСмещениеДатАктаПереоценкиИДокументаОснования(ДокументОбъект, Отказ, РежимЗаписи) Экспорт ... Выборка = Запрос.Выполнить().Выбрать(); Если Выборка.Количество() > 0 Тогда ТекстСообщения = "Нельзя проводить документ, если его дата меньше даты последнего проведенного акта переоценки, введенного на основании данного документа."; КонецЕсли;
Запрос с временными таблицами. Как в обработке получить данные временных таблиц
Вот решение:
https://fastcode.im/Templates/7451/poluchit-dannye-vremennoj-tablicy
При добавлении данной функции в общий модуль, позволяет быстро и без внесения изменений в код получать данные из временных таблиц в запросе. Используется в случае, если МенеджерВременныхТаблиц = Неопределенно. Доступна с версии 8.3.8
//Функция возвращает содержимое временной таблицы в запросе по индексу
//
// Параметры:
// Запрос - Запрос - исполняемый запрос
// ИндексПакета - Число – индекс временной таблицы
//
// Возвращаемое значение:
// - Таблица значений - таблица значений с содержимым временной таблицы.
//
Функция ПолучитьДанныеВременнойТаблицы(Запрос, ИндексПакета) Экспорт
Возврат Запрос.ВыполнитьПакетСПромежуточнымиДанными()[ИндексПакета].Выгрузить();
КонецФункции
РСА У меня в обработке код выглядел так:
ТЗ_НоменклатураЗаказа= Запрос.Выполнить().Выгрузить(); ТЗ_Промежут0=Запрос.ВыполнитьПакетСПромежуточнымиДанными()[0].Выгрузить(); ТЗ_Промежут1=Запрос.ВыполнитьПакетСПромежуточнымиДанными()[1].Выгрузить(); ТЗ_Промежут2=Запрос.ВыполнитьПакетСПромежуточнымиДанными()[2].Выгрузить(); ТЗ_Промежут3=Запрос.ВыполнитьПакетСПромежуточнымиДанными()[3].Выгрузить();
Запрос с временными таблицами, пакетный. Как в обработке получить данные пакетного запроса?
РСА У меня почему-то ничего не получилось!
Варианты были:
получать данные промежуточных таблиц в консоли запросов;
в отладчике?
использовать менеджер временных таблиц?
вместо пакетных запросов делать отдельные запросы?
01.09.24
Расшифровки отчетов смотри
10 примеров программной работы с расшифровкой отчетов на СКД
https://курсы-по-1с.рф/news/skd-reports-ext-10-samples/
10.11.2021
Изучать!
Вот чего-то
https://infostart.ru/1c/articles/1829344/
Новичок новичку: самый простой способ сделать расшифровку в СКД (обычные\управляемые формы)
17.05.23
Вот еще
https://wiseadvice-it.ru/o-kompanii/blog/articles/rasshifrovka-otcheta-v-1s-8-3-na-skd/
Расшифровка отчета в 1С 8.3 на СКД
Поиск "расшифровка для обычных форм"
поиск "1с расшифровка обычные формы"
Работа с расшифровкой в табличном документе
https://its.1c.ru/db/metod8dev/content/2233/hdoc
Чел сделал ошибку и сам разобрался, но нам не написал толком и повторять его опыты не интересно! Вот на мисте для обычных форм https://www.mista.ru/topic/714781