Как использовать функцию АВТОНОМЕРЗАПИСИ() в запросах 1С?

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

С выходом платформы версии 8.3.13 разработчики 1С получили долгожданный инструмент — функцию АВТОНОМЕРЗАПИСИ(). До этого момента для получения порядкового номера строки в запросе приходилось использовать громоздкие и ресурсоемкие конструкции, такие как соединение таблицы самой с собой по условию "меньше" или использование итогов. В этой статье мы подробно разберем, как работает этот механизм, какие ограничения он накладывает и как с его помощью оптимизировать ваш код.

Суть и назначение функции АВТОНОМЕРЗАПИСИ()

Рассмотрим основной смысл данной функции. АВТОНОМЕРЗАПИСИ() — это специальная функция языка запросов, которая генерирует последовательные целые числа для каждой строки результирующего набора данных. Важно понимать, что это не просто случайный уникальный идентификатор, а инструмент, позволяющий зафиксировать порядок строк. Проанализируем ключевой аспект: результат функции всегда имеет тип Число с точностью 10 и без дробной части. Это делает его идеальным кандидатом для создания первичного ключа во временной таблице.

Ранее программистам приходилось писать "говнокод" (как метко выразились участники обсуждения), чтобы пронумеровать строки. Теперь же процесс автоматизирован на уровне СУБД, что значительно повышает производительность, особенно на больших объемах данных.

Обязательные условия использования

Выясним основные технические ограничения, без соблюдения которых запрос просто не скомпилируется. Разберем их по пунктам:

  1. Только во временных таблицах. Функцию АВТОНОМЕРЗАПИСИ() можно использовать исключительно в запросах, результат которых помещается во временную таблицу. Использование в обычном конечном наборе данных или во вложенном запросе (без конструкции ПОМЕСТИТЬ) приведет к ошибке.
  2. Запрет на выражения. Посмотрим на важный нюанс: вы не можете написать АВТОНОМЕРЗАПИСИ() + 1 или использовать функцию внутри ВЫБОР КОГДА.... Платформа требует, чтобы функция вызывалась как самостоятельное поле. Однако, если вам нужно изменить это значение, вы можете сделать это в следующем запросе пакета, обратившись к созданному полю временной таблицы.
  3. Зависимость от сортировки. Порядок, в котором будут присвоены номера, жестко привязан к разделу УПОРЯДОЧИТЬ ПО. Если вы не укажете сортировку, номера будут присвоены в произвольном порядке, который определит оптимизатор СУБД.

Пример базового использования

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


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Товар,
    АВТОНОМЕРЗАПИСИ() КАК ПорядковыйНомер
ПОМЕСТИТЬ ВТ_ТоварыСНомерами
ИЗ
    Справочник.Номенклатура КАК Номенклатура
УПОРЯДОЧИТЬ ПО
    Номенклатура.Наименование
;

В данном примере мы создаем временную таблицу ВТ_ТоварыСНомерами, где поле ПорядковыйНомер будет содержать значения 1, 2, 3 и так далее, в соответствии с алфавитным порядком наименований. Это позволяет нам в дальнейшем обращаться к строкам по их индексу.

Оптимизация соединений и индексация

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

Решение: мы можем сначала поместить данные во временную таблицу, добавив АВТОНОМЕРЗАПИСИ(), и создать индекс по этому полю. Дальнейшие соединения в пакете запросов будут выполняться по одному целочисленному полю, что для СУБД является максимально легкой операцией. Это значительно ускоряет выполнение сложных отчетов.

Реализация накопительных итогов и скользящих средних

Разберем, как с помощью АВТОНОМЕРЗАПИСИ() решить классическую задачу вычисления суммы с накоплением. Рассмотрим следующий алгоритм:

  1. Помещаем исходные данные (например, продажи по дням) во временную таблицу с автономером, отсортировав их по дате.
  2. Соединяем эту таблицу саму с собой по условию Т1.ПорядковыйНомер >= Т2.ПорядковыйНомер.
  3. Группируем по Т1.ПорядковыйНомер и суммируем продажи из Т2.

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

Работа с группировками

Важно понимать порядок вычислений внутри запроса. Если в вашем запросе присутствует СГРУППИРОВАТЬ ПО, то функция АВТОНОМЕРЗАПИСИ() будет вычислена после того, как строки будут свернуты. Проанализируем пример:


ВЫБРАТЬ
    Продажи.Контрагент КАК Контрагент,
    СУММА(Продажи.Сумма) КАК ОбщаяСумма,
    АВТОНОМЕРЗАПИСИ() КАК НомерГруппы
ПОМЕСТИТЬ ВТ_ИтогиПоКонтрагентам
ИЗ
    РегистрНакопления.Продажи КАК Продажи
СГРУППИРОВАТЬ ПО
    Продажи.Контрагент
УПОРЯДОЧИТЬ ПО
    ОбщаяСумма УБЫВ

В этом случае номера будут присвоены уже уникальным контрагентам, отсортированным по объему продаж. Это идеальный способ для реализации различных рейтингов (ТОП-10 клиентов и т.д.).

Пагинация и выборка порциями

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

1. Создаем временную таблицу со всеми данными и полем НомерСтроки.

2. В основном запросе выбираем данные с фильтром:


ГДЕ
    НомерСтроки МЕЖДУ &НачалоСтраницы И &КонецСтраницы

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

Сравнение с SQL-аналогами

Для тех, кто знаком с языком SQL, функция АВТОНОМЕРЗАПИСИ() является аналогом ROW_NUMBER() OVER(ORDER BY ...) в MS SQL Server или PostgreSQL. Однако 1С накладывает свои ограничения (использование только в ПОМЕСТИТЬ), чтобы гарантировать стабильность работы на разных СУБД. Платформа самостоятельно транслирует этот вызов в соответствующие инструкции IDENTITY или оконные функции в зависимости от типа используемой базы данных.

Заключение

Функция АВТОНОМЕРЗАПИСИ() — это мощный инструмент оптимизации. Она позволяет уйти от сложных связей по многим полям, легко реализовывать математические алгоритмы (накопление, скользящее среднее) и эффективно управлять порядком записей. Помните о главных правилах: обязательное использование ПОМЕСТИТЬ и явное указание УПОРЯДОЧИТЬ ПО для предсказуемого результата.

← На главную