Как подсчитать количество записей в форме списка справочника в 1С 7.7?

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

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

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

Метод 1. Фильтрация через список значений (ИспользоватьСписокЭлементов)

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

Давайте рассмотрим по шагам, как получить размер этого списка:


// Создаем список значений для фильтрации
СписокДляФильтра = СоздатьОбъект("СписокЗначений");

// Заполняем список нужными элементами (например, элементами определенной группы)
СпрНоменклатура = СоздатьОбъект("Справочник.Номенклатура");
СпрНоменклатура.ВыбратьЭлементы();
Пока СпрНоменклатура.ПолучитьЭлемент() = 1 Цикл
    Если СпрНоменклатура.РеквизитОтбора = ВыбЗначение Тогда
        СписокДляФильтра.ДобавитьЗначение(СпрНоменклатура.ТекущийЭлемент());
    КонецЕсли;
КонецЦикла;

// Накладываем фильтр на форму списка
ИспользоватьСписокЭлементов(СписокДляФильтра);

// Получаем точное количество строк на форме
КоличествоЗаписей = СписокДляФильтра.РазмерСписка();
Предупреждение("Количество показанных элементов: " + КоличествоЗаписей);

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

Метод 2. Стандартный отбор и подсчет через объект «Запрос»

Ситуация усложняется, если отбор в форме списка накладывается методом УстановитьОтбор. Стандартный механизм динамического списка 1С 7.7 не предоставляет разработчику свойства вроде КоличествоСтрок() для формы списка справочника. Если запустить перебор элементов справочника в цикле через ВыбратьЭлементы() с установленным фильтром, это приведет к серьезным задержкам (интерфейс «зависнет» на больших базах).

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

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


Функция ПолучитьКоличествоЭлементовСОтбором(ИмяРеквизита, ЗначениеРеквизита) Экспорт
    Запрос = СоздатьОбъект("Запрос");
    
    // Формируем текст запроса с агрегатной функцией Счетчик()
    ТекстЗапроса = 
    "|Текущий = Справочник.Номенклатура.ТекущийЭлемент;
    |Реквизит = Справочник.Номенклатура." + ИмяРеквизита + ";
    |Функция КолВо = Счетчик();
    |Условие(Реквизит = ЗначениеРеквизита);";
    
    Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
        Возврат Запрос.КолВо;
    Иначе
        Возврат 0;
    EndIf;
КонецФункции

Этот код работает на порядок быстрее, чем пообъектный обход справочника, и возвращает точное количество элементов, удовлетворяющих заданному критерию.

Метод 3. Прямые SQL-запросы через ВК «1С++» (для SQL-версий баз данных)

Если ваша база данных 1С 7.7 развернута на Microsoft SQL Server, то самым быстрым и современным решением будет отправка прямого SQL-запроса в обход стандартного движка DB-Engines платформы. Для этого используется внешняя компонента 1С++ и класс ODBCRecordset.

Давайте разберем этот процесс подробно. Прямой запрос считает количество записей на уровне SQL Server за миллисекунды, даже если в справочнике содержатся миллионы элементов. Нам понадобится метаописание таблицы справочника, которое компонента подставляет автоматически при использовании конструкции со знаком доллара $.

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


// Создаем объект для прямого доступа к базе SQL
ЗапросSQL = СоздатьОбъект("ODBCRecordset");

// Подготавливаем текст запроса
// $Справочник.Номенклатура - автоподстановка имени таблицы СУБД
// $Справочник.Номенклатура.ВидНоменклатуры - автоподстановка имени колонки реквизита
ТекстЗапроса = "
|SELECT COUNT(ID) as TotalCount 
|FROM $Справочник.Номенклатура (NOLOCK)
|WHERE $Справочник.Номенклатура.ВидНоменклатуры = :ВыбВид
|  AND IsFolder = 3
|";

ЗапросSQL.УстановитьТекстовыйПараметр("ВыбВид", ВыбранныйВидНоменклатуры);

// Выполняем запрос
ТабРезультата = ЗапросSQL.ВыполнитьИнструкцию(ТекстЗапроса);

КоличествоЗаписей = ТабРезультата.ПолучитьЗначение(1, "TotalCount");
Предупреждение("Количество отфильтрованных элементов (SQL): " + КоличествоЗаписей);

Обратите внимание на конструкцию IsFolder = 3. В физической структуре таблиц 1С 7.7 это условие означает выборку только элементов (не групп). Если вам нужно посчитать и группы тоже, это условие следует скорректировать.

Метод 4. Расчет количества для файловых баз (DBF) по размеру файла

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

Каждая таблица справочника хранится в файле с именем SC*.dbf (номер можно узнать в конфигураторе или программно через метаданные). Структура заголовка DBF-файла строго регламентирована стандартом dBase III:

  1. Первые 32 байта занимает заголовок файла.
  2. В байтах с 4 по 7 хранится 32-битное целое число, определяющее общее количество записей в таблице.
  3. В байтах с 8 по 9 записана длина заголовка (размер всех полей описания колонок).
  4. В байтах с 10 по 11 записана длина одной записи в байтах.

Зная это, мы можем считать заголовок файла напрямую с диска, используя объект ФС (Файловая система) или специализированные внешние компоненты для работы с бинарными файлами, и мгновенно извлечь количество строк. Однако важно помнить: этот метод вернет общее количество записей, включая те, которые помечены в СУБД как удаленные (но физически еще не стертые процедурой «Упаковка таблиц»).

Метод 5. Использование альтернативного элемента «Табличное Поле»

Для создания действительно отзывчивых интерфейсов опытные разработчики 1С 7.7 полностью отказываются от стандартных форм списков. С помощью связки внешних компонент 1С++ и FormEx на форму помещается элемент управления «ТабличноеПоле» (Grid).

В этом случае вывод данных полностью контролируется программным кодом:

  1. Данные из базы считываются прямым SQL-запросом (или штатным запросом) во временную ТаблицуЗначений.
  2. Пользователь может применять любые фильтры, которые перехватываются кодом 1С.
  3. При изменении отбора таблица значений мгновенно пересчитывается в памяти.
  4. Количество строк всегда доступно напрямую через свойство ТаблицаДанных.КоличествоСтрок() и выводится в статус-бар или текстовое поле формы.

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

← На главную