Как автоматически заполнить поле Телефон при выборе клиента в 1С:Предприятие 8.3

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

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

Способ 1: Использование программного кода в модуле формы

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

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

  1. Откроем форму документа в конфигураторе.
  2. Найдем элемент формы Клиент, нажмем на него правой кнопкой мыши и выберем События — ПриИзменении.
  3. Система предложит создать процедуру. Выберем вариант создания на клиенте и процедуру на сервере.

Рассмотрим пример кода, который должен получиться в модуле формы:


&НаКлиенте
Процедура КлиентПриИзменении(Элемент)
    // Вызываем серверную процедуру, так как обратиться к данным справочника напрямую с клиента нельзя
    КлиентПриИзмененииНаСервере();
КонецПроцедуры

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

Проанализируем ситуацию: почему мы пишем Объект.Телефон? В контексте модуля формы Объект — это специальная переменная, которая предоставляет доступ к данным текущего документа, открытого на экране. Обращаясь к Объект.Клиент.Телефон, мы используем механизм "через точку". 1С автоматически выполняет запрос к базе данных, находит справочник Клиенты, открывает нужную карточку и достает оттуда значение поля Телефон.

Способ 2: Вывод данных через Путь к данным (без программирования)

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

Выясним, как это сделать:

  1. В окне редактора формы перейдем на закладку Реквизиты (правая колонка).
  2. Раскроем дерево реквизита Объект.
  3. Найдем в списке наш реквизит Клиент и раскроем его (нажмем на плюс слева).
  4. Внутри раскроется список всех полей справочника Клиенты. Найдем там Телефон.
  5. Просто перетащим мышкой поле Телефон (которое находится внутри клиента) на левую часть окна — туда, где расположены элементы формы.

Теперь 1С сама создаст поле, в котором будет отображаться номер телефона. Оно будет обновляться автоматически при каждой смене клиента. Однако помните: в этом случае телефон будет только "светиться" на экране, но не запишется в таблицу базы данных для этого конкретного документа.

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

Рассмотрим важный архитектурный вопрос: зачем нам реквизит Телефон в документе, если он уже есть в справочнике? В профессиональной разработке это называется денормализацией. Представим ситуацию: вы оформили заказ клиенту сегодня. Через месяц клиент сменил номер телефона, и вы обновили его в справочнике. Если в документе телефон не сохраняется (а только отображается из справочника), то открыв старый заказ, вы увидите новый телефон. Это может быть критично для истории взаимодействий. Поэтому копирование данных через Объект.Телефон = Объект.Клиент.Телефон; — это правильный подход для документов продажи или оказания услуг.

Разбор типичных ошибок начинающих разработчиков

Часто новички пытаются использовать конструкции вида Документы.ИнформацияОТоварах.Телефон. Это грубая ошибка. Выясним причину: Документы.ИнформацияОТоварах — это менеджер объекта, то есть "инструкция" ко всем документам этого типа. У менеджера нет поля "Телефон", оно есть только у конкретной записи (экземпляра) документа.

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

  1. Процедура не привязана к событию. Мало просто написать текст в модуле. Нужно зайти в свойства поля ввода на форме и в строке ПриИзменении нажать на лупу, чтобы система "увидела" вашу процедуру.
  2. Разные типы данных. Проверьте, что в справочнике Телефон — это Строка, и в документе это тоже Строка. Если типы не совпадают, присваивание не сработает.
  3. Отсутствие вызова сервера. Если вы пытаетесь написать Объект.Клиент.Телефон внутри процедуры с директивой &НаКлиенте, система выдаст ошибку, так как клиентское приложение не имеет прямого доступа к базе данных.

Оптимизация для продвинутых задач

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

Посмотрим на пример более профессионального подхода:


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

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

← На главную