Как реализовать динамическое обновление контактной информации при выборе контрагента в списке 1С?

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

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

Разбор основной проблемы: почему данные не отображаются?

Рассмотрим ситуацию: программист пишет код, который при активации строки в списке находит нужные данные на сервере, но форма остается пустой. Проанализируем причину. Основная ошибка заключается в использовании локальных переменных внутри серверной процедуры. Когда мы пишем ЮрАдрес = "..." внутри процедуры на сервере, эта переменная живет только до тех пор, пока выполняется процедура. Чтобы данные появились на экране, они должны быть присвоены Реквизитам формы.

Для решения этой задачи нам необходимо выполнить следующие подготовительные действия:

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

Оптимизация события ПриАктивизацииСтроки

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

Во-первых, в текущих данных списка (Элемент.ТекущиеДанные) уже содержится ссылка на объект. Нам не нужно искать контрагента по коду — мы можем передать ссылку напрямую на сервер. Во-вторых, для улучшения отклика интерфейса рекомендуется использовать обработчик ожидания. Это позволит избежать лишних серверных вызовов при быстрой прокрутке списка пользователем.

Рассмотрим правильную структуру клиентского кода:


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    
    // Сбрасываем старый обработчик, если пользователь нажал кнопку "вниз" очень быстро
    ОтключитьОбработчикОжидания("ОбновитьИнформациюНаФорме");
    
    // Запускаем небольшую паузу перед походом на сервер (0.2 - 0.3 секунды)
    Если Элемент.ТекущиеДанные <> Неопределено Тогда
        ПодключитьОбработчикОжидания("ОбновитьИнформациюНаФорме", 0.3, Истина);
    КонецЕсли;
    
КонецПроцедуры

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

Методы получения контактной информации

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

Вариант 1: Использование запроса (универсальный способ)

Запрос — это наиболее быстрый способ извлечь данные из табличной части или регистра, не загружая объект целиком в память сервера. Мы выберем только нужные нам виды контактной информации одним пакетом.


&НаСервереБезКонтекста
Функция ПолучитьИнформациюКонтрагентаНаСервере(СсылкаКонтрагент)
    
    Результат = Новый Структура("ЮридическийАдрес, Телефон", "", "");
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	КонтрагентыКонтактнаяИнформация.Представление КАК Представление,
        |	КонтрагентыКонтактнаяИнформация.Вид КАК Вид
        |ИЗ
        |	Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКонтактнаяИнформация
        |ГДЕ
        |	КонтрагентыКонтактнаяИнформация.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаКонтрагент);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        // Здесь мы сравниваем виды КИ. В типовых решениях это предопределенные элементы
        Если Выборка.Вид = Справочники.ВидыКонтактнойИнформации.ЮридическийАдресКонтрагента Тогда
            Результат.ЮридическийАдрес = Выборка.Представление;
        ИначеЕсли Выборка.Вид = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента Тогда
            Результат.Телефон = Выборка.Представление;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

Вариант 2: Использование возможностей БСП (Библиотеки стандартных подсистем)

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

Пример получения представления адреса через типовую функцию:


// Получаем представление для одного вида КИ
Адрес = УправлениеКонтактнойИнформацией.ПредставлениеОбъекта(СсылкаКонтрагент, Справочники.ВидыКонтактнойИнформации.ЮридическийАдресКонтрагента);

Этот метод хорош тем, что система сама определит, где хранятся данные: в табличной части или в независимом регистре сведений, что часто встречается в последних версиях платформы.

Работа со строками: современный подход

Разберем ситуацию, когда у контрагента может быть несколько телефонов, и нам нужно вывести их через запятую. Вместо старого метода конкатенации в цикле (Результат = Результат + Тел + ", "), который создает много лишних объектов в памяти, воспользуемся функцией СтрСоединить.

Посмотрим на пример эффективного формирования строки:


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

Важные рекомендации по проектированию интерфейса

Проанализировав вышеописанные подходы, выделим несколько правил хорошего тона при динамическом обновлении данных:

Таким образом, мы рассмотрели комплексный подход к динамическому обновлению формы. Сочетание правильной работы с реквизитами формы, использование эффективных запросов и механизмов БСП позволит вам создавать отзывчивые и удобные интерфейсы для пользователей 1С.

← На главную