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

В этой статье мы разберём 5 проверенных способов подсчёта строк в 1С 8.3 и 1С 8.2, включая встроенные методы платформы, SQL-запросы, программный код на встроенном языке, а также нюансы работы с фильтрами и группировками. Особое внимание уделим производительности каждого метода — это критично при работе с большими объёмами данных.

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

1. Встроенные методы платформы: Количество() и Count()

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

Для таблицы значений или табличной части документа применяется метод Количество():

КоличествоСтрок = ТаблицаЗначений.Количество();

Если вы работаете с динамическим списком (например, в форме списка справочника), используйте свойство Count коллекции ВыбранныеСтроки:

КоличествоСтрок = ЭлементыФормы.Список.ВыбранныеСтроки.Count();
  • Плюсы: минимальный код, высокая скорость выполнения, не требует прав на изменение данных.
  • ⚠️ Ограничения: не учитывает фильтры, применённые к динамическому списку (вернёт общее количество строк, а не отфильтрованных).
  • 🔄 Альтернатива: для динамических списков с фильтрами лучше использовать метод ПолучитьДанные() (см. раздел 3).
💡

Если вам нужно посчитать строки в табличной части документа до его записи, используйте метод Количество() непосредственно перед сохранением. После записи количество строк может измениться из-за обработчиков событий!

2. Подсчёт строк через запрос на языке 1С

Когда требуется гибкость — например, посчитать строки с учётом условий или агрегации — на помощь приходят запросы на встроенном языке. Этот метод универсален и работает с любыми источниками данных: справочниками, документами, регистрами.

Базовый синтаксис для подсчёта всех строк в таблице:

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

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

"ВЫБРАТЬ

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

|ИЗ

| Документ.ЗаказыПокупателей КАК Заказы";

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

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

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

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

"ВЫБРАТЬ

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

|ИЗ

| Документ.ЗаказыПокупателей КАК Заказы

|ГДЕ

| Заказы.Дата МЕЖДУ &НачалоМесяца И &КонецМесяца

| И Заказы.Оплачен = ИСТИНА";

Как ускорить выполнение запроса?

Для больших таблиц (100 000+ строк) используйте индексированные поля в условиях фильтрации. Например, если в запросе есть условие по полю Дата, убедитесь, что оно проиндексировано в конфигураторе. Также избегайте функций в условиях (например, ГОД(Заказы.Дата) = 2023) — они блокируют использование индексов.

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

3. Работа с динамическими списками: метод ПолучитьДанные()

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

Чтобы получить точное количество строк с учётом всех применённых фильтров, используйте метод ПолучитьДанные():

ДанныеСписка = ЭлементыФормы.СписокТоваров.ПолучитьДанные();

КоличествоСтрок = ДанныеСписка.Количество();

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

  • 🔍 Фильтры применяются: результат будет соответствовать текущим условиям отбора в списке.
  • Производительность: при большом количестве данных выполнение может занять время (особенно если в списке включены группировки).
  • 📊 Группировки: если в динамическом списке настроены группировки, метод вернёт количество групп, а не строк. Чтобы получить детализированные данные, отключите группировку программно:
ЭлементыФормы.СписокТоваров.Группировки.Очистить();

ДанныеСписка = ЭлементыФормы.СписокТоваров.ПолучитьДанные();

📊 Какой способ подсчёта строк вы используете чаще?
Встроенные методы (Количество(), Count)
Запросы на языке 1С
ПолучитьДанные() для динамических списков
Программный обход строк
Другой вариант

4. Программный обход строк: когда стандартные методы не подходят

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

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

Счётчик = 0;

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

Если Строка.Сумма > 1000 Тогда

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

КонецЕсли;

КонецЦикла;

Для динамических списков можно обойти коллекцию ВыбранныеСтроки:

Счётчик = 0;

Для Каждого Строка Из ЭлементыФормы.Список.ВыбранныеСтроки Цикл

Если НЕ Строка.ПометкаУдаления Тогда

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

КонецЕсли;

КонецЦикла;

Инициализируйте счётчик до цикла (Счётчик = 0)

Учитывайте пометки удаления, если работаете с справочниками/документами

Для больших таблиц (>10 000 строк) используйте Прервать для оптимизации

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

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

5. Подсчёт строк в табличных частях документов и справочников

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

Способ 1. Подсчёт всех строк (включая пустые):

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

Способ 2. Подсчёт только заполненных строк (игнорируем пустые):

Счётчик = 0;

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

Если НЕ ЗначениеЗаполнено(Строка.Номенклатура) Тогда

Продолжить;

КонецЕсли;

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

КонецЦикла;

Способ 3. Подсчёт с учётом пометок удаления:

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

КоличествоУдалённых = 0;

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

