Как программно установить курс валюты в строке табличной части при нажатии кнопки в 1С

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

При разработке интерфейсов в 1С:Предприятие 8 на управляемых формах начинающие программисты часто сталкиваются с трудностями при взаимодействии между элементами формы и данными объекта. Типичная ситуация: на форме есть табличная часть, в которой нужно заполнить реквизит (например, «Курс») по нажатию кнопки. Рассмотрим подробнее, как правильно реализовать этот механизм, избежав распространенных ошибок компиляции и выполнения.

Разбор типичных ошибок: «Переменная не определена» и «Поле объекта не обнаружено»

Проанализируем ситуацию, когда при написании кода возникают ошибки «Переменная не определена». Выясним причину: часто разработчик пытается обратиться к имени кнопки на форме так, будто это переменная, содержащая данные. В 1С ЭлементФормы (например, кнопка с именем Валюта2) и РеквизитОбъекта (поле, где хранится ссылка на валюту) — это разные сущности.

Если код выдает ошибку {...}: Переменная не определена (Валюта2), это означает, что в контексте процедуры система не понимает, что такое Валюта2. Если это имя кнопки, то через него нельзя получить курс. Нужно обращаться к данным, которые привязаны к текущей строке таблицы или к реквизиту самого объекта.

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

Шаг 1. Работа на клиенте: получение текущей строки

Для того чтобы изменить данные в конкретной строке, которую выбрал пользователь, нам нужно обратиться к свойству ТекущиеДанные элемента формы (таблицы). Проанализируем пример кода на клиенте:


&НаКлиенте
Процедура УстановитьКурс(Команда)

    // Получаем строку, на которой сейчас стоит курсор
    СтрокаТабличнойЧасти = Элементы.СписокНоменклатуры.ТекущиеДанные;

    // Обязательно проверяем, выбрана ли строка, чтобы не получить ошибку
    Если СтрокаТабличнойЧасти = Неопределено Тогда
        Сообщить("Пожалуйста, выберите строку в таблице!");
        Возврат;
    КонецЕсли;

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

КонецПроцедуры

В данном примере мы используем Элементы.СписокНоменклатуры.ТекущиеДанные. Это позволяет нам работать напрямую с полями текущей строки. Обратите внимание, что мы передаем в функцию не только валюту, но и Объект.Дата, так как курс валюты почти всегда зависит от даты документа.

Шаг 2. Работа на сервере: получение данных из базы

Поскольку данные о курсах валют обычно хранятся в Регистрах сведений, нам необходимо переключиться на серверный контекст. Использование директивы &НаСервереБезКонтекста является наиболее оптимальным с точки зрения производительности, так как на сервер не передаются лишние данные всей формы.

Разберем, как должна выглядеть функция получения курса. Посмотрим на правильную реализацию с использованием запроса к периодическому регистру сведений:


&НаСервереБезКонтекста
Функция ПолучитьКурсНаСервере(ВыбраннаяВалюта, ДатаДокумента)

    // В учебных конфигурациях курс иногда хранят прямо в справочнике (упрощенно)
    // Но правильно получать его из регистра сведений "КурсыВалют"
    
    Отбор = Новый Структура;
    Отбор.Вставить("Валюта", ВыбраннаяВалюта);
    
    // Получаем последние данные на дату документа
    ЗначенияРесурсов = РегистрыСведений.КурсыВалют.СрезПоследних(ДатаДокумента, Отбор);
    
    Если ЗначенияРесурсов.Количество() > 0 Тогда
        Возврат ЗначенияРесурсов[0].Курс;
    Иначе
        Возврат 0;
    КонецЕсли;

КонецФункции

Почему нельзя писать «Валюта.Курс»?

Проанализируем ситуацию, которая часто встречается в вопросах новичков. Если Валюта — это ссылка на справочник, то обращение Валюта.Курс сработает только в том случае, если в справочнике «Валюты» есть соответствующий реквизит. Однако в реальных задачах курс меняется каждый день, поэтому он хранится в периодическом регистре сведений.

Важные моменты:

  1. Различие имен: Всегда проверяйте, как называется реквизит в метаданных (в конфигураторе) и как называется элемент на форме. Кнопка — это Элемент, а Валюта в таблице — это Данные.
  2. Контекст: На клиенте (&НаКлиенте) мы не имеем доступа к регистрам сведений напрямую. Именно поэтому мы разделяем код на клиентскую процедуру обработки нажатия и серверную функцию получения курса.
  3. Типы данных: Если вы получаете ошибку «Поле объекта не обнаружено», убедитесь, что вы обращаетесь к Объект.ИмяТЧ или Элементы.ИмяТЧ.ТекущиеДанные, а не пытаетесь найти данные внутри самой кнопки.

Итоговый правильный алгоритм

Подведем итог и соберем воедино работающую схему для кнопки в табличной части:

1. В обработчике команды (кнопки) на клиенте получаем доступ к строке через ТекущиеДанные.

2. Проверяем заполнение ключевых полей (Валюта).

3. Передаем ссылку на валюту и дату в серверную функцию.

4. На сервере извлекаем актуальный курс из регистра сведений или реквизита справочника.

5. Возвращаем значение на клиент и присваиваем его полю Курс в строке таблицы.

Такой подход обеспечивает стабильную работу программы, отсутствие ошибок обращения к контексту и высокую скорость выполнения операций.

← На главную