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

Важно понимать, что выбор метода зависит от контекста: для таблицы значений в памяти подойдёт один подход, для регистра сведений в базе данных — другой, а при работе с динамическими списками в управляемых формах потребуются особые приёмы. Мы разберём каждый сценарий с примерами кода, предупреждениями о типичных ошибках и советами по оптимизации. Если вы когда-либо сталкивались с ситуацией, когда Таблица.Количество() возвращает неожиданный результат или запрос выполняется слишком долго — здесь вы найдёте объяснения и решения.

1. Базовый метод: функция Количество() для таблиц значений

Самый простой способ узнать количество строк — использовать встроенную функцию Количество() для объекта ТаблицаЗначений. Этот метод работает мгновенно, так как оперирует данными, уже загруженными в память. Пример:

Таблица = Новый ТаблицаЗначений;

Таблица.Колонки.Добавить("Наименование");

Таблица.Колонки.Добавить("Количество");

Таблица.Добавить();

Таблица.Добавить();

Таблица.Добавить();

Сообщить(Таблица.Количество()); // Вернёт 3

Однако здесь есть нюансы:

  • 🔹 Функция Количество() возвращает физическое количество строк, включая пустые (если они были добавлены явно).
  • 🔹 Для динамических списков в управляемых формах этот метод не подходит — он вернёт количество строк, отображаемых на текущей странице, а не общее число записей.
  • 🔹 Если таблица связана с источником данных (например, запросом), функция может вернуть 0 до момента фактической загрузки данных.
💡

Чтобы избежать ошибок, всегда проверяйте, инициализирована ли таблица перед вызовом Количество(). Используйте конструкцию Если Таблица <> Неопределено Тогда.

2. Подсчёт строк в запросе: ВЫБРАТЬ КОЛИЧЕСТВО()

Когда данные хранятся в базе (справочники, документы, регистры), самый эффективный способ — использовать язык запросов 1С. Конструкция ВЫБРАТЬ КОЛИЧЕСТВО(*) вернёт точное число записей, соответствующих условиям отбора. Пример для справочника Номенклатура:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| НЕ Номенклатура.ПометкаУдаления";

Результат = Запрос.Выполнить();

КоличествоСтрок = Результат.Выбрать().Количество; // 1250 (пример)

Преимущества метода:

  • 🚀 Работает напрямую с базой данных, не загружая все строки в память.
  • 🎯 Поддерживает сложные условия отбора (по датам, реквизитам, связям с другими таблицами).
  • 📊 Можно комбинировать с группировкой: ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК КолВо, Номенклатура.ВидыНоменклатуры КАК Вид....
⚠️ Внимание: При работе с большими таблицами (миллионы записей) запрос КОЛИЧЕСТВО(*) может выполняться долго. В таких случаях используйте виртуальные таблицы или оптимизируйте индексы.

Использовать индексируемые поля в условиях ГДЕ|

Ограничить период дат, если это возможно|

Избегать SELECT * — указывать только нужные колонки|

Проверить права доступа к данным-->

3. Работа с динамическими списками в управляемых формах

Динамические списки — это элементы интерфейса, которые подгружают данные порциями (постранично). Здесь Количество() вернёт только число строк на текущей странице. Чтобы получить общее количество записей, используйте свойство ВсегоСтрок:

// В модуле формы

Процедура КнопкаПосчитатьНажатие(Кнопка)

Сообщить(ЭлементыФормы.СписокНоменклатуры.ВсегоСтрок);

КонецПроцедуры

Особенности метода:

  • 📱 Работает только для управляемых форм (не подходит для обычных форм 8.2).
  • 🔄 Если список имеет отбор, ВсегоСтрок учтёт только видимые записи.
  • ⚡ Для больших списков (более 10 000 строк) может возникать задержка при первом обращении.

Если нужно посчитать строки с учётом пользовательских отборов, используйте комбинацию:

