К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как в 1С выбрать все документы

Как выбрать все документы в 1С: запрос без условий, выборка через Выбрать(), отбор по периоду и виду документа. Примеры кода, типичные ошибки и проверка результата.

Задача «выбрать все документы» в 1С встречается в двух типовых ситуациях: при написании запроса в консоли или в модуле и при программном обходе документов через метод Выбрать() менеджера документа. В обоих случаях «все» почти всегда означает «все документы конкретного вида», а не буквально все документы базы — выборка по всем типам сразу потребует перебора метаданных и на больших базах выполняется долго.

Простейший вариант — запрос без секции ГДЕ: конструкция ВЫБРАТЬ Ссылка ИЗ Документ.РеализацияТоваровУслуг вернёт все существующие в базе документы этого вида, включая непроведённые и помеченные на удаление. Это важно понимать сразу: без дополнительных условий в выборку попадёт всё, что физически хранится в таблице.

Ниже разобраны оба подхода — через запрос и через метод Выбрать(), варианты отбора по периоду и статусу проведения, способ выбрать документы всех видов разом, а также типичные ошибки, из-за которых выборка возвращается пустой или неполной.

Выбор всех документов запросом

Запрос — основной инструмент выборки. Минимальный текст запроса, возвращающего все документы одного вида, выглядит так:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Док.Ссылка КАК Ссылка,

| Док.Номер КАК Номер,

| Док.Дата КАК Дата

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Док

|УПОРЯДОЧИТЬ ПО

| Док.Дата";

Результат = Запрос.Выполнить().Выбрать();

Отсутствие секции ГДЕ и есть условие «выбрать всё». В выборку попадут проведённые, непроведённые и помеченные на удаление документы. Если нужны только «живые» документы, добавьте отбор:

"ГДЕ

| Док.Проведен = ИСТИНА

| И НЕ Док.ПометкаУдаления"

Обход результата выполняется циклом Пока Результат.Следующий() Цикл. Внутри цикла доступны поля, перечисленные в секции ВЫБРАТЬ. Если нужно работать с документом как с объектом (менять реквизиты, перепроводить), получите объект через Результат.Ссылка.ПолучитьОбъект() — но учитывайте, что это дорогая операция, и делать её для каждой строки большой выборки следует только при реальной необходимости.

bsl
ВЫБРАТЬ Ссылка, Номер, Дата ИЗ Документ.ПоступлениеТоваровУслуг ГДЕ Проведен УПОРЯДОЧИТЬ ПО Дата

Выборка через метод Выбрать()

Второй способ — метод Выбрать() менеджера документов. Он удобен, когда не нужен сложный запрос, а требуется просто перебрать документы, например в регламентном задании или обработке:

Выборка = Документы.РеализацияТоваровУслуг.Выбрать();

Пока Выборка.Следующий() Цикл

Сообщить(Выборка.Номер);

КонецЦикла;

Вызов без параметров возвращает все документы вида. Метод принимает необязательные параметры: начало и конец интервала дат, отбор по реквизитам (структура) и порядок. Например, выборка за период:

Выборка = Документы.РеализацияТоваровУслуг.Выбрать(

НачалоМесяца(ТекущаяДатаСеанса()),

КонецМесяца(ТекущаяДатаСеанса()));

Отбор по реквизиту передаётся структурой: Новый Структура("Организация", ОрганизацияСсылка). Ограничение метода — отбор возможен только по равенству и только по реквизитам, для которых в конфигураторе включено индексирование или которые входят в критерий отбора. Для сложных условий (по сумме больше заданной, по виду операции из списка) используйте запрос.

Запрос или метод Выбрать()

Запрос

Подходит для сложных условий, соединений с другими таблицами, группировок и итогов. Требует написания текста запроса.

Метод Выбрать()

Подходит для простого перебора по периоду или одному реквизиту. Не поддерживает сложные условия и соединения.

Динамический список

Подходит для отображения документов пользователю в форме списка с произвольным отбором, а не для пакетной обработки.

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

На практике «все документы» почти всегда уточняется условиями. Самые частые из них:

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

Для отбора по периоду существует также виртуальная таблица границ, но в большинстве случаев достаточно условия МЕЖДУ. Если запрос используется в отчёте на СКД, период лучше передавать через параметры НачалоПериода и КонецПериода — они автоматически появятся в настройках отчёта.

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

Запрос не может обратиться сразу ко всем видам документов одной таблицей — у каждого вида своя таблица. Если нужно собрать документы всех видов (например, для поиска по номеру или аудита), переберите метаданные и выполните запрос по каждому виду:

