Язык запросов 1С

Как получить документы запросом в 1С: период, отбор, обход выборки

Коротко

Чтобы получить документы запросом в 1С, обращайтесь к таблице Документ.ИмяВида: в секции ВЫБРАТЬ перечислите нужные поля (обычно Ссылка, Дата, Номер), в ГДЕ задайте отбор — по периоду через Дата МЕЖДУ &Начало И &Конец и по реквизитам через &Параметр. Значения подставляйте только через УстановитьПараметр(), а не конкатенацией строк.

Результат запроса обходят выборкой: Запрос.Выполнить().Выбрать() и цикл Пока Выборка.Следующий() Цикл. Один запрос заменяет перебор тысяч документов в цикле — это и быстрее, и надёжнее.

Как выбрать документы за период запросом

Самая частая задача — получить документы одного вида за интервал дат. В языке запросов 1С отбор по периоду делают оператором МЕЖДУ по реквизиту Дата (та самая фраза «1с запрос документ дата»):

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |   ПоступлениеТоваровУслуг.Ссылка КАК Ссылка,
    |   ПоступлениеТоваровУслуг.Дата КАК Дата,
    |   ПоступлениеТоваровУслуг.Номер КАК Номер,
    |   ПоступлениеТоваровУслуг.Контрагент КАК Контрагент
    |ИЗ
    |   Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
    |ГДЕ
    |   ПоступлениеТоваровУслуг.Дата МЕЖДУ &Начало И &Конец
    |УПОРЯДОЧИТЬ ПО
    |   ПоступлениеТоваровУслуг.Дата";
Запрос.УстановитьПараметр("Начало", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("Конец", КонецДня(ДатаОкончания));

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Номер + " от " + Выборка.Дата);
КонецЦикла;

Ключевой момент — границы периода. Реквизит Дата хранит дату и время, поэтому конец периода оборачивают в КонецДня(), иначе документы за последний день после полуночи не попадут в выборку. Оператор МЕЖДУ включает обе границы.

Ключевые методы: параметры, выполнение, обход выборки

Любой запрос к документам строится на трёх методах: подстановка значений через УстановитьПараметр(), запуск через Выполнить() и обход результата через Выбрать() и Следующий().

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

Если данные удобнее обрабатывать таблицей, а не построчно, результат запроса выгружают в таблицу значений методом Выгрузить():

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

Отбор по контрагенту и реквизитам документа

Чтобы наложить отбор по документу (запрос «1с запрос отбор по документу»), добавляйте условия в секцию ГДЕ через И. Отбор по контрагенту, организации, статусу — всё это реквизиты шапки документа:

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

Условие Проведен = ИСТИНА отсекает черновики. Если нужны только конкретные документы без дублей по какому-то полю — используйте ВЫБРАТЬ РАЗЛИЧНЫЕ, тогда повторяющиеся строки схлопнутся в одну.

Тип и вид документа в запросе

Частый вопрос — «1с тип документа в запросе»: как в одной выборке отличить вид документа или получить документы разных видов вместе. Имя таблицы Документ.ИмяВида и задаёт вид; чтобы собрать документы нескольких видов в одну выборку по периоду, используют ОБЪЕДИНИТЬ ВСЕ с общими полями:

Запрос.Текст =
    "ВЫБРАТЬ
    |   ПоступлениеТоваровУслуг.Ссылка КАК Документ,
    |   ПоступлениеТоваровУслуг.Дата КАК Дата
    |ИЗ
    |   Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
    |ГДЕ
    |   ПоступлениеТоваровУслуг.Дата МЕЖДУ &Начало И &Конец
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    |   РеализацияТоваровУслуг.Ссылка,
    |   РеализацияТоваровУслуг.Дата
    |ИЗ
    |   Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
    |ГДЕ
    |   РеализацияТоваровУслуг.Дата МЕЖДУ &Начало И &Конец
    |УПОРЯДОЧИТЬ ПО
    |   Дата";

Тип конкретной записи в цикле обхода определяют функцией ТипЗнч(Выборка.Документ) или проверкой Выборка.Документ ССЫЛКА Документ.ПоступлениеТоваровУслуг. Поле Ссылка уже несёт в себе тип, поэтому отдельно «тип документа» хранить не нужно.

Соединение с табличной частью документа

Когда нужны строки документа (номенклатура, количество, цена), обращаются к табличной части как к отдельной таблице Документ.ИмяВида.ИмяТабличнойЧасти. Она уже связана с шапкой через поле Ссылка, поэтому дополнительное соединение обычно не требуется:

