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