Запрос к документам 1С пишут почти в каждой доработке, от отчёта по продажам до выгрузки на сайт. Ниже — как выбрать документы за период, оставить только проведённые, отсечь помеченные на удаление, отобрать по организации и контрагенту и собрать несколько видов документов в одну выборку через ОБЪЕДИНИТЬ ВСЕ. Примеры построены на документах РеализацияТоваровУслуг и ПоступлениеТоваровУслуг: в УТ 11 и БП 3.0 они называются одинаково, и у обоих есть реквизиты Организация, Контрагент и СуммаДокумента. Платформа 8.3.
Кроме реквизитов, у таблицы документа есть стандартные поля, на них держится большинство условий.
| Поле | Тип | Для чего |
|---|---|---|
Ссылка | ДокументСсылка | сам документ; через точку доступны его реквизиты |
Дата | Дата, со временем | отбор за период |
Номер | Строка или Число | поиск по номеру; в типовых конфигурациях это строка с префиксом |
Проведен | Булево | только проведённые; поля нет, если проведение документа запрещено в конфигураторе |
ПометкаУдаления | Булево | исключить помеченные на удаление |
МоментВремени | МоментВремени | хронологическая сортировка, как в журнале |
Табличные части — отдельные таблицы вида Документ.РеализацияТоваровУслуг.Товары. В каждой строке есть поле Ссылка на документ-владелец, через него берут дату и признак проведения шапки. Если нужно освежить общие правила языка запросов, загляните в статью о синтаксисе запросов 1С.
Функция выбирает проведённые реализации организации за период, при необходимости — по одному или нескольким контрагентам, и возвращает таблицу значений. Её кладут в общий модуль с флагом «Сервер» (в примере — ДокументыПродажСервер) или в модуль объекта обработки.
// Проведённые реализации организации за период, без помеченных на удаление.
// Отбор по контрагентам необязательный: одна ссылка, массив или список значений.
// Размещение: общий модуль ДокументыПродажСервер (флаг «Сервер»)
// или модуль объекта обработки. Платформа 8.3.
// Имена объектов - как в УТ 11 и БП 3.0 (Документ.РеализацияТоваровУслуг).
// Возвращает ТаблицуЗначений: Ссылка, Дата, Номер, Контрагент, СуммаДокумента.
Функция ПроведенныеРеализацииЗаПериод(Знач ДатаНачала, Знач ДатаОкончания,
Знач Организация, Знач Контрагенты = Неопределено) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка КАК Ссылка,
| Реализация.Дата КАК Дата,
| Реализация.Номер КАК Номер,
| Реализация.Контрагент КАК Контрагент,
| Реализация.СуммаДокумента КАК СуммаДокумента
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода
| И Реализация.Проведен
| И НЕ Реализация.ПометкаУдаления
| И Реализация.Организация = &Организация
| И &УсловиеПоКонтрагентам
|
|УПОРЯДОЧИТЬ ПО
| Реализация.МоментВремени";
// Метка &УсловиеПоКонтрагентам заменяется текстом условия или ИСТИНА.
Если ОтборЗадан(Контрагенты) Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&УсловиеПоКонтрагентам",
"Реализация.Контрагент В (&Контрагенты)");
Запрос.УстановитьПараметр("Контрагенты", Контрагенты);
Иначе
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&УсловиеПоКонтрагентам", "ИСТИНА");
КонецЕсли;
// Дата документа хранится со временем: границы - начало и конец дня.
// Пустая дата окончания означает «без ограничения».
Если ЗначениеЗаполнено(ДатаОкончания) Тогда
КонецПериода = КонецДня(ДатаОкончания);
Иначе
КонецПериода = Дата(3999, 12, 31, 23, 59, 59);
КонецЕсли;
Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
Запрос.УстановитьПараметр("Организация", Организация);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
// Истина, если в отбор передано хотя бы одно значение.
Функция ОтборЗадан(Значение)
Если ТипЗнч(Значение) = Тип("Массив")
Или ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
Возврат Значение.Количество() > 0;
КонецЕсли;
Возврат ЗначениеЗаполнено(Значение);
КонецФункции
Дата МЕЖДУ &НачалоПериода И &КонецПериода — обе границы включаются, как при паре сравнений >= и <=.КонецДня(ДатаОкончания) — дата документа хранится со временем. Если передать 31.03 00:00:00, документы, записанные в этот день позже полуночи, в выборку не попадут. Подробно о границах периода и функциях дат — в статье про даты в запросе 1С.Реализация.Проведен — булево поле пишут в условии как есть, без = ИСТИНА.&УсловиеПоКонтрагентам — не параметр, а метка в тексте. Когда контрагенты не заданы, её заменяют на ИСТИНА, и отбор пропадает. Так в тексте не остаются конструкции вида (&Контрагент = ... ИЛИ ...), которые мешают СУБД использовать индекс.В (&Контрагенты) принимает одну ссылку, массив или список значений: когда отбор станет множественным, вызывающий код менять не придётся.УПОРЯДОЧИТЬ ПО Реализация.МоментВремени — хронологический порядок, как в журнале, в том числе для документов с одинаковым временем до секунды.Вызов из управляемой формы обработки. В тонком и веб-клиенте нет ни объекта Запрос, ни таблицы значений, поэтому клиентская процедура команды лишь передаёт управление серверной:
// Модуль формы обработки. Реквизиты формы: Период (СтандартныйПериод),
// Организация, Контрагент, СписокДокументов (ТаблицаЗначений с колонками
// Ссылка, Дата, Номер, Контрагент, СуммаДокумента).
&НаКлиенте
Процедура Заполнить(Команда)
ЗаполнитьНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьНаСервере()
Таблица = ДокументыПродажСервер.ПроведенныеРеализацииЗаПериод(
Период.ДатаНачала, Период.ДатаОкончания, Организация, Контрагент);
ЗначениеВРеквизитФормы(Таблица, "СписокДокументов");
КонецПроцедуры
Реквизит СписокДокументов создают заранее, с колонками как в результате запроса. Имя Документы не берите: реквизит перекроет глобальное свойство Документы, и обращения вида Документы.РеализацияТоваровУслуг в модуле формы перестанут работать.
Состояние документа описывают два флага, и из их сочетаний на практике нужны четыре варианта:
| Что нужно | Условие в ГДЕ |
|---|---|
| Только проведённые | Док.Проведен |
| Черновики: записаны, не проведены, не помечены | НЕ Док.Проведен И НЕ Док.ПометкаУдаления |
| Помеченные на удаление | Док.ПометкаУдаления |
| Все, кроме помеченных | НЕ Док.ПометкаУдаления |
Отдельный вопрос — пометка удаления в запросе 1С: нужно ли к Проведен добавлять НЕ ПометкаУдаления? При установке пометки на проведённый документ платформа отменяет его проведение, поэтому в штатной работе проведённый и одновременно помеченный документ не встречается. Второе условие ничего не ломает и страхует от данных, пришедших в обход обычной логики записи, например по обмену. В отчётах по деньгам я оставляю оба.
Условия дописываются в секцию ГДЕ к отбору по дате и проведению. Самые ходовые:
| Задача | Условие |
|---|---|
| Один контрагент | Реализация.Контрагент = &Контрагент |
| Несколько контрагентов | Реализация.Контрагент В (&Контрагенты) |
| Группа справочника вместе с вложенными | Реализация.Контрагент В ИЕРАРХИИ (&Группа) |
| Документы без контрагента | Реализация.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка) |
| По реквизиту контрагента | Реализация.Контрагент.ИНН = &ИНН |
| По виду операции (УТ 11) | Реализация.ХозяйственнаяОперация = ЗНАЧЕНИЕ(Перечисление.ХозяйственныеОперации.РеализацияКлиенту) |
Пустые ссылки и значения перечислений в тексте запроса задают через функцию ЗНАЧЕНИЕ(), подробнее о ней — в статье о функции ЗНАЧЕНИЕ в запросе. Обращение через точку (Контрагент.ИНН) платформа превращает в соединение с таблицей справочника. Для реквизита одного типа это дёшево. Для поля составного типа, например ДокументОснование, соединение строится с таблицей каждого возможного типа, и запрос заметно тяжелеет. Там сначала уточняют тип: ВЫРАЗИТЬ(Док.ДокументОснование КАК Документ.ЗаказКлиента).Дата.
В запросе по документам 1С 8.3 табличная часть — самостоятельный источник. Условия на шапку накладывают через поле Ссылка. Пример: какие товары и на какую сумму продала организация за период.
ВЫБРАТЬ
Товары.Номенклатура КАК Номенклатура,
СУММА(Товары.Количество) КАК Количество,
СУММА(Товары.Сумма) КАК Сумма,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Товары.Ссылка) КАК ЧислоДокументов
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
И Товары.Ссылка.Проведен
И Товары.Ссылка.Организация = &Организация
СГРУППИРОВАТЬ ПО
Товары.Номенклатура
УПОРЯДОЧИТЬ ПО
Сумма УБЫВ
Товары.Ссылка.Проведен — неявное соединение с шапкой документа, обычный способ отбора по реквизитам шапки. КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Товары.Ссылка) считает документы, а не строки. Если нужны только суммы за длинный период, в типовых конфигурациях их быстрее взять из регистров накопления.
Общей таблицы «все документы» в запросе нет, каждый вид документа — своя таблица. Чтобы получить, например, историю работы с контрагентом, который и покупает, и поставляет, выборки из разных документов склеивают:
ВЫБРАТЬ
Реализация.Ссылка КАК Документ,
Реализация.Дата КАК Дата,
"Продажа" КАК ВидОперации,
Реализация.Организация КАК Организация,
Реализация.СуммаДокумента КАК Сумма
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода
И Реализация.Проведен
И Реализация.Контрагент = &Контрагент
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Поступление.Ссылка,
Поступление.Дата,
"Закупка",
Поступление.Организация,
Поступление.СуммаДокумента
ИЗ
Документ.ПоступлениеТоваровУслуг КАК Поступление
ГДЕ
Поступление.Дата МЕЖДУ &НачалоПериода И &КонецПериода
И Поступление.Проведен
И Поступление.Контрагент = &Контрагент
УПОРЯДОЧИТЬ ПО
Дата
ОБЪЕДИНИТЬ без ВСЕ убирает одинаковые строки и тратит на это время. У разных документов ссылки всегда разные, так что для документов нужен ОБЪЕДИНИТЬ ВСЕ.УПОРЯДОЧИТЬ ПО пишут один раз в конце, он действует на весь результат и использует имена полей из первой части.Документ получается составного типа, а строка ВидОперации избавляет от проверки ТипЗнч() и сразу годится для отчёта.Если нужные виды входят в журнал документов, его можно выбрать как одну таблицу, но из реквизитов будут доступны только сопоставленные графам журнала.
КонецДня().Реализация.Контрагент это значит, что реквизит в вашей конфигурации называется иначе. Для Реализация.Проведен — что проведение документа запрещено. Сверьте имена в конструкторе запроса.УстановитьПараметр() или в имени опечатка. Каждый параметр из текста запроса должен быть установлен.ОБЪЕДИНИТЬ ВСЕ добавили поле, а в другую забыли. Если в каком-то документе нужного реквизита нет, подставьте на его место NULL или пустое значение.Новый Запрос написан в клиентской процедуре управляемой формы (&НаКлиенте). В тонком и веб-клиенте объекта Запрос нет, поэтому запрос выполняют на сервере: в процедуре с директивой &НаСервере, &НаСервереБезКонтекста или в серверном общем модуле. В обычном приложении с обычными формами (толстый клиент) запрос работает и на клиенте.ВЫБРАТЬ РАЗРЕШЕННЫЕ: недоступные документы просто не попадут в выборку. В запросах, от которых зависит результат операции (проверка при проведении, перепроведение, контроль перед закрытием месяца), РАЗРЕШЕННЫЕ не ставят: скрытые документы молча выпадут, и у разных пользователей результат окажется разным. Там выдают права на чтение или прерывают операцию с сообщением о нехватке прав. Если непонятно, почему пользователь видит не то, что должен, — это задача на настройку прав доступа.В типовых конфигурациях номер — строка с префиксом организации или информационной базы, поэтому Номер = "125" ничего не найдёт. Для поиска по хвосту подойдёт Номер ПОДОБНО "%125", но под шаблон попадёт и 1125, так что добавляйте отбор по дате: номера уникальны только в пределах периода нумерации. Шаблоны и строковые функции разобраны в статье про строки в запросе 1С.
Соберите текст программно: обойдите Метаданные.Документы, для каждого вида добавьте часть с отбором по дате и склейте части через ОБЪЕДИНИТЬ ВСЕ. Поля Проведен у непроводимых документов нет, поэтому условие на него добавляйте, только если МетаДок.Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить. В типовой конфигурации видов документов много, запрос получится тяжёлым, поэтому отбор по дате нужен в каждой части.
Да, текст вставляется в набор данных «Запрос», параметры появятся на вкладке «Параметры» сами. Метка &УсловиеПоКонтрагентам там не нужна: необязательные отборы в СКД оставляют пользователю через настройки отчёта.
Для сумм и количеств за период — регистр: данные уже сгруппированы по нужным измерениям, а у регистров накопления есть итоги. Документы читают, когда нужен сам список: номера, комментарии, ответственные и другие реквизиты, которых в регистре нет.
Если нужен не один запрос, а отчёт с отборами, группировками и расшифровкой до документа или обработка, которая по выборке что-то меняет в документах, её быстрее сделает программист, знающий вашу конфигурацию. Опишите, какие документы и за какой период нужны, и разместите задачу на 1c-only.ru — оценка бесплатная, ответ в течение рабочего дня. Подробнее об услуге — отчёты и обработки 1С.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.