Запрос.Текст =
    "ВЫБРАТЬ
    |   Товары.Ссылка КАК Документ,
    |   Товары.Ссылка.Дата КАК Дата,
    |   Товары.Номенклатура КАК Номенклатура,
    |   Товары.Количество КАК Количество,
    |   Товары.Сумма КАК Сумма
    |ИЗ
    |   Документ.РеализацияТоваровУслуг.Товары КАК Товары
    |ГДЕ
    |   Товары.Ссылка.Дата МЕЖДУ &Начало И &Конец
    |   И Товары.Ссылка.Проведен = ИСТИНА
    |УПОРЯДОЧИТЬ ПО
    |   Дата";

Обращение через точку Товары.Ссылка.Дата — это неявное соединение с шапкой. Оно удобно, но если по такому полю ещё и идёт отбор в ГДЕ, на больших объёмах лучше вынести условие в явное СОЕДИНЕНИЕ с таблицей документа, чтобы СУБД построила эффективный план.

Получить ссылку или поля документа

Решите заранее, что именно вам нужно из запроса — ссылки на документы или их поля. Если дальше вы будете проводить документы, менять реквизиты или открывать формы, выбирайте только Ссылка и получайте остальное через объект:

// Нужны только ссылки — минимум данных из СУБД
"ВЫБРАТЬ Заказ.Ссылка КАК Ссылка ИЗ Документ.ЗаказКлиента КАК Заказ ГДЕ ..."

// Нужны поля для отчёта — берём их прямо в запросе, объект не читаем
"ВЫБРАТЬ Заказ.Номер, Заказ.Дата, Заказ.СуммаДокумента ИЗ Документ.ЗаказКлиента КАК Заказ ГДЕ ..."

Не выбирайте лишние поля «про запас»: чем меньше колонок, тем легче запрос. И наоборот — не читайте Выборка.Ссылка.ПолучитьОбъект() в цикле только ради пары реквизитов, которые можно было получить прямо в тексте запроса.

Частые ошибки при получении документов запросом

  • Запрос внутри цикла. Выполнять Запрос.Выполнить() в цикле по документам или контрагентам — главный источник тормозов. Отбор задаётся условиями в ГДЕ, а не многократным запуском запроса.
  • Не обёрнут конец периода. Дата МЕЖДУ &Начало И &Конец с параметром без КонецДня() теряет документы за последний день после 00:00:00.
  • Значения подставлены конкатенацией строк. Склейка параметра прямо в текст запроса ломается на кавычках и датах и открывает дыры. Всегда используйте УстановитьПараметр() и &Параметр.
  • Путают Ссылка и поля. Выборка.Ссылка — это ссылка на документ целиком; чтобы получить его номер или дату, выбирайте их полями запроса или обращайтесь через точку, а не пытайтесь «достать» из ссылки как из структуры.
  • Ошибка в имени вида или реквизита. Документ.ПоступлениеТоваров вместо реального ПоступлениеТоваровУслуг — запрос падает. Имена берите из метаданных именно вашей конфигурации.

Как получить документы запросом: короткий чек-лист

  • За периодДата МЕЖДУ &Начало И &Конец с НачалоДня/КонецДня.
  • Отбор по документу — условия по реквизитам шапки через И в ГДЕ.
  • Строки документа — таблица Документ.Вид.ТабличнаяЧасть.
  • Несколько видовОБЪЕДИНИТЬ ВСЕ с общими полями.
  • ОбходВыполнить().Выбрать() и Пока Следующий(), либо Выгрузить() в таблицу.

Частые вопросы о получении документов запросом в 1С

Как получить документы за период запросом в 1С?

Обратитесь к таблице Документ.ИмяВида и в секции ГДЕ задайте условие Дата МЕЖДУ &Начало И &Конец, подставив границы через УстановитьПараметр() с НачалоДня() и КонецДня(). Результат обойдите выборкой Выполнить().Выбрать().

Как в запросе получить документы разных видов вместе?

Соедините выборки по каждому виду документа оператором ОБЪЕДИНИТЬ ВСЕ, выбирая одинаковый набор полей (обычно Ссылка и Дата). Тип конкретной записи потом определяется функцией ТипЗнч() или оператором ССЫЛКА.

Что лучше выбирать — ссылку на документ или его поля?

Если дальше нужен объект (проведение, изменение реквизитов) — выбирайте только Ссылка. Если данные идут в отчёт — берите нужные поля прямо в запросе и не читайте объект в цикле, это лишняя нагрузка.