Отбор = ЭлементыФормы.СписокНоменклатуры.Отбор;

Запрос = Новый Запрос("ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ Справочник.Номенклатура КАК Номенклатура");

Запрос.Текст = Запрос.Текст + Отбор.ПолучитьТекстЗапроса();

Количество = Запрос.Выполнить().Выбрать().Количество;

4. Альтернативные методы: Цикл и Счетчик

В некоторых случаях (например, при работе с массивами или коллекциями) удобно использовать ручной подсчёт через цикл. Этот метод универсален, но менее эффективен для больших объёмов данных:

Таблица = ПолучаемТаблицуЗначений(); // Предполагаем, что данные уже загружены

Счетчик = 0;

Для Каждого Строка Из Таблица Цикл

Счетчик = Счетчик + 1;

КонецЦикла;

Сообщить(Счетчик);

Когда это актуально:

  • 🔧 Нужно не только посчитать строки, но и обработать каждую запись (например, проверить значения).
  • 🧩 Работа с нестандартными структурами (вложенные таблицы, массивы массивов).
  • 📝 Требуется логирование или дополнительные действия для каждой строки.
⚠️ Внимание: Для таблиц с более чем 10 000 строк цикл может значительно замедлить выполнение. В таких случаях лучше использовать ВЫБРАТЬ КОЛИЧЕСТВО() в запросе.
📊 Какой метод подсчёта строк вы используете чаще?
Функция Количество()
Запрос с КОЛИЧЕСТВО(*)
Свойство ВсегоСтрок
Цикл и счётчик

5. Продвинутые техники: Виртуальные таблицы и временные таблицы

Для оптимизации работы с большими объёмами данных в 1С:Предприятие 8.3 используются виртуальные таблицы и временные таблицы. Они позволяют уменьшить нагрузку на сервер и ускорить подсчёт.

Пример с виртуальной таблицей остатков:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(RAZNOST) КАК КоличествоУникальныхЗаписей

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаОтчета, ) КАК Остатки

|ГДЕ

| Остатки.Количество > 0";

Запрос.УстановитьПараметр("ДатаОтчета", ТекущаяДата());

Результат = Запрос.Выполнить();

Сравнение методов:

Метод Скорость Память Применимость
Количество() ⚡ Мгновенно 🟢 Низкая Таблицы значений в памяти
ВЫБРАТЬ КОЛИЧЕСТВО(*) 🟡 Зависит от индексов 🟢 Низкая Любые таблицы БД
ВсегоСтрок 🟡 Медленно для больших списков 🟢 Низкая Динамические списки
Цикл + Счетчик 🐢 Медленно 🔴 Высокая Обработка каждой строки
Виртуальные таблицы ⚡ Быстро 🟢 Низкая Регистры, большие данные
Почему виртуальные таблицы быстрее?

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

6. Типичные ошибки и как их избежать

Даже опытные разработчики иногда сталкиваются с неожиданными результатами при подсчёте строк. Вот самые распространённые ошибки:

  • 🚫 Игнорирование пометки удаления: Запрос ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ Справочник.Контрагенты вернёт все записи, включая помеченные на удаление. Всегда добавляйте условие ГДЕ НЕ ПометкаУдаления.
  • 🚫 Путаница с динамическими списками: Метод Количество() для элемента формы ТабличноеПоле вернёт количество видимых строк, а не всех данных источника.
  • 🚫 Неучёт прав доступа: Если у пользователя нет прав на просмотр части данных, запрос КОЛИЧЕСТВО(*) может вернуть заниженное значение. Проверяйте роли!
  • 🚫 Забывают про транзакции: При подсчёте строк в транзакции результат может отличаться от фактического состояния базы (если транзакция ещё не зафиксирована).

