Как быстро получить количество строк в большом документе 1С 7.7: использование 1SQLite и оптимизация контекста

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с проблемой производительности при работе с документами, содержащими огромное количество строк (десятки и сотни тысяч). Стандартные методы, такие как КоличествоСтрок(), при вызове через объект могут выполняться крайне медленно — вплоть до нескольких минут. В этой статье мы разберем, как эффективно решать задачу подсчета строк с помощью внешней компоненты 1SQLite и как правильно работать с контекстом формы для получения оперативных данных.

Причина низкой производительности штатных методов

Прежде чем переходить к решениям, проанализируем ситуацию: почему стандартный метод КоличествоСтрок() работает так долго? Когда вы создаете объект через СоздатьОбъект("Документ.ВидДока"), находите нужный документ и вызываете метод КоличествоСтрок(), платформа 1С 7.7 выполняет полную десериализацию объекта. Это означает, что система считывает из базы данных абсолютно все реквизиты всех строк табличной части, чтобы полностью воссоздать объект в оперативной памяти. Если в документе 200 000 строк, это может потребовать загрузки сотен мегабайт данных, хотя вам нужно лишь одно число.

Решение 1: Использование 1SQLite для сохраненных документов

Если документ уже записан в базу данных, самым быстрым способом получить количество его строк является прямой SQL-запрос через компоненту 1SQLite. Этот метод не загружает данные строк в память 1С, а выполняет агрегатную функцию COUNT(*) непосредственно на уровне движка базы данных.

Рассмотрим пример кода для выполнения такого запроса:


База = СоздатьОбъект("SQLiteBase");
База.Открыть(":memory:"); // Или к файлу БД
Запрос = База.НовыйЗапрос();
ТекстЗапроса = "
|SELECT
|    COUNT(*) as Кво
|FROM
|    [ДокументСтроки.ВашВидДокумента] as Док
|WHERE
|    Док.IDDOC = :ТекДок";
Запрос.УстановитьПараметр("ТекДок", ВыбДок);
ТЗ = Запрос.Выполнить();
КвоСтрок = ТЗ.ПолучитьЗначение(1, "Кво");

Важный нюанс: Прямой запрос видит только те данные, которые уже физически записаны на диск (в файлы DBF или таблицы SQL). Если пользователь открыл документ, добавил 100 строк, но еще не нажал кнопку «Записать», 1SQLite об этих строках не узнает.

Решение 2: Оптимизация работы с контекстом формы

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

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


// В модуле формы документа
Кво = КоличествоСтрок(); // Работает мгновенно

Если же вам нужно получить данные извне, можно использовать «хак» с передачей контекста или параметров через ОткрытьФорму. Рассмотрим такой пример:


// Код в обработке, которой нужно узнать количество строк в открытом документе
Конт = "ПолучитьКво";
ОткрытьФорму(ВыбДок, Конт);
// В самом документе в ПриОткрытии():
Если Форма.Параметр = "ПолучитьКво" Тогда
    Форма.Параметр = КоличествоСтрок();
    СтатусВозврата(0); // Закрываем форму сразу, не отображая
    Возврат;
КонецЕсли;

Решение 3: Программный счетчик (Глобальная переменная)

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

  1. Создайте реквизит шапки ВсегоСтрок (числовой).
  2. В процедурах ПриЗаписи() или при интерактивном добавлении/удалении строк обновляйте это значение.
  3. При открытии формы инициализируйте переменную счетчика значением КоличествоСтрок().

Это позволит вам в любой момент мгновенно получить значение реквизита шапки, не прибегая к тяжелым вычислениям.

Сравнительный анализ производительности

Проанализируем результаты замеров для документа объемом 260 000 строк:

Использование FormEx для визуального контроля

В связке с 1SQLite часто используют расширение FormEx. Если документ открыт, вы можете обратиться к объекту TableBox, который управляет визуальным отображением строк. Через методы FormEx можно получить количество строк в табличном поле формы без обращения к объекту документа, что также работает крайне быстро и отражает текущее состояние «экранных» данных.

Резюме: Если документ закрыт — используйте 1SQLite. Если документ открыт и редактируется — используйте контекст формы. Никогда не используйте Объект.КоличествоСтрок() для документов с количеством строк более 10 000 в циклах или часто вызываемых процедурах.

← На главную