Выборка всех документов из базы 1С — одна из самых частых задач, с которыми сталкиваются разработчики, администраторы и даже опытные пользователи. Казалось бы, что может быть проще: написать запрос ВЫБРАТЬ * ИЗ Документ.ИмяДокумента — и готово. Но на практике такой подход часто приводит к ошибкам, медленной работе или неполным данным. Почему?

Дело в том, что в 1С документы хранятся не так, как обычные таблицы в SQL. Они имеют иерархическую структуру, связанные табличные части, реквизиты, движения по регистрам — и всё это нужно учитывать при выборке. Кроме того, прямой запрос ко всем документам без фильтров может "подвесить" базу на крупных предприятиях, где накапливаются миллионы записей. В этой статье разберём 5 проверенных способов выбрать все документы в 1С — от элементарных до продвинутых, с примерами кода и пояснениями, когда какой метод применять.

Особое внимание уделим оптимизации запросов: как избежать полного сканирования таблиц, какие индексы использовать, и почему иногда лучше обойтись без SQL-аналогов. Все примеры актуальны для платформ 1С:Предприятие 8.3 и 8.2, но с учётом их особенностей.

📊 Как часто вы работаете с выборками документов в 1С?
Ежедневно
Несколько раз в неделю
Редко, по необходимости
Никогда не писал запросы сам

1. Базовый запрос: выборка всех документов одного типа

Начнём с самого простого — выборки всех документов конкретного вида, например, всех РеализацияТоваровУслуг. В большинстве случаев достаточно стандартного запроса:

ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

Документ.Дата КАК Дата,

Документ.Номер КАК Номер

ИЗ

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

Но даже здесь есть подводные камни:

  • 📌 Ограничение по правам: если у пользователя нет прав на чтение всех документов, запрос вернёт только те, к которым есть доступ. Это может ввести в заблуждение при отладке.
  • Производительность: на больших базах такой запрос выполняется долго. Например, выборка 50 000 документов может занять несколько минут.
  • 🔄 Движения документов: сам документ выбран, но его движения по регистрам (например, остатки товаров) — нет. Их нужно запрашивать отдельно.

Чтобы ускорить выполнение, добавьте фильтр по периоду, даже если вам нужны "все" документы. Например, за последние 5 лет:

ВЫБРАТЬ

Документ.Ссылка КАК Ссылка

ИЗ

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

ГДЕ

Документ.Дата >= ДАТАВРЕМЯ(2019, 1, 1)

⚠️ Внимание: Если вам действительно нужны все документы без исключения (например, для миграции данных), рассмотрите альтернативные методы: выгрузку через ЗагрузкаДанныхXML или специализированные обработки вроде "ВыгрузкаЗагрузкаДанныхXML". Прямой запрос к миллионам записей может заблокировать базу для других пользователей.

2. Выборка документов с табличными частями

Документы в 1С часто содержат табличные части — например, список товаров в РеализацияТоваровУслуг или услуги в АктВыполненныхРабот. Чтобы выбрать их вместе с документами, используйте конструкцию ЛЕВОЕ СОЕДИНЕНИЕ:

ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

Документ.Дата КАК Дата,

Товары.Номенклатура КАК Номенклатура,

Товары.Количество КАК Количество

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК Товары

ПО Документ.Ссылка = Товары.Ссылка

Важные нюансы:

  • 🔗 Связь по ссылке: табличные части присоединяются по полю Ссылка, а не по Номер или Дата. Это гарантирует корректное сопоставление даже при дублирующихся номерах.
  • 📊 Пустые строки: если в документе нет табличной части (например, пустой список товаров), ЛЕВОЕ СОЕДИНЕНИЕ всё равно вернёт сам документ, но с NULL в полях табличной части.
  • 🚀 Производительность: присоединение табличных частей значительно увеличивает время выполнения. Для ускорения ограничьте выборку только нужными полями.

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

ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

Товары.Номенклатура КАК Товар,

Услуги.Номенклатура КАК Услуга

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК Товары

ПО Документ.Ссылка = Товары.Ссылка

ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Услуги КАК Услуги

ПО Документ.Ссылка = Услуги.Ссылка

Указать все нужные табличные части в JOIN|Проверить связь по полю Ссылка|Ограничить выборку только необходимыми полями|Добавить фильтр по дате для ускорения-->

3. Выборка документов с движениями по регистрам

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

ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

ДвиженияТоваров.Номенклатура КАК Номенклатура,

ДвиженияТоваров.Количество КАК Количество

ИЗ

