В разработке на платформе 1С:Предприятие часто возникает задача повышения удобства ввода данных. Один из самых распространенных сценариев — автоматическое заполнение связанных полей при выборе ключевого значения. Например, когда мы выбираем сотрудника в документе «Табель смены», система должна самостоятельно подтянуть его текущую должность и размер оклада. Рассмотрим подробно, как это реализовать, используя механизмы «Обычных форм».
Для реализации нашей задачи мы будем использовать обработчик события ПриИзменении. Это событие возникает в тот момент, когда пользователь выбрал значение в поле или ввел его вручную и нажал Enter (или переключил фокус). В контексте табличной части это событие должно быть привязано не к самой таблице, а к конкретной колонке — в нашем случае к колонке «Сотрудник».
Важно понимать разницу между управляемыми и обычными формами. В обычных формах работа с данными строки происходит через обращение к текущим данным элемента управления формы. Чтобы создать обработчик, нам нужно зайти в свойства колонки табличной части и нажать на лупу рядом с событием ПриИзменении. Платформа создаст процедуру в модуле формы, с которой мы и будем работать.
Первым делом проанализируем, как получить доступ к той строке, в которой пользователь только что изменил сотрудника. В обычных формах для этого используется свойство ТекущиеДанные табличного поля. Рассмотрим пример базовой структуры процедуры:
Процедура ИмяВашейТабличнойЧастиСотрудникПриИзменении(Элемент)
// Получаем текущую строку табличной части
СтрокаТЧ = ЭлементыФормы.ИмяВашейТабличнойЧасти.ТекущиеДанные;
// Проверим, не очистил ли пользователь поле Сотрудник
Если СтрокаТЧ.Сотрудник.Пустая() Тогда
СтрокаТЧ.Должность = "";
СтрокаТЧ.Оклад = 0;
Возврат;
КонецЕсли;
КонецПроцедуры
Здесь ЭлементыФормы.ИмяВашейТабличнойЧасти — это программное имя элемента управления на форме, а не имя самой таблицы в метаданных. Переменная СтрокаТЧ теперь содержит ссылку на текущую строку, и мы можем обращаться к её реквизитам напрямую.
Если в вашей конфигурации должность закреплена непосредственно в справочнике СотрудникиОрганизаций, то получить её значение проще всего простым обращением к реквизиту ссылки. Однако, как было отмечено в исходной задаче, реквизиты «Должность» и «Оклад» имеют тип Строка. Нам необходимо привести ссылку к строковому представлению.
Рассмотрим код для заполнения должности:
// Должность получаем напрямую из данных сотрудника
// Используем функцию Строка(), если реквизит в справочнике — ссылка,
// а в табличной части — текст.
СтрокаТЧ.Должность = Строка(СтрокаТЧ.Сотрудник.Должность);
Обратите внимание: если должность в справочнике сотрудника является периодическим значением (хранится в регистре сведений), такой способ не подойдет. В этом случае нам потребуется использовать метод СрезПоследних регистра сведений, чтобы получить актуальную должность на дату документа.
Ситуация с окладом сложнее. Как указано в описании, ОкладТариф связан с планом видов расчета. Обычно в 1С сами планы видов расчета (ПВР) хранят только виды начислений, а конкретные суммы (размеры окладов) фиксируются в регистрах сведений (например, «Плановые начисления» или аналогичные).
Чтобы вытащить сумму оклада, нам нужно обратиться к регистру, сделав отбор по сотруднику и конкретному виду расчета. Проанализируем пример кода с использованием регистра сведений:
// Подготовим структуру отбора для получения данных из регистра
Отбор = Новый Структура;
Отбор.Вставить("Сотрудник", СтрокаТЧ.Сотрудник);
// Получаем актуальную запись из регистра на дату документа
// Предположим, регистр называется "ПлановыеНачисления"
ЗаписиОклада = РегистрыСведений.ПлановыеНачисления.СрезПоследних(Дата, Отбор);
Если ЗаписиОклада.Количество() > 0 Тогда
// Если запись найдена, записываем значение ресурса "Размер" в нашу строку
// Приводим к строке, если в ТЧ реквизит строковый (хотя лучше использовать Число)
СтрокаТЧ.Оклад = Строка(ЗаписиОклада[0].Размер);
Иначе
СтрокаТЧ.Оклад = "0"; // Если данных нет
КонецЕсли;
Выясним одну важную деталь, упомянутую в обсуждении: использование типа Строка для оклада и должности. В профессиональной разработке это считается плохой практикой по нескольким причинам:
Число().Рекомендуем изменить тип реквизита Оклад на Число (15, 2), а реквизита Должность — на СправочникСсылка.Должности. Это существенно упростит написание кода и дальнейшую эксплуатацию системы.
Сведем все вышеперечисленное в единый алгоритм, который можно вставить в модуль обычной формы документа:
Процедура ТабельнаяЧастьСотрудникПриИзменении(Элемент)
// 1. Получаем доступ к строке
СтрокаТЧ = ЭлементыФормы.ТабельнаяЧасть.ТекущиеДанные;
// 2. Проверка на заполнение
Если СтрокаТЧ = Неопределено Или СтрокаТЧ.Сотрудник.Пустая() Тогда
Возврат;
КонецЕсли;
// 3. Заполняем должность (из реквизита справочника)
СтрокаТЧ.Должность = Строка(СтрокаТЧ.Сотрудник.Должность);
// 4. Поиск оклада в регистре сведений
// Используем дату документа для получения актуального значения
Отбор = Новый Структура("Сотрудник", СтрокаТЧ.Сотрудник);
// Здесь указываем имя вашего регистра, где хранятся суммы начислений
ДанныеОкладов = РегистрыСведений.НачисленияСотрудников.СрезПоследних(Дата, Отбор);
Если ДанныеОкладов.Количество() > 0 Тогда
// Заполняем реквизит из регистра
СтрокаТЧ.Оклад = Строка(ДанныеОкладов[0].Размер);
Иначе
СтрокаТЧ.Оклад = "0";
КонецЕсли;
КонецПроцедуры
Посмотрим на ситуацию шире: что если пользователь изменит дату документа уже после заполнения таблицы? В этом случае «Срез последних» для оклада может стать неактуальным. Для решения этой проблемы опытные разработчики часто добавляют вопрос пользователю: «Дата документа изменилась, пересчитать оклады в табличной части?». При положительном ответе запускается цикл по всем строкам таблицы с вызовом логики пересчета.
Также стоит помнить, что в обычных формах при заполнении реквизитов через программный код визуальное обновление ячеек происходит автоматически, в отличие от некоторых сценариев управляемых форм. Однако, если вы хотите гарантировать перерисовку, можно использовать метод ЭлементыФормы.ИмяВашейТабличнойЧасти.ОбновитьСтроки().
Таким образом, мы проанализировали основные этапы решения задачи: от перехвата события изменения до получения данных из регистров. Использование этих методов позволит сделать ваш документ «Табель смены» удобным и защищенным от ошибок ручного ввода.