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