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