Документ.ПоступлениеТоваров КАК Документ

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(

&ДатаНачала, &ДатаОкончания,

Номенклатура В (

ВЫБРАТЬ РАЗЛИЧНЫЕ Товары.Номенклатура

ИЗ Документ.ПоступлениеТоваров.Товары КАК Товары

)

) КАК ДвиженияТоваров

ПО Документ.Ссылка = ДвиженияТоваров.Регистратор

Ключевые моменты:

  • 📈 Виртуальные таблицы: для регистров используются специальные виртуальные таблицы (Остатки, Обороты, ОстаткиИОбороты). Они автоматически учитывают движения документов.
  • 🔍 Фильтрация по регистратору: связь между документом и его движениями осуществляется по полю Регистратор, которое ссылается на документ.
  • Производительность: виртуальные таблицы могут тормозить. Всегда ограничивайте период (&ДатаНачала, &ДатаОкончания) и список номенклатуры.

Если вам нужны все движения документа, без привязки к конкретным регистрам, используйте общую виртуальную таблицу ДвиженияДокумента:

ВЫБРАТЬ

Движения.Регистратор КАК СсылкаНаДокумент,

Движения.Регистр КАК Регистр,

Движения.ВидыДвижений КАК ВидыДвижений

ИЗ

Регистр.ДвиженияДокумента КАК Движения

ГДЕ

Движения.Регистратор В (

ВЫБРАТЬ Ссылка

ИЗ Документ.ПоступлениеТоваров

)

⚠️ Внимание: Виртуальные таблицы ДвиженияДокумента и РегистрНакопления.ИмяРегистра.Остатки работают по-разному в 1С:Предприятие 8.2 и 8.3. В версии 8.2 некоторые конструкции могут не поддерживаться или требовать обходных путей (например, использование временных таблиц).

4. Оптимизированная выборка: пакетный режим и временные таблицы

При работе с большими объёмами данных (десятки тысяч документов) прямой запрос может заблокировать базу или выполняться слишком долго. В таких случаях используйте:

  1. Пакетный режим: разбивайте выборку на порции по 100–1000 документов.
  2. Временные таблицы: сохраняйте промежуточные результаты для ускорения.
  3. Индексы: добавляйте условия по индексированным полям (например, Дата, Организация).

Пример пакетной выборки с использованием временной таблицы:

// Создаём временную таблицу для результатов

Перем ТЗРезультаты;

ТЗРезультаты = Новый ТаблицаЗначений;

ТЗРезультаты.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("СсылкаНаДокумент.ПоступлениеТоваров"));

ТЗРезультаты.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));

// Запрашиваем документы порциями по 500 штук

ДатаНачала = '20200101';

Порция = 500;

ТекущаяПозиция = 0;

Пока Истина Цикл

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

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

"ВЫБРАТЬ ПЕРВЫЕ " + Порция + "

Документ.Ссылка КАК Ссылка,

Документ.Дата КАК Дата

ИЗ

Документ.ПоступлениеТоваров КАК Документ

ГДЕ

Документ.Дата >= &ДатаНачала

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

Документ.Дата

ИНДЕКСИРОВАТЬ ПО

Ссылка";

Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);

Если ТекущаяПозиция > 0 Тогда

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

И Документ.Дата > &ПоследняяДата";

Запрос.УстановитьПараметр("ПоследняяДата", ПоследняяДата);

КонецЕсли;

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

Если Результат.Пустой() Тогда

Прервать;

КонецЕсли;

// Добавляем результаты во временную таблицу

Выборка = Результат.Выбрать();

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

НоваяСтрока = ТЗРезультаты.Добавить();

НоваяСтрока.Ссылка = Выборка.Ссылка;

НоваяСтрока.Дата = Выборка.Дата;

ПоследняяДата = Выборка.Дата;

КонецЦикла;

ТекущаяПозиция = ТекущаяПозиция + Порция;

КонецЦикла;

Преимущества этого подхода:

  • Нет блокировок: база не "подвисает" на долго выполняемом запросе.
  • 🔄 Контроль над памятью: данные обрабатываются порциями, не перегружая сервер.
  • 🛠 Гибкость: можно добавлять логику обработки каждой порции (например, запись в файл или отправку на сервер).

Для ещё большей оптимизации используйте планы обмена или регламентные задания, если выборка нужна регулярно. Например, можно настроить фоновое задание, которое будет обновлять временную таблицу с документами раз в час.

💡

Если вам нужно выбрать документы для дальнейшей обработки в внешней системе (например, выгрузки в Excel или интеграции с сайтом), используйте формат JSON или XML. В 1С 8.3 для этого есть встроенные методы ЗаписатьJSON() и ЗаписатьXML(), которые работают быстрее, чем ручная сборка строк.

5. Альтернативные методы: обход коллекций и внешние обработки

