Почему не заполняется цена при выборе товара в документе 1С?

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

При разработке документов в 1С часто встречается задача: пользователь выбирает номенклатуру в табличной части, и программа должна автоматически подставить цену, хранящуюся в карточке товара или регистре. Нередко возникает ситуация, когда код написан, синтаксических ошибок нет, но при выборе товара в режиме предприятия ничего не происходит — цена остается пустой или равной нулю. Рассмотрим причины такого поведения и способы решения проблемы, от простых ошибок внимательности до архитектурных нюансов.

1. Проверка привязки события к элементу формы

Самая распространенная причина, по которой код «не работает», заключается в том, что платформа просто не знает, что этот код нужно выполнить. Написание процедуры в модуле формы с правильным названием (например, ТабличнаяЧасть1ТоварПриИзменении) недостаточно.

Разберем порядок действий для проверки:

  1. Откроем форму документа в Конфигураторе.
  2. Перейдем на вкладку «Элементы» и найдем колонку табличной части, отвечающую за товар (например, ТабличнаяЧасть1Товар).
  3. Откроем палитру свойств этого элемента (обычно справа или по нажатию Alt+Enter).
  4. Прокрутим список свойств вниз до раздела «События».
  5. Найдем событие ПриИзменении.

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

2. Оптимизация клиент-серверного вызова

В исходном коде используется директива &НаСервере. Для получения простых данных (таких как цена) это неэффективно, так как при вызове обычной серверной процедуры на сервер передается весь контекст формы (все данные документа), что создает лишний трафик.

Мы рекомендуем использовать директиву &НаСервереБезКонтекста. Она позволяет передать только необходимые параметры (ссылку на товар) и получить ответ, не нагружая систему передачей всей формы.

Перепишем код функции более правильно:


&НаСервереБезКонтекста
Функция ПолучитьЦенуТовараНаСервере(СсылкаНаТовар)
    
    // Проверка на пустую ссылку, чтобы не делать лишний запрос
    Если СсылкаНаТовар.Пустая() Тогда
        Возврат 0;
    КонецЕсли;

    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ЕСТЬNULL(Товары.Цена, 0) КАК Цена
        |ИЗ
        |   Справочник.Товары КАК Товары
        |ГДЕ
        |   Товары.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаНаТовар);
    
    Результат = Запрос.Выполнить();
    
    Если Не Результат.Пустой() Тогда
        Выборка = Результат.Выбрать();
        Выборка.Следующий();
        Возврат Выборка.Цена;
    Иначе
        Возврат 0;
    КонецЕсли;

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

Обратите внимание, мы добавили конструкцию ЕСТЬNULL в запросе. Это гарантирует, что если цена в карточке товара не задана (равна NULL), запрос вернет 0, и мы избежим ошибок при математических операциях в дальнейшем.

3. Корректный вызов с клиента

Теперь рассмотрим клиентскую часть кода. Здесь важно убедиться, что мы работаем с актуальными данными текущей строки. Используем свойство ТекущиеДанные.


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

    // Вызываем серверную функцию без контекста
    СтрокаТЧ.Цена = ПолучитьЦенуТовараНаСервере(СтрокаТЧ.Товар);
    
    // Если нужно пересчитать сумму строки:
    // СтрокаТЧ.Сумма = СтрокаТЧ.Цена * СтрокаТЧ.Количество;
    
КонецПроцедуры

4. Использование отладчика

Если после исправления привязки события и кода цена все равно не появляется, необходимо воспользоваться отладчиком. Это позволит понять, на каком этапе теряется значение.

  1. В конфигураторе поставьте точку останова (F9) на первой строке процедуры ТабличнаяЧасть1ТоварПриИзменении.
  2. Запустите режим «1С:Предприятие» в режиме отладки.
  3. Измените товар в документе.

Если программа остановилась на точке останова, значит, событие работает. Нажимая F10 (Шаг через), проследите выполнение кода. Проверьте значение переменной СтрокаТЧ.Товар (нажав Shift+F9). Если ссылка корректна, зайдите внутрь серверной функции (F11) и посмотрите, что возвращает запрос. Возможно, для выбранного товара цена в базе действительно равна 0.

5. Архитектурное примечание

Важно отметить, что хранение цены непосредственно в реквизитах справочника Товары характерно только для учебных задач или очень простых конфигураций. В реальных типовых решениях (УТ, ERP, Бухгалтерия) цены хранятся в Регистрах сведений (например, ЦеныНоменклатуры), так как они меняются во времени и зависят от вида цен.

Если вы работаете с типовой конфигурацией, ваш запрос к справочнику не вернет цену, так как реквизита Цена там просто нет. В таком случае запрос должен обращаться к виртуальной таблице среза последних регистра сведений:


// Пример текста запроса для реальных задач (упрощенно)
"ВЫБРАТЬ
|	ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена
|ИЗ
|	РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
|			&Период,
|			Номенклатура = &Номенклатура И ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних"
← На главную