Разработка и Конфигурация · 11 мин
Как сделать счетчик в 1С: практическое руководство
Как сделать счетчик в 1С: нумераторы документов, счетчик в запросе и цикле, счетчик ссылок в форме. Примеры кода, типичные ошибки и проверка результата.
Задача «сделать счетчик» в 1С возникает в разных контекстах: пронумеровать документы уникальными номерами, посчитать итерации в цикле, вывести порядковый номер строки в отчете или подсчитать количество записей в табличной части. У каждого сценария свой правильный инструмент, и ошибка в выборе приводит либо к дублям номеров, либо к лишнему коду.
Платформа 1С:Предприятие уже содержит встроенные механизмы счетчиков — нумераторы, автонумерацию, функции языка запросов. В большинстве случаев писать собственный счетчик «с нуля» не требуется: достаточно правильно настроить штатный механизм. Собственные переменные-счетчики нужны только в алгоритмах, где штатные средства не покрывают логику.
Ниже разобраны все основные сценарии: от простейшего счетчика в цикле до настройки нумератора документов с префиксами и периодичностью. Для каждого варианта приведены примеры кода, условия применения и способы проверки результата.
Определяем, какой счетчик нужен под задачу
Прежде чем писать код, ответьте на вопрос: что именно должен считать счетчик? От этого зависит вся реализация. Если нужно присваивать уникальные номера объектам базы (документам, элементам справочников) — это задача нумератора. Если нужно посчитать что-то внутри алгоритма — достаточно переменной. Если требуется порядковый номер в выборке запроса — есть штатная функция языка запросов.
Как выбрать реализацию счетчика
Частая ошибка начинающих — реализовывать собственную нумерацию документов через запрос максимального номера и прибавление единицы. Такой подход опасен: при одновременной работе нескольких пользователей два сеанса могут получить одинаковый «максимальный номер», и возникнут дубли. Штатный нумератор решает эту проблему на уровне платформы.
Счетчик в цикле: базовый вариант на встроенном языке
Простейший счетчик — это числовая переменная, которая инициализируется перед циклом и увеличивается на каждой итерации. Такой подход подходит для подсчета обработанных записей, накопления итогов, ограничения количества повторений.
Счетчик = 0;
Для Каждого Строка Из ТаблицаДанных Цикл
Если Строка.Сумма > 0 Тогда
Счетчик = Счетчик + 1;
КонецЕсли;
КонецЦикла;
Сообщить("Обработано строк с суммой: " + Счетчик);
Обратите внимание на три обязательных элемента: инициализация переменной до цикла (иначе получите ошибку «Переменная не определена»), инкремент внутри тела цикла и использование результата после завершения. Если счетчик нужен внутри условия самого цикла — например, прервать обработку после 100 записей — проверяйте его значение в начале итерации и вызывайте Прервать.
Для нумерации строк при выводе в табличный документ удобно использовать счетчик, начинающийся с единицы, а не с нуля — так номера совпадут с привычной для пользователя нумерацией. Альтернатива — цикл Для Сч = 1 По КоличествоСтрок Цикл, где переменная цикла сама выполняет роль счетчика.
Счетчик = 0;
Для Каждого Строка Из ТабличнаяЧасть Цикл
Счетчик = Счетчик + 1;
Строка.НомерПозиции = Счетчик;
КонецЦикла;Нумератор документов: штатный счетчик номеров
Для автоматической нумерации документов в конфигураторе существует объект «Нумератор» (НумераторыДокументов). Он гарантирует уникальность номеров даже при конкурентной работе пользователей, поскольку выделение номера происходит при записи объекта с блокировкой на уровне СУБД.
Настройка выполняется в конфигураторе: откройте ветку «Документы», найдите нужный вид документа, на закладке «Нумерация» укажите длину номера, периодичность (в пределах года, месяца, дня или неограниченно) и включите автонумерацию. Если у нескольких видов документов должна быть сквозная нумерация — создайте общий нумератор в ветке «Нумераторы» и назначьте его обоим видам.
- 1Откройте конфигуратор и найдите нужный вид документа
- 2На закладке «Нумерация» включите автонумерацию и задайте длину номера
- 3Установите периодичность: обычно «В пределах года» для первичных документов
- 4При необходимости сквозной нумерации создайте общий объект «Нумератор» и свяжите с ним виды документов
- 5Обновите конфигурацию базы данных и проверьте создание двух документов подряд
Периодичность определяет, когда счетчик сбрасывается: при значении «Год» с первого января нумерация начнется заново. Учтите это при смене длины номера — если за период создается больше документов, чем позволяет длина (например, более 9999 при длине 4), платформа не сможет выдать следующий номер, и запись документа завершится ошибкой.
Префиксы и программная установка номера
Для разделения нумерации по организациям, подразделениям или узлам обмена используются префиксы. В типовых конфигурациях префикс формируется автоматически через подписку на событие «ПриУстановкеНовогоНомера» (или «ПриУстановкеНовогоКода» для справочников). В собственной конфигурации можно создать такую подписку вручную.
Процедура УстановкаПрефиксаПриУстановкеНовогоНомера(Источник, СтандартнаяОбработка, Префикс) Экспорт
Префикс = СокрЛП(Источник.Организация.Префикс);
КонецПроцедуры;
Если нужно установить номер полностью программно — например, при загрузке данных из внешней системы — присвойте свойство Номер до записи объекта. При этом платформа не будет контролировать уникальность в рамках нумератора, и ответственность за дубли ложится на ваш код. Для справочников аналогичная логика работает со свойством Код и событием «ПриУстановкеНовогоКода».
Счетчик в запросе: АВТОНОМЕРЗАПИСИ
Когда порядковый номер нужен прямо в результате запроса — например, для нумерации строк печатной формы или временной таблицы — используйте функцию языка запросов АВТОНОМЕРЗАПИСИ(). Она возвращает целочисленный номер записи в выборке, начиная с единицы.
ВЫБРАТЬ
АВТОНОМЕРЗАПИСИ() КАК НомерСтроки,
Товары.Номенклатура КАК Номенклатура,
Товары.Количество КАК Количество
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка = &Ссылка
Функция нумерует записи в том порядке, в котором их вернул запрос, поэтому для предсказуемой нумерации обязательно добавляйте предложение УПОРЯДОЧИТЬ ПО. Без сортировки порядок строк не гарантирован, и номера могут «прыгать» от выполнения к выполнению. Учтите также, что АВТОНОМЕРЗАПИСИ нельзя использовать в иерархических итогах и некоторых конструкциях с группировками — в таких случаях нумеруйте строки уже при обходе выборки в коде.
Счетчики строк в табличных частях и формах
Для подсчета строк табличной части отдельный счетчик обычно не нужен: у коллекции есть метод Количество(), а у каждой строки — свойство НомерСтроки, которое платформа поддерживает автоматически. Если вы удаляете строки программно и хотите сохранить непрерывную нумерацию, после удаления перенумеруйте строки в цикле, присваивая НомерСтроки последовательные значения.
В управляемых формах счетчик как реквизит формы создается через панель «Реквизиты формы»: добавьте реквизит с типом «Число» и обновляйте его в обработчиках, например при добавлении строки. Для отображения количества элементов динамического списка используйте обработку выборки данных или вычисление на клиенте, если объем невелик.
Проверка результата и типичные ошибки
После реализации счетчика проверьте его работу на граничных ситуациях: пустая выборка (счетчик должен остаться нулем, а не вызвать ошибку), первая запись периода (нумератор должен начать с единицы), параллельное создание объектов двумя пользователями (номера не должны совпасть). Для нумераторов полезно также проверить поведение при переполнении длины номера.
Как проверить результат
Номера отличаются на единицу, дубли отсутствуют
Одинаковые номера или пропуски без причины
Нумерация начинается с первого номера согласно периодичности
Нумерация продолжается или сбрасывается не вовремя
Возвращается 0, ошибок нет
Ошибка «Переменная не определена» или неверное значение
Идут подряд с 1 в порядке сортировки
Порядок номеров меняется между выполнениями запроса
Отдельного внимания заслуживает ситуация с обменом данными: если базы обмениваются документами, номера, присвоенные в разных узлах, могут пересекаться. Стандартное решение — уникальные префиксы узлов, которые настраиваются в плане обмена. Не отключайте префиксацию «для красоты номеров» в распределенных базах.
Частые вопросы о счетчиках в 1С
Как сбросить нумерацию документов, чтобы она началась заново?
Штатного способа сброса нет — нумератор хранит последний выданный номер в служебных данных. Практические варианты: дождаться смены периода (если задана периодичность), создать новый нумератор и назначить его виду документа, либо изменить префикс. Прямая правка служебных таблиц СУБД не поддерживается и может нарушить целостность базы.
Почему у документов пропуски в номерах?
Пропуски возникают, когда документ получил номер, но не был записан (пользователь закрыл форму без сохранения) или был удален. Номер выделяется при установке нового номера, а не при успешной записи, поэтому «дырки» в нумерации — нормальное поведение платформы, а не признак ошибки.
Можно ли сделать нумерацию справочника внутри групп?
Да, для этого в свойствах справочника установите признак «Серии кодов: В пределах подчинения». Тогда каждая группа будет иметь собственную последовательность кодов. Учтите, что при переносе элемента в другую группу его код может перестать быть уникальным в новой серии.
Как пронумеровать строки в печатной форме?
Если строки выводятся обходом выборки, заведите переменную-счетчик и увеличивайте её перед выводом каждой области. Если данные берутся запросом, проще добавить АВТОНОМЕРЗАПИСИ() с упорядочиванием — тогда номер придет уже готовым полем выборки.
Чем счетчик в запросе отличается от счетчика в коде?
АВТОНОМЕРЗАПИСИ нумерует записи одним проходом на стороне СУБД и не требует обхода выборки — это быстрее для больших выборок. Переменная в коде дает полный контроль: можно пропускать записи, нумеровать с произвольного значения, сбрасывать счетчик по условию. Выбор зависит от логики нумерации.
Что важно запомнить
Для нумерации объектов базы используйте штатные нумераторы и автонумерацию — они гарантируют уникальность при параллельной работе. Для подсчета в алгоритмах достаточно переменной в цикле, для номеров строк в запросе — функции АВТОНОМЕРЗАПИСИ() с обязательной сортировкой. Собственная нумерация через «максимум + 1» в многопользовательском режиме недопустима.