Иногда запросы — не лучший вариант. Рассмотрим альтернативы:

Метод Когда использовать Пример кода Плюсы Минусы
Обход коллекции Документы Нужны все документы без фильтров, небольшая база
Выборка = Документы.ПоступлениеТоваров.Выбрать();

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

// Обработка

КонецЦикла;

Простота, не требует знания языка запросов Медленно на больших базах, нет фильтрации
Менеджер документов Нужны документы с определёнными реквизитами
Менеджер = Документы.ПоступлениеТоваров;

Выборка = Менеджер.ВыбратьДокументы(

ДатаНачала, ДатаОкончания,

Новый Структура("Организация", Организация));

Встроенная фильтрация, оптимизировано Ограниченная гибкость по сравнению с запросами
Внешняя обработка Сложные выборки, интеграция с другими системами
Обработка = ВнешниеОбработки.Создать("ВыгрузкаДокументов");

Обработка.ВыгрузитьДокументы(ТипДокумента, ДатаНачала, ДатаОкончания);

Максимальная гибкость, можно дорабатывать Требует установки обработки, поддержка
Прямой SQL-запрос Критичные по скорости операции, опытные разработчики
Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ |_Ref| КАК Ссылка ИЗ |_Document123|";

Максимальная скорость, доступ к "сырым" данным Риск нарушить целостность, зависимость от версии СУБД

Для большинства задач оптимальным решением будет комбинация запроса с фильтрами и временных таблиц. Однако в некоторых случаях альтернативные методы оказываются эффективнее:

  • 🔧 Обход коллекции удобен для небольших баз или когда нужно быстро протестировать логику.
  • 📤 Внешние обработки незаменимы для интеграции с другими системами (например, выгрузка документов в 1С:EDT или Bitrix24).
  • 🗃 Прямой SQL используйте только в крайних случаях — например, для восстановления данных после сбоя.
⚠️ Внимание: Прямые SQL-запросы к базе 1С (SELECT * FROM _Document123) могут нарушить целостность данных, если вы не учитываете особенности хранения ссылочных типов. Например, поле _Ref в SQL соответствует ссылке в 1С, но его структура зависит от версии платформы. Всегда тестируйте такие запросы на копии базы!

6. Типичные ошибки и как их избежать

Даже опытные разработчики допускают ошибки при выборке документов. Вот самые распространённые:

  • 🚫 Запрос без фильтров: выборка всех документов за весь период может "положить" базу. Всегда ограничивайте диапазон дат.
  • 🔗 Неправильная связь табличных частей: если соединить табличную часть не по Ссылка, а по Номер, получите некорректные данные (номера могут повторяться!).
  • 📉 Игнорирование индексов: фильтрация по неиндексированным полям (например, Комментарий) сильно тормозит запрос.
  • 🔄 Забытые транзакции: если запрос выполняется в транзакции, которая не закрывается, это блокирует таблицы для других пользователей.
  • 📂 Выборка ненужных полей: запрос ВЫБРАТЬ * возвращает все реквизиты, включая служебные. Указывайте только необходимые.

Пример неправильного запроса (медленного и опасного):

ВЫБРАТЬ *

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

Исправленный вариант:

ВЫБРАТЬ

Ссылка,

Дата,

Номер,

Контрагент

ИЗ

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

ГДЕ

Дата BETWEEN &ДатаНачала AND &ДатаОкончания

ИНДЕКСИРОВАТЬ ПО

Дата

Ещё одна типичная ошибка — игнорирование прав доступа. Если запрос выполняется от имени пользователя с ограниченными правами, он может вернуть не все документы, но без ошибки! Чтобы проверить это, временно назначьте себе роль ПолныеПрава и сравните результаты.

Что делать, если запрос выполняется слишком долго?

Если запрос к документам выполняется больше 30 секунд, попробуйте:

1. Разбить его на части (пакетная обработка).

2. Добавить фильтр по индексированному полю (например, Организация).

3. Использовать временные таблицы для промежуточных результатов.

4. Проверить план выполнения запроса в консоли администратора 1С.

5. Если ничего не помогает — перенести логику во внешнюю обработку или регламентное задание.

7. Продвинутые техники: объединение данных из нескольких документов

Часто требуется выбрать данные из разных типов документов — например, все Поступления и Реализации за период. Для этого используйте конструкцию ОБЪЕДИНИТЬ ВСЕ:

ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

Документ.Дата КАК Дата,

Документ.Номер КАК Номер,

"Поступление" КАК ТипДокумента

ИЗ

Документ.ПоступлениеТоваров КАК Документ

ГДЕ

Документ.Дата >= &ДатаНачала

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

