Как связать колонки двух разных таблиц на форме 1С и синхронизировать их данные

Программист 1С v8.3 (Обычные формы)
← На главную

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

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

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


Процедура НарушенияПриАктивизацииСтроки(Элемент)
    ЭлементыФормы.Аудируемые.Категория = ЭлементыФормы.КатегорияРеакцияРаботника.Категория; 
КонецПроцедуры

Проанализируем этот фрагмент. Проблема здесь в том, что ЭлементыФормы.Аудируемые — это сам элемент управления (табличное поле), а не конкретная строка данных. У элемента управления нет свойства Категория. Чтобы обратиться к данным, нужно использовать свойство ТекущиеДанные. Однако даже правильное обращение к ТекущиеДанные требует понимания того, в какой именно строке второй таблицы мы хотим изменить значение.

Решение 1: Использование технических колонок и ключей связи

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

Разберем по шагам, как это реализовать:

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

Теперь рассмотрим код, который будет синхронизировать данные при изменении категории в первой таблице:


Процедура КатегорияРеакцияРаботникаПриИзменении(Элемент)
    // 1. Получаем текущие данные первой таблицы (откуда берем данные)
    ТекущаяСтрока1 = ЭлементыФормы.КатегорияРеакцияРаботника.ТекущиеДанные;
    
    Если ТекущаяСтрока1 = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // 2. Ищем связанную строку во второй таблице по Ключу Связи
    // Предположим, вторая таблица называется "Аудируемые"
    ПараметрыОтбора = Новый Структура("КлючСвязи", ТекущаяСтрока1.КлючСвязи);
    НайденныеСтроки = Объект.Аудируемые.НайтиСтроки(ПараметрыОтбора);

    // 3. Обновляем данные во всех найденных строках
    Для Каждого СтрокаТЧ2 Из НайденныеСтроки Цикл
        СтрокаТЧ2.Категория = ТекущаяСтрока1.Категория;
    КонецЦикла;
КонецПроцедуры

Решение 2: Работа с Текущими Данными в Обычных формах

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

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


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

Важно помнить, что в Обычных формах (1С 8.2 и режим совместимости 8.3) после программного изменения данных в таблице может потребоваться визуальное обновление элемента формы. Для этого используйте метод ЭлементыФормы.ИмяТаблицы.Обновить().

Решение 3: Особенности работы в Управляемых формах (1С 8.3)

В современных Управляемых формах принцип работы меняется: мы работаем не с элементами формы, а непосредственно с данными объекта. Разберем ситуацию синхронизации данных через событие ПриИзменении на клиенте:


&НаКлиенте
Процедура СписокНарушенийКатегорияПриИзменении(Элемент)
    // Получаем текущую строку через идентификатор
    ИдентификаторСтроки = Элементы.СписокНарушений.ТекущаяСтрока;
    ДанныеСтроки = Объект.СписокНарушений.НайтиПоИдентификатору(ИдентификаторСтроки);
    
    Если ДанныеСтроки <> Неопределено Тогда
        // Вызываем серверную процедуру для поиска и обновления второй таблицы
        ОбновитьКатегорииВоВторойТаблице(ДанныеСтроки.КлючСвязи, ДанныеСтроки.Категория);
    КонецЕсли;
КонецПроцедуры

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

Типичные ошибки при синхронизации таблиц

Проанализируем основные причины, по которым механизм связи может не работать:

  1. Отсутствие проверки на Неопределено: Если пользователь не выбрал строку в таблице, обращение к ТекущиеДанные.Категория вызовет аварийное завершение программы.
  2. Присваивание переменной самой себе: Как было замечено в обсуждении на форуме, код ТД = ЭлементыФормы.Таблица1.ТекущиеДанные; ТД = ЭлементыФормы.Таблица2.ТекущиеДанные; ТД.Поле = ТД.Поле; абсолютно бесполезен, так как во второй строке переменная ТД перезаписывается и теряет связь с первой таблицей.
  3. Использование неправильных событий: Событие ПриАктивизацииСтроки происходит очень часто (при каждом клике или перемещении стрелками). Если в нем прописана тяжелая логика поиска по тысячам строк, интерфейс будет "тормозить". Для изменения данных лучше использовать ПриИзменении конкретной колонки.

Рекомендации по проектированию

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

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

← На главную