К статье
Практический материал

Разработка и Конфигурация · 13 мин

Как связать две табличные части в 1С

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

В типовых и самописных конфигурациях 1С часто возникает задача: в документе есть две табличные части, и строки одной должны соответствовать строкам другой. Классический пример — «Товары» и «Серии»: для каждой номенклатуры из первой таблицы во второй хранятся строки с сериями и количеством именно по этой позиции. Без механизма связи пользователю пришлось бы вручную искать нужные строки, а разработчику — писать громоздкие проверки при проведении.

Платформа 1С:Предприятие 8.3 предлагает штатные средства для такой связи: свойство «СвязьПараметровВыбора», механизм ключевых строк через реквизит «КлючСвязи» и программную синхронизацию через события формы. Каждый способ решает свой круг задач: где-то достаточно отбора при выборе значения, где-то нужна жёсткая привязка строки к строке, а где-то — автоматическое заполнение одной таблицы по данным другой.

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

Какие задачи решает связь табличных частей

Прежде чем выбирать механизм, важно понять, какого рода связь требуется. На практике встречаются три сценария. Первый — строки второй табличной части «принадлежат» конкретным строкам первой: серии к товарам, этапы к работам, скидки к позициям. Второй — значения, выбираемые во второй таблице, должны зависеть от данных текущей строки первой: например, при выборе номенклатуры подтягиваются только её характеристики. Третий — данные второй таблицы целиком формируются по первой: автоматическое распределение суммы оплаты по строкам товаров.

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

Способ 1: связь через реквизит «КлючСвязи» и отбор строк

Это основной механизм для связи «строка к строкам». Добавьте в обе табличные части реквизит типа «Число» — например, «КлючСвязи». В первой табличной части при добавлении строки заполните его уникальным значением в рамках документа, во второй — копируйте значение из строки-владельца. Уникальность удобно обеспечить через реквизит формы или объекта с максимальным значением ключа.

Чтобы пользователь видел только связанные строки, настройте отбор второй таблицы по текущей строке первой. Для этого в обработчике «ПриАктивизацииСтроки» первой табличной части установите отбор в элементе формы второй таблицы, а при её отсутствии — сбросьте отбор или заблокируйте редактирование.

bsl
&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Элементы.Серии.ОтборСтрок = Неопределено;
        Возврат;
    КонецЕсли;
    Отбор = Новый ФиксированнаяСтруктура("КлючСвязи", ТекущиеДанные.КлючСвязи);
    Элементы.Серии.ОтборСтрок = Отбор;
КонецПроцедуры

&НаКлиенте
Процедура СерииПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Отказ = Истина;
        ПоказатьПредупреждение(, "Сначала выберите строку товаров.");
    КонецЕсли;
КонецПроцедуры

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

Порядок настройки связи по ключу
  1. 1
    Добавьте реквизит «КлючСвязи» (Число) в обе табличные части объекта.
  2. 2
    В событии «ПриНачалеРедактирования» первой таблицы присваивайте новый ключ новым строкам.
  3. 3
    В «ПриАктивизацииСтроки» первой таблицы устанавливайте ОтборСтрок второй таблицы по ключу.
  4. 4
    В «ПередНачаломДобавления» второй таблицы блокируйте добавление без выбранной строки первой и подставляйте ключ автоматически в «ПриНачалеРедактирования».
  5. 5
    В «ПередУдалением» первой таблицы удаляйте связанные строки второй.
  6. 6
    Проверьте поведение при копировании строк и отмене проведения.

Способ 2: связь параметров выбора между таблицами

Если задача — ограничить список выбираемых значений во второй табличной части данными текущей строки первой, используйте свойство поля ввода «СвязьПараметровВыбора». Оно работает декларативно, без кода: при открытии списка выбора платформа передаёт в него отбор по указанному реквизиту.

Типичный пример: во второй табличной части выбирается характеристика, и она должна принадлежать номенклатуре из текущей строки первой таблицы. В конфигураторе откройте палитру свойств поля «Характеристика», найдите «СвязьПараметровВыбора» и добавьте связь вида «Отбор.Владелец» ← «Элементы.Товары.ТекущиеДанные.Номенклатура». Путь к данным указывается от корня формы.

Ограничение способа: он влияет только на интерактивный выбор. Если строки второй таблицы заполняются программно или обработкой, связь параметров выбора ничего не проверит — корректность данных нужно контролировать отдельно, например в «ОбработкаПроверкиЗаполнения» объекта.

Способ 3: программная синхронизация данных

Когда вторая табличная часть целиком вычисляется из первой, связь строится кодом. Примеры: распределение оплаты по товарам пропорционально суммам, формирование строк «Серии» по количеству товаров, пересчёт итогов второй таблицы при изменении первой. Здесь нет постоянной связи — есть процедура, которая приводит таблицы в согласованное состояние.

Такую процедуру вызывайте из событий «ПриИзменении» ключевых полей первой таблицы, из команд формы («Заполнить серии») и из «ПередЗаписью» для финальной проверки. Если расчёт тяжёлый или требует запросов к базе, выносите его в серверную процедуру, чтобы не таскать данные между клиентом и сервером в цикле.

bsl
&НаСервере
Процедура ЗаполнитьСерииПоТоварам()
    Объект.Серии.Очистить();
    Для Каждого СтрокаТовара Из Объект.Товары Цикл
        НоваяСтрока = Объект.Серии.Добавить();
        НоваяСтрока.КлючСвязи = СтрокаТовара.КлючСвязи;
        НоваяСтрока.Номенклатура = СтрокаТовара.Номенклатура;
        НоваяСтрока.Количество = СтрокаТовара.Количество;
    КонецЦикла;