Документ.Дата КАК Дата,

Документ.Номер КАК Номер,

"Реализация" КАК ТипДокумента

ИЗ

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

ГДЕ

Документ.Дата >= &ДатаНачала

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

// Создаём временную таблицу для результатов

ТЗОбъединенные = Новый ТаблицаЗначений;

ТЗОбъединенные.Колонки.Добавить("Ссылка");

ТЗОбъединенные.Колонки.Добавить("Дата");

ТЗОбъединенные.Колонки.Добавить("Тип");

ТЗОбъединенные.Колонки.Добавить("Сумма");

// Заполняем данными из Поступлений

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

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

"ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

Документ.Дата КАК Дата,

""Поступление"" КАК Тип,

Документ.СуммаДокумента КАК Сумма

ИЗ

Документ.ПоступлениеТоваров КАК Документ

ГДЕ

Документ.Дата >= &ДатаНачала";

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

Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);

Выборка = Результат.Выбрать();

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

ТЗОбъединенные.Добавить().Заполнить(Выборка);

КонецЦикла;

// Добавляем данные из Реализаций

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

"ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

Документ.Дата КАК Дата,

""Реализация"" КАК Тип,

Документ.СуммаДокумента КАК Сумма

ИЗ

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

ГДЕ

Документ.Дата >= &ДатаНачала";

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

Выборка = Результат.Выбрать();

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

ТЗОбъединенные.Добавить().Заполнить(Выборка);

КонецЦикла;

Этот подход позволяет:

  • 🔗 Объединять документы с разной структурой (например, у одного документа есть реквизит Поставщик, у другого — Покупатель).
  • ⚡ Обрабатывать данные порциями, не перегружая память.
  • 📊 Добавлять произвольную логику при объединении (например, конвертацию валют или расчёт дополнительных полей).

Если вам нужно объединить документы по какому-то общему признаку (например, по контрагенту), используйте ГРУППИРОВКА:

ВЫБРАТЬ

Документ.Контрагент КАК Контрагент,

СУММА(Документ.СуммаДокумента) КАК ОбщаяСумма,

КОЛИЧЕСТВО(*) КАК КоличествоДокументов

ИЗ

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

ГДЕ

Документ.Дата >= &ДатаНачала

СГРУППИРОВАТЬ ПО

Документ.Контрагент

💡

При объединении данных из разных документов всегда проверяйте совместимость типов полей. Например, поле СуммаДокумента может иметь разный тип в Поступлении и Реализации (число с разной точностью). Используйте функции приведения типов, например ЧИСЛО(Сумма, 10, 2).

FAQ: Ответы на частые вопросы

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

Для больших баз используйте пакетную обработку (выборка порциями по 100–1000 документов) или регламентные задания, которые будут выполняться в фоновом режиме. Альтернатива — выгрузка через ЗагрузкаДанныхXML или специализированные обработки вроде "ВыгрузкаЗагрузкаДанныхXML". Прямой запрос ко всем документам может заблокировать базу.

Пример пакетной выборки:

Порция = 1000;

ТекущаяПозиция = 0;

Пока Истина Цикл

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

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

// ... обработка результата

Если Результат.Пустой() Тогда Прервать; КонецЕсли;

КонецЦикла;

Почему запрос возвращает не все документы, хотя фильтров нет?

Это может происходить по трём причинам:

  1. Права доступа: у пользователя нет прав на просмотр всех документов. Проверьте роли в конфигураторе.
  2. Пометка на удаление: по умолчанию запросы не возвращают помеченные на удаление документы. Добавьте условие ГДЕ НЕ Документ.ПометкаУдаления.
  3. Транзакции: если запрос выполняется в транзакции, которая ещё не зафиксирована, он может не видеть свежие данные.

Чтобы проверить права, временно назначьте себе роль ПолныеПрава и выполните запрос заново.

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

Используйте виртуальные таблицы регистров. Пример для регистра накопления ТоварыНаСкладах:

ВЫБРАТЬ

Движения.Регистратор КАК СсылкаНаДокумент,

Движения.Номенклатура КАК Номенклатура,

Движения.Количество КАК Количество

ИЗ

РегистрНакопления.ТоварыНаСкладах.Обороты(

&ДатаНачала, &ДатаОкончания,

Номенклатура В (

ВЫБРАТЬ РАЗЛИЧНЫЕ Товары.Номенклатура

ИЗ Документ.ПоступлениеТоваров.Товары КАК Товары

)

) КАК Движения

Для бухгалтерских документов используйте виртуальные таблицы регистра бухгалтерии, например РегистрБухгалтерии.ХозРасчетный.Обороты().

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