Как в 1С:ERP выбрать все проведенные документы, по которым нет проводок?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При сопровождении и аудите базы 1С:ERP часто возникает задача выявления документов, которые имеют статус проведения, но не сформировали движений в регистре бухгалтерии Хозрасчетный. Разберем архитектурные особенности отражения операций в ERP, причины отсутствия проводок, а также технические и штатные способы решения этой задачи.

Особенности архитектуры учета в 1С:ERP

В отличие от классической 1С:Бухгалтерии, где проводки формируются непосредственно в момент нажатия кнопки проведения, в 1С:ERP реализована концепция отложенного проведения по регламентированному учету. При проведении документа формируются только оперативные регистры накопления, а проводки по регистру бухгалтерии создаются асинхронно — вручную пользователем или регламентным заданием.

Основные причины, почему документ может быть проведен, но не иметь проводок:

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

Способ 1. Использование штатного механизма отражения в учете

Прежде чем писать программный код или сложные запросы, обратим внимание на типовой функционал. В 1С:ERP предусмотрено специализированное рабочее место «Отражение документов в регламентированном учете».

В этом рабочем месте конфигурация сама классифицирует документы по статусам:

  1. Документы, ожидающие отражения в учете.
  2. Документы, требующие настройки счетов учета.
  3. Документы с ошибками проведения.

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

Способ 2. Программное построение динамического запроса по метаданным

Если требуется получить точный список ссылок через запрос (например, для внешней обработки или отчета), нельзя написать единый статический запрос без перечисления таблиц, так как в языке запросов 1С нет конструкции обращения сразу ко «всем документам».

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

Разберем по шагам, как правильно реализовать такой алгоритм:

  1. Получаем список объектов метаданных документов, входящих в состав регистраторов регистра бухгалтерии Хозрасчетный.
  2. Формируем текст запроса, объединяя выборки по каждому виду документа через ОБЪЕДИНИТЬ ВСЕ.
  3. Выполняем левое соединение с таблицей регистра бухгалтерии и отбираем записи, где регистратор равен NULL.

Посмотрим на пример кода генерации такого запроса:


ТекстЗапроса = "";
МассивРегистраторов = Метаданные.РегистрыБухгалтерии.Хозрасчетный.Регистраторы;

Для Каждого ДокументМетаданные Из МассивРегистраторов Цикл
    
    Если Не ПустаяСтрока(ТекстЗапроса) Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |ОБЪЕДИНИТЬ ВСЕ
        |";
    КонецЕсли;
    
    ТекстЗапроса = ТекстЗапроса + "
    |ВЫБРАТЬ
    |   Док.Ссылка КАК Документ,
    |   Док.Дата КАК Дата,
    |   ТИПЗНАЧЕНИЯ(Док.Ссылка) КАК ТипДокумента
    |ИЗ
    |   Документ." + ДокументМетаданные.Имя + " КАК Док
    |   ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
    |       ПО Док.Ссылка = Хозрасчетный.Регистратор
    |ГДЕ
    |   Док.Проведен = ИСТИНА
    |   И Хозрасчетный.Регистратор ЕСТЬ NULL";

КонецЦикла;

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

Пока Выборка.Следующий() Цикл
    // Обработка найденного документа
КонецЦикла;

Способ 3. Оптимизация запроса через временные таблицы и отбор по периоду

В ERP насчитывается более сотни видов документов-регистраторов. Единый запрос со 100+ секциями ОБЪЕДИНИТЬ ВСЕ и множественными соединениями может привести к долгой компиляции плана на сервере СУБД и значительному потреблению оперативной памяти.

Для оптимизации рекомендуется:

  1. Ограничивать период выборки: всегда добавлять фильтр по дате документа (например, за текущий месяц или квартал).
  2. Использовать временную таблицу существующих проводок: сначала выбрать во временную таблицу список всех уникальных регистраторов из регистра бухгалтерии за нужный период, а затем соединять таблицы документов с этой временной таблицей.
  3. Разбивать обработку на пакеты: если база содержит большой объем данных, обходить метаданные пачками по 20–30 типов документов либо формировать запрос в цикле по каждому типу отдельно.

Посмотрим на структуру оптимизированного запроса с временной таблицей существующих регистраторов:


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ РАЗЛИЧНЫЕ
|   Хозрасчетный.Регистратор КАК Регистратор
|ПОМЕСТИТЬ ВТ_РегистраторыСПроводками
|ИЗ
|   РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
|ГДЕ
|   Хозрасчетный.Период МЕЖДУ &ДатаНачала И &ДатаОкончания
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|   Док.Ссылка КАК Документ
|ИЗ
|   Документ.ПриобретениеТоваровУслуг КАК Док
|   ЛЕВОЕ СОЕДИНЕНИЕ ВТ_РегистраторыСПроводками КАК ВТ
|       ПО Док.Ссылка = ВТ.Регистратор
|ГДЕ
|   Док.Проведен = ИСТИНА
|   И Док.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
|   И ВТ.Регистратор ЕСТЬ NULL";

Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("ДатаОкончания", КонецДня(ДатаОкончания));
Результат = Запрос.Выполнить();

Такой подход обеспечивает высокую скорость выполнения и исключает перегрузку СУБД при работе с большими массивами учетных данных.

← На главную