Для Каждого МетаДок Из Метаданные.Документы Цикл

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Документ." + МетаДок.Имя;

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

// обработка

КонецЦикла;

КонецЦикла;

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

Проверка результата выборки

После выполнения запроса проверьте, что выборка не пустая и содержит ожидаемое количество строк. Метод РезультатЗапроса.Пустой() быстро покажет, есть ли данные, а Выбрать().Количество() — сколько строк вернулось (учтите: вызов Количество() на больших выборках может быть ресурсоёмким в некоторых СУБД).

Быстрый способ проверить запрос без написания кода — консоль запросов (в типовых конфигурациях на управляемых формах доступна как внешняя обработка, в инструментах разработчика — встроена). Вставьте текст запроса, задайте параметры и сравните количество строк с количеством документов в списке формы при тех же отборах.

Контрольные точки

Как проверить результат

Количество строк выборки
Норма

Совпадает с количеством документов в списке при тех же отборах

Тревожный признак

Выборка пустая или строк заметно меньше — проверьте условия и границы периода

Состав выборки
Норма

Есть проведённые и непроведённые документы, если отбор по статусу не задан

Тревожный признак

Пропали помеченные на удаление или документы на границах периода

Скорость выполнения
Норма

Запрос по индексированным полям выполняется быстро

Тревожный признак

Запрос «подвисает» — вероятно, условие по неиндексированному реквизиту на большой таблице

Типичные ошибки и ограничения

Чаще всего проблемы возникают не из-за синтаксиса, а из-за неверных предположений о данных:

  • Выборка «пустая», потому что в условии сравнивается составной тип или ссылка другого вида документа.
  • Использование ПолучитьОбъект() в цикле по десяткам тысяч документов — обработка работает часами и блокирует записи.
  • Перебор через Выбрать() с обходом по Следующий() без транзакции при параллельной записи — возможны блокировки и конфликты.
  • Попытка выбрать «все документы» через обращение к несуществующей общей таблице — такой таблицы нет, нужен перебор метаданных или журнал.
Типичные ошибки
01
Условие «Дата = &Дата» вместо диапазона — документы с другим временем не попадают в выборку
02
Забытый отбор по ПометкаУдаления — в обработку попадают мусорные документы и искажают итоги
03
Получение объекта для каждой строки выборки без необходимости — резкое падение производительности
04
Отбор в методе Выбрать() по неиндексированному реквизиту — ошибка исполнения или полное сканирование таблицы
Итог

Что важно запомнить

Все документы вида выбираются запросом без секции ГДЕ или методом Выбрать() без параметров. Уточняйте выборку периодом с корректными границами дат, статусом проведения и пометкой удаления. Для всех видов сразу перебирайте метаданные или используйте журнал документов, а массовые обработки сначала тестируйте на копии базы.

Частые вопросы

Как выбрать только проведённые документы?

Добавьте в запрос условие ГДЕ Проведен = ИСТИНА (достаточно ГДЕ Проведен). Учтите, что не все виды документов поддерживают проведение — для документов с отключённым проведением поле Проведен всегда ложно, и такое условие вернёт пустую выборку.

Как выбрать документы за текущий месяц?

Передайте в запрос параметры: НачалоМесяца(ТекущаяДатаСеанса()) и КонецМесяца(ТекущаяДатаСеанса()), а в тексте используйте условие ГДЕ Дата МЕЖДУ &Начало И &Конец. Функции НачалоМесяца и КонецМесяца доступны во встроенном языке.

Почему запрос без условий не возвращает все документы?

Наиболее вероятные причины: у текущего пользователя действует ограничение доступа к данным (RLS) на уровне записей, документы находятся в другой базе или вы смотрите не тот вид документа. Проверьте выборку под пользователем с полными правами.

Можно ли выбрать документы по подстроке в номере?

Да, через оператор ПОДОБНО: ГДЕ Номер ПОДОБНО "%00123%". Учтите, что номер документа — строка с лидирующими нулями, поэтому шаблон должен учитывать формат номера, а поиск по ПОДОБНО не использует индекс и на больших таблицах работает медленно.

Чем отличается Выгрузить() от Выбрать() у результата запроса?

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

Как выбрать документы, у которых есть движения по конкретному регистру?

Используйте соединение с таблицей регистра или условие ГДЕ Ссылка В (ВЫБРАТЬ Регистратор ИЗ РегистрНакопления.ИмяРегистра). Второй вариант проще: подзапрос вернёт всех регистраторов, у которых есть записи в регистре.