Как отладить проблемный подсчёт:

  1. Проверьте, совпадает ли количество строк в консоли запросов и в вашем коде.
  2. Используйте ПояснитьЗапрос(), чтобы увидеть план выполнения:
  3. Убедитесь, что отборы в запросе и в динамическом списке идентичны.
  4. Для больших таблиц тестируйте запрос на тестовой базе с аналогичным объёмом данных.
💡

Всегда проверяйте подсчёт строк на тестовых данных перед использованием в рабочей базе — особенно если запрос содержит сложные условия или соединения таблиц.

7. Оптимизация производительности при подсчёте

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

  • 🛠️ Индексируйте поля, используемые в условиях ГДЕ: Например, для запроса по датам добавьте индекс на реквизит ДатаДокумента.
  • 🗃️ Разбивайте большие запросы: Вместо одного запроса на миллион записей используйте пакетную обработку (например, по месяцам).
  • 🔄 Кэшируйте результаты: Если количество строк нужно часто, сохраняйте его в регистре сведений и обновляйте по расписанию.
  • 📊 Используйте материализованные представления: В PostgreSQL или MS SQL можно создать представление с предварительно посчитанными агрегатами.

Пример оптимизированного запроса:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК КолВо

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода

| И Реализация.Организация = &Организация";

Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));

Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДата()));

Запрос.УстановитьПараметр("Организация", Справочники.Организации.НашаФирма);

Результат = Запрос.Выполнить();

⚠️ Внимание: В кластерных базах (например, с использованием 1С:ГИС или распределённых информационных баз) подсчёт строк может давать разные результаты на разных узлах. В таких случаях используйте центральный сервер отчётности.

FAQ: Частые вопросы о подсчёте строк в 1С

Можно ли узнать количество строк в таблице без запроса к базе?

Да, но только если данные уже загружены в память. Для ТаблицыЗначений используйте Таблица.Количество(), для МассиваМассив.Количество(). Однако для данных, хранящихся в базе (справочники, документы, регистры), без запроса не обойтись.

Почему запрос КОЛИЧЕСТВО(*) выполняется долго?

Это типичная проблема для больших таблиц (более 1 млн записей). Причины:

  • Отсутствуют индексы на поля, используемые в условиях ГДЕ.
  • Запрос сканирует всю таблицу (например, если нет ограничения по дате).
  • СУБД (MS SQL, PostgreSQL) не оптимизирует запрос из-за сложной структуры.

Решение: добавьте индексы, ограничьте период данных или используйте виртуальные таблицы.

Как посчитать строки в табличной части документа?

Для табличной части документа (например, Товары в РеализацииТоваровУслуг) используйте:

КоличествоСтрок = ДокументОбъект.Товары.Количество();

Если нужно посчитать строки с ненулевым количеством:

Счетчик = 0;

Для Каждого Строка Из ДокументОбъект.Товары Цикл

Если Строка.Количество > 0 Тогда

Счетчик = Счетчик + 1;

КонецЕсли;

КонецЦикла;

В чём разница между КОЛИЧЕСТВО(*) и КОЛИЧЕСТВО(Поле)?

КОЛИЧЕСТВО(*) подсчитывает все строки, соответствующие условиям, включая те, где поля содержат NULL. КОЛИЧЕСТВО(Поле) считает только строки, где указанное поле не равно NULL.

Пример:

// Вернёт количество НЕпустых значений в колонке "Телефон"

ВЫБРАТЬ КОЛИЧЕСТВО(Контрагент.Телефон) ИЗ Справочник.Контрагенты

Можно ли посчитать строки в отчёте (СКД)?

Да, в Системе Компоновки Данных (СКД) количество строк доступно через:

  • Свойство Результат.Вывод.КоличествоСтрок после выполнения отчёта.
  • Или через запрос к временной таблице результата (если нужно посчитать строки с определёнными условиями).

Пример:

Отчет = Отчеты.Продажи.Создать();

Отчет.Компоновать();

КоличествоСтрок = Отчет.Результат.Вывод.КоличествоСтрок;