Выборка всех документов из базы 1С — одна из самых частых задач, с которыми сталкиваются разработчики, администраторы и даже опытные пользователи. Казалось бы, что может быть проще: написать запрос ВЫБРАТЬ * ИЗ Документ.ИмяДокумента — и готово. Но на практике такой подход часто приводит к ошибкам, медленной работе или неполным данным. Почему?
Дело в том, что в 1С документы хранятся не так, как обычные таблицы в SQL. Они имеют иерархическую структуру, связанные табличные части, реквизиты, движения по регистрам — и всё это нужно учитывать при выборке. Кроме того, прямой запрос ко всем документам без фильтров может "подвесить" базу на крупных предприятиях, где накапливаются миллионы записей. В этой статье разберём 5 проверенных способов выбрать все документы в 1С — от элементарных до продвинутых, с примерами кода и пояснениями, когда какой метод применять.
Особое внимание уделим оптимизации запросов: как избежать полного сканирования таблиц, какие индексы использовать, и почему иногда лучше обойтись без SQL-аналогов. Все примеры актуальны для платформ 1С:Предприятие 8.3 и 8.2, но с учётом их особенностей.
1. Базовый запрос: выборка всех документов одного типа
Начнём с самого простого — выборки всех документов конкретного вида, например, всех РеализацияТоваровУслуг. В большинстве случаев достаточно стандартного запроса:
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
Документ.Дата КАК Дата,
Документ.Номер КАК Номер
ИЗ
Документ.РеализацияТоваровУслуг КАК Документ
Но даже здесь есть подводные камни:
- 📌 Ограничение по правам: если у пользователя нет прав на чтение всех документов, запрос вернёт только те, к которым есть доступ. Это может ввести в заблуждение при отладке.
- ⚡ Производительность: на больших базах такой запрос выполняется долго. Например, выборка 50 000 документов может занять несколько минут.
- 🔄 Движения документов: сам документ выбран, но его движения по регистрам (например, остатки товаров) — нет. Их нужно запрашивать отдельно.
Чтобы ускорить выполнение, добавьте фильтр по периоду, даже если вам нужны "все" документы. Например, за последние 5 лет:
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК Документ
ГДЕ
Документ.Дата >= ДАТАВРЕМЯ(2019, 1, 1)
⚠️ Внимание: Если вам действительно нужны все документы без исключения (например, для миграции данных), рассмотрите альтернативные методы: выгрузку через ЗагрузкаДанныхXML или специализированные обработки вроде "ВыгрузкаЗагрузкаДанныхXML". Прямой запрос к миллионам записей может заблокировать базу для других пользователей.
2. Выборка документов с табличными частями
Документы в 1С часто содержат табличные части — например, список товаров в РеализацияТоваровУслуг или услуги в АктВыполненныхРабот. Чтобы выбрать их вместе с документами, используйте конструкцию ЛЕВОЕ СОЕДИНЕНИЕ:
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
Документ.Дата КАК Дата,
Товары.Номенклатура КАК Номенклатура,
Товары.Количество КАК Количество
ИЗ
Документ.РеализацияТоваровУслуг КАК Документ
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК Товары
ПО Документ.Ссылка = Товары.Ссылка
Важные нюансы:
- 🔗 Связь по ссылке: табличные части присоединяются по полю
Ссылка, а не поНомерилиДата. Это гарантирует корректное сопоставление даже при дублирующихся номерах. - 📊 Пустые строки: если в документе нет табличной части (например, пустой список товаров),
ЛЕВОЕ СОЕДИНЕНИЕвсё равно вернёт сам документ, но сNULLв полях табличной части. - 🚀 Производительность: присоединение табличных частей значительно увеличивает время выполнения. Для ускорения ограничьте выборку только нужными полями.
Если вам нужны все табличные части документа (например, и товары, и услуги), используйте несколько соединений:
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
Товары.Номенклатура КАК Товар,
Услуги.Номенклатура КАК Услуга
ИЗ
Документ.РеализацияТоваровУслуг КАК Документ
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК Товары
ПО Документ.Ссылка = Товары.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Услуги КАК Услуги
ПО Документ.Ссылка = Услуги.Ссылка
Указать все нужные табличные части в JOIN|Проверить связь по полю Ссылка|Ограничить выборку только необходимыми полями|Добавить фильтр по дате для ускорения-->
3. Выборка документов с движениями по регистрам
Документы в 1С не только хранят данные, но и формируют движения по регистрам (накопления, бухгалтерии, расчётов). Например, документ ПоступлениеТоваров создаёт движения в регистре ТоварыНаСкладах. Чтобы выбрать документы вместе с их движениями, используйте виртуальные таблицы:
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
ДвиженияТоваров.Номенклатура КАК Номенклатура,
ДвиженияТоваров.Количество КАК Количество
ИЗ
Документ.ПоступлениеТоваров КАК Документ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
&ДатаНачала, &ДатаОкончания,
Номенклатура В (
ВЫБРАТЬ РАЗЛИЧНЫЕ Товары.Номенклатура
ИЗ Документ.ПоступлениеТоваров.Товары КАК Товары
)
) КАК ДвиженияТоваров
ПО Документ.Ссылка = ДвиженияТоваров.Регистратор
Ключевые моменты:
- 📈 Виртуальные таблицы: для регистров используются специальные виртуальные таблицы (
Остатки,Обороты,ОстаткиИОбороты). Они автоматически учитывают движения документов. - 🔍 Фильтрация по регистратору: связь между документом и его движениями осуществляется по полю
Регистратор, которое ссылается на документ. - ⏳ Производительность: виртуальные таблицы могут тормозить. Всегда ограничивайте период (
&ДатаНачала,&ДатаОкончания) и список номенклатуры.
Если вам нужны все движения документа, без привязки к конкретным регистрам, используйте общую виртуальную таблицу ДвиженияДокумента:
ВЫБРАТЬ
Движения.Регистратор КАК СсылкаНаДокумент,
Движения.Регистр КАК Регистр,
Движения.ВидыДвижений КАК ВидыДвижений
ИЗ
Регистр.ДвиженияДокумента КАК Движения
ГДЕ
Движения.Регистратор В (
ВЫБРАТЬ Ссылка
ИЗ Документ.ПоступлениеТоваров
)
⚠️ Внимание: Виртуальные таблицыДвиженияДокументаиРегистрНакопления.ИмяРегистра.Остаткиработают по-разному в 1С:Предприятие 8.2 и 8.3. В версии 8.2 некоторые конструкции могут не поддерживаться или требовать обходных путей (например, использование временных таблиц).
4. Оптимизированная выборка: пакетный режим и временные таблицы
При работе с большими объёмами данных (десятки тысяч документов) прямой запрос может заблокировать базу или выполняться слишком долго. В таких случаях используйте:
- Пакетный режим: разбивайте выборку на порции по 100–1000 документов.
- Временные таблицы: сохраняйте промежуточные результаты для ускорения.
- Индексы: добавляйте условия по индексированным полям (например,
Дата,Организация).
Пример пакетной выборки с использованием временной таблицы:
// Создаём временную таблицу для результатов
Перем ТЗРезультаты;
ТЗРезультаты = Новый ТаблицаЗначений;
ТЗРезультаты.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("СсылкаНаДокумент.ПоступлениеТоваров"));
ТЗРезультаты.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));
// Запрашиваем документы порциями по 500 штук
ДатаНачала = '20200101';
Порция = 500;
ТекущаяПозиция = 0;
Пока Истина Цикл
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ " + Порция + "
Документ.Ссылка КАК Ссылка,
Документ.Дата КАК Дата
ИЗ
Документ.ПоступлениеТоваров КАК Документ
ГДЕ
Документ.Дата >= &ДатаНачала
УПОРЯДОЧИТЬ ПО
Документ.Дата
ИНДЕКСИРОВАТЬ ПО
Ссылка";
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Если ТекущаяПозиция > 0 Тогда
Запрос.Текст = Запрос.Текст + "
И Документ.Дата > &ПоследняяДата";
Запрос.УстановитьПараметр("ПоследняяДата", ПоследняяДата);
КонецЕсли;
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Прервать;
КонецЕсли;
// Добавляем результаты во временную таблицу
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
НоваяСтрока = ТЗРезультаты.Добавить();
НоваяСтрока.Ссылка = Выборка.Ссылка;
НоваяСтрока.Дата = Выборка.Дата;
ПоследняяДата = Выборка.Дата;
КонецЦикла;
ТекущаяПозиция = ТекущаяПозиция + Порция;
КонецЦикла;
Преимущества этого подхода:
- ⚡ Нет блокировок: база не "подвисает" на долго выполняемом запросе.
- 🔄 Контроль над памятью: данные обрабатываются порциями, не перегружая сервер.
- 🛠 Гибкость: можно добавлять логику обработки каждой порции (например, запись в файл или отправку на сервер).
Для ещё большей оптимизации используйте планы обмена или регламентные задания, если выборка нужна регулярно. Например, можно настроить фоновое задание, которое будет обновлять временную таблицу с документами раз в час.
Если вам нужно выбрать документы для дальнейшей обработки в внешней системе (например, выгрузки в Excel или интеграции с сайтом), используйте формат JSON или XML. В 1С 8.3 для этого есть встроенные методы ЗаписатьJSON() и ЗаписатьXML(), которые работают быстрее, чем ручная сборка строк.
5. Альтернативные методы: обход коллекций и внешние обработки
Иногда запросы — не лучший вариант. Рассмотрим альтернативы:
| Метод | Когда использовать | Пример кода | Плюсы | Минусы |
|---|---|---|---|---|
Обход коллекции Документы |
Нужны все документы без фильтров, небольшая база | |
Простота, не требует знания языка запросов | Медленно на больших базах, нет фильтрации |
| Менеджер документов | Нужны документы с определёнными реквизитами | |
Встроенная фильтрация, оптимизировано | Ограниченная гибкость по сравнению с запросами |
| Внешняя обработка | Сложные выборки, интеграция с другими системами | |
Максимальная гибкость, можно дорабатывать | Требует установки обработки, поддержка |
| Прямой SQL-запрос | Критичные по скорости операции, опытные разработчики | |
Максимальная скорость, доступ к "сырым" данным | Риск нарушить целостность, зависимость от версии СУБД |
Для большинства задач оптимальным решением будет комбинация запроса с фильтрами и временных таблиц. Однако в некоторых случаях альтернативные методы оказываются эффективнее:
- 🔧 Обход коллекции удобен для небольших баз или когда нужно быстро протестировать логику.
- 📤 Внешние обработки незаменимы для интеграции с другими системами (например, выгрузка документов в 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;
Пока Истина Цикл
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ " + Порция + " Ссылка ИЗ Документ.ИмяДокумента";
// ... обработка результата
Если Результат.Пустой() Тогда Прервать; КонецЕсли;
КонецЦикла;
Почему запрос возвращает не все документы, хотя фильтров нет?
Это может происходить по трём причинам:
- Права доступа: у пользователя нет прав на просмотр всех документов. Проверьте роли в конфигураторе.
- Пометка на удаление: по умолчанию запросы не возвращают помеченные на удаление документы. Добавьте условие
ГДЕ НЕ Документ.ПометкаУдаления. - Транзакции: если запрос выполняется в транзакции, которая ещё не зафиксирована, он может не видеть свежие данные.
Чтобы проверить права, временно назначьте себе роль ПолныеПрава и выполните запрос заново.
Как выбрать документы вместе с их движениями по регистрам?
Используйте виртуальные таблицы регистров. Пример для регистра накопления ТоварыНаСкладах:
ВЫБРАТЬ
Движения.Регистратор КАК СсылкаНаДокумент,
Движения.Номенклатура КАК Номенклатура,
Движения.Количество КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах.Обороты(
&ДатаНачала, &ДатаОкончания,
Номенклатура В (
ВЫБРАТЬ РАЗЛИЧНЫЕ Товары.Номенклатура
ИЗ Документ.ПоступлениеТоваров.Товары КАК Товары
)
) КАК Движения
Для бухгалтерских документов используйте виртуальные таблицы регистра бухгалтерии, например РегистрБухгалтерии.ХозРасчетный.Обороты().