КонецПроцедуры

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

Сравнение способов и критерии выбора

Сравнение вариантов связи

Ключ связи + отбор строк

Жёсткая связь строка-к-строкам. Подходит для «Товары–Серии», «Работы–Этапы». Требует кода в 4–5 событиях формы и контроля при удалении/копировании.

Связь параметров выбора

Ограничение списка выбора без единой строки кода. Подходит, когда значение во второй таблице зависит от реквизита первой. Не защищает от программного заполнения.

Программная синхронизация

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

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

Маршрут решения

Как выбрать механизм

Строки второй таблицы принадлежат конкретным строкам первой и редактируются вручнуюИспользуйте реквизит «КлючСвязи» и отбор строк по активной строке.
Нужно только ограничить выбор значения в поле по данным другой таблицыНастройте «СвязьПараметровВыбора» в палитре свойств поля формы.
Вторая таблица должна автоматически формироваться по первойНапишите серверную процедуру заполнения и вызывайте её из событий изменения и команды формы.
Требуется гарантировать целостность при обмене и загрузкеДобавьте проверку соответствия таблиц в «ОбработкаПроверкиЗаполнения» модуля объекта.

Проверка результата и контроль целостности

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

Для защиты от рассинхронизации добавьте в модуль объекта проверку: для каждой строки второй табличной части должна существовать строка первой с тем же ключом, а суммарные количества по ключу должны совпадать. Такая проверка в «ОбработкаПроверкиЗаполнения» остановит проведение документа с битыми связями, даже если данные попали туда в обход формы.

Контрольные точки

Как проверить результат

Отбор второй таблицы
Норма

При переходе по строкам первой таблицы во второй видны только связанные строки

Тревожный признак

Отображаются все строки или список пуст при наличии данных

Копирование строки товара
Норма

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

Тревожный признак

Копия делит серии с исходной строкой — правка одной меняет другую

Удаление строки товара
Норма

Связанные строки второй таблицы удаляются вместе с ней

Тревожный признак

Во второй таблице остаются «осиротевшие» строки с несуществующим ключом

Проведение документа
Норма

Документ с нарушенной связью не проводится, выводится понятное сообщение

Тревожный признак

Проведение проходит при любых данных

Типичные ошибки и ограничения

Самая частая ошибка — использование номера строки как ключа связи. При удалении или перемещении строк номера пересчитываются, и связь разваливается. Ключ должен быть независимым счётчиком, который не меняется в течение жизни строки. Вторая распространённая проблема — установка отбора строк только в «ПриАктивизацииСтроки» без обработки случая пустой таблицы: когда строк нет, отбор остаётся от прежней строки, и пользователь видит чужие данные.

Третья группа ошибок — клиент-серверные: обращение к «Объект» в клиентских процедурах тонкого клиента недоступно, а передача всей таблицы на сервер в цикле по строкам убивает производительность. Собирайте данные в массив структур и передавайте на сервер одним вызовом. Наконец, не забывайте, что отбор строк — это только визуальный фильтр формы: в данных объекта строки хранятся все, и запросы в движениях должны учитывать связь по ключу явно.

Типичные ошибки
01
Использовать НомерСтроки как ключ — связь ломается при удалении или сортировке строк.
02
Не обрабатывать удаление строки первой таблицы — во второй копятся «осиротевшие» строки, которые попадают в движения.
03
Не сбрасывать ОтборСтрок при отсутствии текущей строки — пользователь видит данные чужой строки.
04
Полагаться только на СвязьПараметровВыбора — программное заполнение и обмен обходят её, в базу попадают некорректные значения.
05
Дёргать сервер в цикле по строкам — форма документа начинает заметно тормозить.

Часто задаваемые вопросы

Можно ли связать табличные части двух разных документов?

Напрямую штатных механизмов нет — ключ связи и отбор строк работают внутри одного объекта. Междокументную связь реализуют через реквизит-ссылку на документ-основание и программное заполнение по основанию: вторая таблица целевого документа формируется обработкой заполнения по данным источника.

Чем ключ связи отличается от использования номера строки?

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

Почему отбор строк не работает в динамическом списке или при программном обращении?

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

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

Для ограничения выбора используйте ту же «СвязьПараметровВыбора», указав путь к реквизиту шапки, например «Объект.Организация». Для автозаполнения — подставляйте значение шапки в событии «ПриНачалеРедактирования» табличной части при добавлении новой строки.

Нужно ли хранить связь в регистрах при проведении?

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

Работает ли этот подход в обычных формах?

Да, логика та же, но API отличается: вместо ОтборСтрок у табличного поля используется свойство «ОтборСтрок» данных табличной части на форме, а события называются «ПриАктивизацииСтроки» и «ПередНачаломДобавления» аналогично. Примеры кода потребуют адаптации синтаксиса.

Итог

Что важно запомнить

Для связи «строка к строкам» используйте числовой «КлючСвязи» в обеих табличных частях и отбор строк по активной строке; для ограничения выбора — «СвязьПараметровВыбора»; для производных данных — программное заполнение. Ключ не должен зависеть от номера строки, удаление и копирование строк требуют отдельной обработки, а итоговую целостность проверяйте в модуле объекта при проведении.