Как сопоставить номер строки документа с номером строки регистра накопления в 1С

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

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

Особенности системного поля НомерСтроки в регистрах

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

Кроме того, в типовых алгоритмах проведения строки табличной части редко переносятся в регистр «один в один». Выделим основные причины расхождения номеров:

  1. Группировка данных: запросы проведения часто сворачивают одинаковые позиции номенклатуры с помощью конструкции СГРУППИРОВАТЬ ПО, чтобы уменьшить объем движений.
  2. Партионный учет и списание: при распределении партий (FIFO/LIFO) или подборе серийных номеров одна строка документа может порождать несколько записей в регистре.
  3. Условия проведения: строки с нулевым количеством или позициями, не подлежащими учету в данном регистре, отсекаются условиями запроса.

Способ 1. Добавление реквизита КлючСтроки или НомерСтрокиДокумента

Если для решения прикладной задачи требуется строгая связь с исходной строкой документа, наиболее простым и надежным подходом является добавление в состав реквизитов регистра накопления дополнительного поля — например, НомерСтрокиДокумента или КлючСтроки с типом Число.

Разберем по шагам, как передать номер строки документа в движение с помощью запроса:


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

Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    Движение = Движения.ОстаткиМатериалов.Добавить();
    Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
    Движение.Период = Дата;
    Движение.Номенклатура = Выборка.Номенклатура;
    Движение.Количество = Выборка.Количество;
    // Явно сохраняем номер строки документа в реквизит регистра:
    Движение.КлючСтроки = Выборка.НомерСтрокиДокумента;
КонецЦикла;

Способ 2. Использование типового механизма КлючСвязи

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

Для решения этой проблемы в табличную часть документа и в движения регистров добавляется специальный реквизит КлючСвязи (тип Число):

  1. При создании новой строки в табличной части ей генерируется уникальный числовой идентификатор (например, максимальный существующий ключ + 1).
  2. При проведении документа этот идентификатор переносится во все движения, порожденные данной строкой, без изменения даже при разбиении строки на партии.
  3. При чтении данных сопоставление выполняется не по номеру строки, а по равенству реквизита КлючСвязи.

Способ 3. Прямой перенос строк без группировки

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

Посмотрим на пример обхода строк табличной части:


Для Каждого СтрТЧ Из ТабличнаяЧастьМаршрута Цикл
    Движение = Движения.ВыполнениеМаршрутныхКарт.Добавить();
    Движение.Период = Дата;
    Движение.ТехнологическаяОперация = СтрТЧ.ТехнологическаяОперация;
    Движение.Количество = СтрТЧ.Количество;
    // Системный НомерСтроки сформируется платформой автоматически (1, 2, 3...)
КонецЦикла;

Архитектурные рекомендации

Проанализируем последствия связывания записей регистра с каждой строкой документа:

  1. Производительность: отказ от агрегации строк увеличивает размер физических таблиц движений и индексов СУБД, что может замедлить проведение документов и расчет итогов.
  2. Выбор объекта метаданных: если регистр используется исключительно для детального аудита операций построчно и по нему не требуется получать остатки или обороты, более целесообразно использовать регистр сведений с подчинением регистратору вместо регистра накопления.
← На главную