Если Строка.ПометкаУдаления Тогда

КоличествоУдалённых = КоличествоУдалённых + 1;

КонецЕсли;

КонецЦикла;

ФактическоеКоличество = КоличествоСтрок - КоличествоУдалённых;

💡

При работе с табличными частями документов всегда проверяйте настройку "Автозаполнение" — если она включена, платформа может автоматически добавлять пустые строки, что исказит результат подсчёта.

⚠️ Внимание: В некоторых конфигурациях (например, 1С:ERP или 1С:УТ 11) табличные части могут иметь сложную структуру с вложенными таблицами. В этом случае для точного подсчёта используйте рекурсивный обход или специализированные функции модуля объекта.

6. Оптимизация производительности: что делать с большими таблицами

Если таблица содержит десятки или сотни тысяч строк, стандартные методы подсчёта могут работать медленно. В таких случаях требуются специальные подходы:

  • 🚀 Индексы: Для запросов к базам данных (SQL) убедитесь, что поля, используемые в условиях фильтрации, проиндексированы. В индексы настраиваются в конфигураторе для реквизитов справочников и документов.
  • 📊 Агрегация на стороне СУБД: Если вы работаете с внешней базой (например, PostgreSQL или MS SQL), перенесите подсчёт на сторону сервера с помощью конструкции ВЫБРАТЬ КОЛИЧЕСТВО(*) без выгрузки всех данных.
  • Асинхронные операции: Для фоновых задач используйте механизм ФоновыеЗадания, чтобы не блокировать интерфейс пользователя:
ФоновоеЗадание = ФоновыеЗадания.Создать("ПодсчётСтрокВФоне");

ФоновоеЗадание.Параметры.Таблица = МояТаблица;

ФоновоеЗадание.Выполнить();

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

ЭлементыФормы.Список.Колонки.Очистить(); // Оставляем только необходимые колонки

ЭлементыФормы.Список.Группировки.Очистить();

Данные = ЭлементыФормы.Список.ПолучитьДанные();

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

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

Можно ли посчитать строки в таблице 1С без программирования?

Да, в некоторых случаях. Например, в динамическом списке количество строк отображается в статусной строке формы (внизу окна). Для табличных частей документов можно использовать кнопку "Итоги" на панели инструментов, если она настроена в конфигураторе.

Однако для гибких условий (фильтры, группировки) без программирования не обойтись.

Почему метод Количество() возвращает неверное значение?

Частые причины:

  1. В таблице есть пустые строки (например, в табличной части документа с включённым автозаполнением).
  2. Строки помечены на удаление, но ещё не удалены физически.
  3. Вы работаете с динамическим списком, где метод возвращает только видимые строки (без учёта фильтров).

Решение: используйте программный обход строк с проверкой условий (см. раздел 4).

Как посчитать уникальные значения в колонке таблицы?

Используйте запрос с конструкцией ВЫБРАТЬ РАЗЛИЧНЫЕ:

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

"ВЫБРАТЬ

| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Номенклатура) КАК КоличествоУникальных

|ИЗ

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

Для таблицы значений подойдёт такой код:

УникальныеЗначения = Новый Массив;

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

Если НЕ УникальныеЗначения.Найти(Строка.Номенклатура) Тогда

УникальныеЗначения.Добавить(Строка.Номенклатура);

КонецЕсли;

КонецЦикла;

КоличествоУникальных = УникальныеЗначения.Количество();

Можно ли посчитать строки в таблице 1С через SQL-запрос напрямую?

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

  • Нарушить целостность данных при некорректных запросах.
  • Не учитывать бизнес-логику конфигурации (например, права доступа).
  • Сломаться при обновлении платформы (изменении структуры таблиц).

Исключение: если вы разрабатываете внешнюю обработку для администрирования базы и точно знаете структуру таблиц. Пример для MS SQL:

ВЫБРАТЬ COUNT(*) ИЗ _Document83 AS D

WHERE D._Reference83_ID = 'Документ.ЗаказПокупателя';

Для безопасного использования оберните SQL в транзакцию и проверьте права:

Если НЕ Метаданные.Документы.ЗаказыПокупателей.Права.Чтение Тогда

Возврат;

КонецЕсли;

Как посчитать строки в таблице на форме в 1С 8.2 и 8.3: есть ли различия?

Основные различия связаны с динамическими списками:

  • 1С 8.2: метод ПолучитьДанные() может работать медленнее из-за устаревшей архитектуры.
  • 1С 8.3: добавлена поддержка асинхронного получения данных (метод ПолучитьДанныеАсинх()), что ускоряет работу с большими объёмами.
  • 1С 8.3.20+: оптимизирована работа с группировками в динамических списках.

Для остальных методов (Количество(), запросы, программный обход) разницы нет.