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

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

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

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

Разбор проблемы: Клиент против Сервера

Первое и самое важное правило управляемого приложения: на клиенте ссылка — это не объект. Когда вы находитесь в контексте &НаКлиенте, переменная, содержащая ссылку на справочник (например, СправочникСсылка.Счетчики), содержит только идентификатор (GUID) и представление (наименование). Вы не можете написать Ссылка.Код или Ссылка.ЗаводскойНомер на клиенте, так как этих данных просто нет в оперативной памяти клиентского приложения.

Для обращения к реквизитам объекта необходимо «сходить» на сервер. Рассмотрим, как это сделать правильно, избегая распространенных ошибок.

Анализ типичной ошибки: Передача элементов формы на сервер

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


&НаКлиенте
Процедура ТЧВводПоказанийСчетчиковСчетчикПриИзменении(Элемент)
    ЗаполнениеТЧНаОсновеВведенныхДанных(Элемент); // Ошибка здесь!
КонецПроцедуры

&НаСервере
Процедура ЗаполнениеТЧНаОсновеВведенныхДанных(Элемент)
    // Код...
КонецПроцедуры

При таком подходе система выдаст ошибку: «Ошибка преобразования данных XDTO: Отсутствует отображение для типа ПолеФормы». Это происходит потому, что объект Элемент (тип ПолеФормы) существует только в интерфейсе на стороне клиента. Сервер ничего не знает о кнопках, полях ввода и других визуальных компонентах. На сервер можно передавать только данные: числа, строки, даты, ссылки или структуры.

Правильная реализация получения данных

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

  1. В обработчике события ПриИзменении получаем данные текущей строки.
  2. Вызываем серверную функцию/процедуру, передавая ей ссылку.
  3. На сервере получаем нужные данные и возвращаем их на клиент (или заполняем реквизиты формы напрямую).

Рассмотрим пример кода, который решает поставленную задачу:


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

    // Проверяем, заполнено ли поле
    Если ЗначениеЗаполнено(ТекущиеДанные.Счетчик) Тогда
        // Передаем на сервер ТОЛЬКО ссылку
        ЗаполнитьДанныеСчетчикаНаСервере(ТекущиеДанные.Счетчик, ТекущиеДанные.НомерСтроки);
    Иначе
        // Если поле очистили, очищаем зависимые поля
        ТекущиеДанные.Коэффициент = 0;
        ТекущиеДанные.ЗаводскойНомер = "";
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДанныеСчетчикаНаСервере(СсылкаНаСчетчик, НомерСтроки)
    
    // На сервере нам доступна работа через "точку"
    // Находим строку в данных формы объекта по индексу
    // Индекс в коллекции начинается с 0, а НомерСтроки с 1
    СтрокаТЧ = Объект.ТЧВводПоказанийСчетчиков[НомерСтроки - 1];
    
    // Получаем данные из ссылки
    СтрокаТЧ.Коэффициент = СсылкаНаСчетчик.Коэффициент;
    СтрокаТЧ.ЗаводскойНомер = СсылкаНаСчетчик.ЗаводскойНомер;
    
КонецПроцедуры

Оптимизация: Работа со структурами

Проанализируем ситуацию: если в табличной части много колонок, обращение к каждой через Объект.ТЧ... может быть неудобным. Лучше использовать серверную функцию, которая возвращает Структуру с данными.

Рассмотрим этот профессиональный подход:


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

&НаСервереБезКонтекста
Функция ПолучитьДанныеСчетчика(Ссылка)
    
    Результат = Новый Структура;
    Результат.Вставить("Коэффициент", Ссылка.Коэффициент);
    Результат.Вставить("ЗаводскойНомер", Ссылка.ЗаводскойНомер);
    Результат.Вставить("МестоУстановки", Ссылка.МестоУстановки);
    
    Возврат Результат;
    
КонецФункции

Важный момент: использование директивы &НаСервереБезКонтекста ускоряет работу, так как на сервер не передается вся форма (весь Объект), а только один параметр — Ссылка. Это значительно экономит трафик и время отклика системы.

Полезные советы при работе с ТЧ

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

← На главную