Как получить документы запросом в 1С: период, отбор, обход выборки
Чтобы получить документы запросом в 1С, обращайтесь к таблице
Документ.ИмяВида: в секции ВЫБРАТЬ перечислите нужные поля
(обычно Ссылка, Дата, Номер), в ГДЕ
задайте отбор — по периоду через Дата МЕЖДУ &Начало И &Конец и по
реквизитам через &Параметр. Значения подставляйте только через
УстановитьПараметр(), а не конкатенацией строк.
Результат запроса обходят выборкой: Запрос.Выполнить().Выбрать() и цикл
Пока Выборка.Следующий() Цикл. Один запрос заменяет перебор тысяч документов
в цикле — это и быстрее, и надёжнее.
Как выбрать документы за период запросом
Самая частая задача — получить документы одного вида за интервал дат. В языке запросов 1С
отбор по периоду делают оператором МЕЖДУ по реквизиту Дата
(та самая фраза «1с запрос документ дата»):
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка КАК Ссылка,
| ПоступлениеТоваровУслуг.Дата КАК Дата,
| ПоступлениеТоваровУслуг.Номер КАК Номер,
| ПоступлениеТоваровУслуг.Контрагент КАК Контрагент
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Дата МЕЖДУ &Начало И &Конец
|УПОРЯДОЧИТЬ ПО
| ПоступлениеТоваровУслуг.Дата";
Запрос.УстановитьПараметр("Начало", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("Конец", КонецДня(ДатаОкончания));
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Номер + " от " + Выборка.Дата);
КонецЦикла;
Ключевой момент — границы периода. Реквизит Дата хранит дату и время,
поэтому конец периода оборачивают в КонецДня(), иначе документы за последний день
после полуночи не попадут в выборку. Оператор МЕЖДУ включает обе границы.
Ключевые методы: параметры, выполнение, обход выборки
Любой запрос к документам строится на трёх методах: подстановка значений через
УстановитьПараметр(), запуск через Выполнить() и обход результата
через Выбрать() и Следующий().
Запрос.УстановитьПараметр("Контрагент", СсылкаНаКонтрагента);
Запрос.УстановитьПараметр("Начало", НачалоДня(ДатаНачала));
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// Выборка.Ссылка, Выборка.Дата ...
КонецЦикла;
Если данные удобнее обрабатывать таблицей, а не построчно, результат запроса выгружают в
таблицу значений методом Выгрузить():
Таблица = Запрос.Выполнить().Выгрузить();
Сообщить("Найдено документов: " + Таблица.Количество());
Отбор по контрагенту и реквизитам документа
Чтобы наложить отбор по документу (запрос «1с запрос отбор по документу»), добавляйте условия
в секцию ГДЕ через И. Отбор по контрагенту, организации, статусу —
всё это реквизиты шапки документа:
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка,
| РеализацияТоваровУслуг.Дата КАК Дата,
| РеализацияТоваровУслуг.СуммаДокумента КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Дата МЕЖДУ &Начало И &Конец
| И РеализацияТоваровУслуг.Контрагент = &Контрагент
| И РеализацияТоваровУслуг.Проведен = ИСТИНА
|УПОРЯДОЧИТЬ ПО
| РеализацияТоваровУслуг.Дата";
Запрос.УстановитьПараметр("Начало", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("Конец", КонецДня(ДатаОкончания));
Запрос.УстановитьПараметр("Контрагент", ВыбранныйКонтрагент);
Условие Проведен = ИСТИНА отсекает черновики. Если нужны только конкретные
документы без дублей по какому-то полю — используйте ВЫБРАТЬ РАЗЛИЧНЫЕ, тогда
повторяющиеся строки схлопнутся в одну.
Тип и вид документа в запросе
Частый вопрос — «1с тип документа в запросе»: как в одной выборке отличить вид документа или
получить документы разных видов вместе. Имя таблицы Документ.ИмяВида и задаёт вид;
чтобы собрать документы нескольких видов в одну выборку по периоду, используют
ОБЪЕДИНИТЬ ВСЕ с общими полями:
Запрос.Текст =
"ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка КАК Документ,
| ПоступлениеТоваровУслуг.Дата КАК Дата
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Дата МЕЖДУ &Начало И &Конец
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка,
| РеализацияТоваровУслуг.Дата
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Дата МЕЖДУ &Начало И &Конец
|УПОРЯДОЧИТЬ ПО
| Дата";
Тип конкретной записи в цикле обхода определяют функцией ТипЗнч(Выборка.Документ)
или проверкой Выборка.Документ ССЫЛКА Документ.ПоступлениеТоваровУслуг. Поле
Ссылка уже несёт в себе тип, поэтому отдельно «тип документа» хранить не нужно.
Соединение с табличной частью документа
Когда нужны строки документа (номенклатура, количество, цена), обращаются к табличной части
как к отдельной таблице Документ.ИмяВида.ИмяТабличнойЧасти. Она уже связана с
шапкой через поле Ссылка, поэтому дополнительное соединение обычно не требуется:
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Ссылка КАК Документ,
| Товары.Ссылка.Дата КАК Дата,
| Товары.Номенклатура КАК Номенклатура,
| Товары.Количество КАК Количество,
| Товары.Сумма КАК Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Дата МЕЖДУ &Начало И &Конец
| И Товары.Ссылка.Проведен = ИСТИНА
|УПОРЯДОЧИТЬ ПО
| Дата";
Обращение через точку Товары.Ссылка.Дата — это неявное соединение с шапкой.
Оно удобно, но если по такому полю ещё и идёт отбор в ГДЕ, на больших объёмах
лучше вынести условие в явное СОЕДИНЕНИЕ с таблицей документа, чтобы СУБД
построила эффективный план.
Получить ссылку или поля документа
Решите заранее, что именно вам нужно из запроса — ссылки на документы или их поля. Если дальше
вы будете проводить документы, менять реквизиты или открывать формы, выбирайте только
Ссылка и получайте остальное через объект:
// Нужны только ссылки — минимум данных из СУБД
"ВЫБРАТЬ Заказ.Ссылка КАК Ссылка ИЗ Документ.ЗаказКлиента КАК Заказ ГДЕ ..."
// Нужны поля для отчёта — берём их прямо в запросе, объект не читаем
"ВЫБРАТЬ Заказ.Номер, Заказ.Дата, Заказ.СуммаДокумента ИЗ Документ.ЗаказКлиента КАК Заказ ГДЕ ..."
Не выбирайте лишние поля «про запас»: чем меньше колонок, тем легче запрос. И наоборот — не
читайте Выборка.Ссылка.ПолучитьОбъект() в цикле только ради пары реквизитов,
которые можно было получить прямо в тексте запроса.
Частые ошибки при получении документов запросом
-
Запрос внутри цикла. Выполнять
Запрос.Выполнить()в цикле по документам или контрагентам — главный источник тормозов. Отбор задаётся условиями вГДЕ, а не многократным запуском запроса. -
Не обёрнут конец периода.
Дата МЕЖДУ &Начало И &Конецс параметром безКонецДня()теряет документы за последний день после 00:00:00. -
Значения подставлены конкатенацией строк. Склейка параметра прямо в текст
запроса ломается на кавычках и датах и открывает дыры. Всегда используйте
УстановитьПараметр()и&Параметр. -
Путают
Ссылкаи поля.Выборка.Ссылка— это ссылка на документ целиком; чтобы получить его номер или дату, выбирайте их полями запроса или обращайтесь через точку, а не пытайтесь «достать» из ссылки как из структуры. -
Ошибка в имени вида или реквизита.
Документ.ПоступлениеТовароввместо реальногоПоступлениеТоваровУслуг— запрос падает. Имена берите из метаданных именно вашей конфигурации.
Как получить документы запросом: короткий чек-лист
- За период —
Дата МЕЖДУ &Начало И &КонецсНачалоДня/КонецДня. - Отбор по документу — условия по реквизитам шапки через
ИвГДЕ. - Строки документа — таблица
Документ.Вид.ТабличнаяЧасть. - Несколько видов —
ОБЪЕДИНИТЬ ВСЕс общими полями. - Обход —
Выполнить().Выбрать()иПока Следующий(), либоВыгрузить()в таблицу.
Частые вопросы о получении документов запросом в 1С
Как получить документы за период запросом в 1С?
Обратитесь к таблице Документ.ИмяВида и в секции ГДЕ задайте
условие Дата МЕЖДУ &Начало И &Конец, подставив границы через
УстановитьПараметр() с НачалоДня() и КонецДня().
Результат обойдите выборкой Выполнить().Выбрать().
Как в запросе получить документы разных видов вместе?
Соедините выборки по каждому виду документа оператором ОБЪЕДИНИТЬ ВСЕ,
выбирая одинаковый набор полей (обычно Ссылка и Дата). Тип
конкретной записи потом определяется функцией ТипЗнч() или оператором
ССЫЛКА.
Что лучше выбирать — ссылку на документ или его поля?
Если дальше нужен объект (проведение, изменение реквизитов) — выбирайте только
Ссылка. Если данные идут в отчёт — берите нужные поля прямо в запросе и не
читайте объект в цикле, это лишняя нагрузка.