Как получить список всех видов документов и их количество в базе 1С и SQL

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

В процессе сопровождения и аудита информационных баз 1С часто возникает задача оценить объем накопленных данных. Одной из ключевых метрик является количество документов каждого вида. Это необходимо для понимания динамики роста базы, поиска «мусорных» объектов или подготовки к свертке данных. В рамках данной статьи мы подробно разберем несколько способов получения этой информации: от универсальных запросов на встроенном языке 1С до прямых запросов к СУБД MS SQL.

Способ 1: Динамическое формирование запроса на языке 1С

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

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


Функция ПолучитьСтатистикуПоДокументам()
    Запрос = Новый Запрос;
    ТекстЗапроса = "";
    ПервыйДокумент = Истина;

    Для Каждого МетаданныеДокумента Из Метаданные.Документы Цикл
        
        ИмяДокумента = МетаданныеДокумента.Имя;
        Представление = МетаданныеДокумента.Синоним;
        Если ПустаяСтрока(Представление) Тогда
            Представление = ИмяДокумента;
        КонецЕсли;

        ШаблонЗапроса = 
        "ВЫБРАТЬ
        |   &ИмяДокумента КАК ВидДокумента,
        |   &Синоним КАК Представление,
        |   КОЛИЧЕСТВО(*) КАК Количество
        |ИЗ
        |   Документ." + ИмяДокумента + " КАК Таблица";

        Если Не ПервыйДокумент Тогда
            ТекстЗапроса = ТекстЗапроса + "
            |ОБЪЕДИНИТЬ ВСЕ
            |";
        КонецЕсли;

        ТекстЗапроса = ТекстЗапроса + СтрЗаменить(СтрЗаменить(ШаблонЗапроса, "&ИмяДокумента", """" + ИмяДокумента + """"), "&Синоним", """" + Представление + """");
        
        ПервыйДокумент = Ложь;
    КонецЦикла;

    Запрос.Текст = ТекстЗапроса + "
    |УПОРЯДОЧИТЬ ПО
    |   Количество УБЫВ";

    Возврат Запрос.Выполнить().Выгрузить();
КонецФункции

Важные замечания к этому способу:

  1. Ограничения SQL-сервера: В тяжелых конфигурациях (таких как ERP 2.5), где количество видов документов превышает несколько сотен, один огромный запрос с сотнями ОБЪЕДИНИТЬ ВСЕ может вызвать ошибку переполнения стека парсера SQL-сервера или превысить лимит на количество таблиц в запросе. В таких случаях мы рекомендуем разбивать выполнение на пакеты (например, по 50 документов) и объединять результаты в одну ТаблицаЗначений.
  2. Учет пометок на удаление: В приведенном примере подсчитываются все записи. Если вам нужно знать количество только «живых» документов, добавьте в шаблон условие ГДЕ ПометкаУдаления = ЛОЖЬ.
  3. Производительность: Хотя этот запрос и выполняет сканирование таблиц, для получения только количества он работает достаточно быстро, так как СУБД использует индексы.

Способ 2: Использование выборки в цикле (простой метод)

Если вам не нужен один общий результат для сортировки, а достаточно просто вывести список в консоль или лог, можно использовать объект ВыборкаИзРезультатаЗапроса внутри цикла. Этот метод менее требователен к памяти сервера 1С, так как не формирует гигантскую строку текста запроса.


Для Каждого ДокМета Из Метаданные.Документы Цикл
    ТекстЗапроса = "ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Кол ИЗ Документ." + ДокМета.Имя;
    Запрос = Новый Запрос(ТекстЗапроса);
    Результат = Запрос.Выполнить().Выбрать();
    Если Результат.Следующий() Тогда
        Сообщить(ДокМета.Имя + ": " + Результат.Кол);
    КонецЕсли;
КонецЦикла;

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

Способ 3: Прямой SQL-запрос для MS SQL Server

Для системных администраторов и разработчиков, имеющих доступ к консоли MS SQL Server Management Studio, существует способ мгновенного получения статистики. Этот метод работает на порядки быстрее, так как обращается к системным таблицам, хранящим количество строк в партициях таблиц.

Рассмотрим пример запроса, который выбирает данные из sys.partitions. Обратите внимание, что в 1С таблицы документов начинаются с префикса _Document.


SELECT 
    t.name AS [TableName],
    p.rows AS [RowCount]
FROM 
    sys.tables AS t
INNER JOIN      
    sys.partitions AS p ON t.object_id = p.object_id
WHERE 
    t.name LIKE '_Document%' 
    AND p.index_id IN (0, 1) -- 0: heap, 1: clustered index
ORDER BY 
    p.rows DESC;

Нюансы использования SQL:

Сводная таблица методов

Выясним, какой метод лучше выбрать в зависимости от ситуации:

  1. Для разового отчета в пользовательском режиме: Динамический запрос с ОБЪЕДИНИТЬ ВСЕ. Это дает возможность легко вывести результат в ТабличныйДокумент или на диаграмму.
  2. Для очень больших конфигураций (ERP): Попакетное выполнение запросов или перебор в цикле.
  3. Для мгновенного анализа огромных баз (ТБ): Прямой SQL-запрос к системным представлениям статистики.

Рассмотрим ситуацию с использованием PostgreSQL. Если ваша база работает под управлением этой СУБД, запрос к системным таблицам будет выглядеть иначе. Мы можем использовать таблицу pg_class, чтобы получить примерное количество строк (reltuples):


SELECT 
    relname AS table_name, 
    reltuples AS row_count 
FROM 
    pg_class 
WHERE 
    relname LIKE '_document%' 
ORDER BY 
    reltuples DESC;

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

← На главную