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