Почему не подставляется цена в документе: разбор примера из книги М.Г. Радченко

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

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

Анализ программных ошибок в коде

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


Функция РозничнаяЦена(АктуальнаяДата, ЭлементНомшенклатуры) Экспорт
    //Создать вспомогательный объект "Отбор".
    Отбор = Новый Структура("Номенклатура", "ЭлементНоменклатуры");
    
    //Получить актуальные значения ресурсов регистра.
    ЗначенияРесурсов = РегистрыСведений.Цены.ПолучитьПоследнее(АктуальнаяДата, Отбор);
    Возврат ЗначенияРесурсов.Цена;
КонецФункции

Выделим две критические ошибки, на которые указали участники форума:

  1. Передача строки вместо переменной: В строке создания структуры Отбор = Новый Структура("Номенклатура", "ЭлементНоменклатуры"); значение "ЭлементНоменклатуры" взято в кавычки. Это превращает переменную в обычный текст. Программа пытается найти в регистре сведений товар, название которого буквально совпадает с текстом "ЭлементНоменклатуры", а не тот товар, который мы выбрали в документе.
  2. Опечатка в имени аргумента: В заголовке функции написано ЭлементНомшенклатуры (лишняя буква "ш"), а внутри функции используется ЭлементНоменклатуры. Для платформы 1С это две абсолютно разные переменные.

Исправленный вариант функции в общем модуле должен выглядеть следующим образом:


Функция РозничнаяЦена(АктуальнаяДата, ЭлементНоменклатуры) Экспорт
    // Исправлено: убраны лишние буквы и кавычки у переменной
    Отбор = Новый Структура("Номенклатура", ЭлементНоменклатуры);
    
    ЗначенияРесурсов = РегистрыСведений.Цены.ПолучитьПоследнее(АктуальнаяДата, Отбор);
    Возврат ЗначенияРесурсов.Цена;
КонецФункции

Проверка настроек общего модуля

Даже если код написан идеально, он может не сработать из-за неверных свойств самого объекта ОбщийМодуль. Проанализируем, как должны быть настроены свойства модуля (например, РаботаСоСправочниками), чтобы клиентское приложение могло получить данные с сервера:

Поскольку функция РозничнаяЦена обращается к РегистрыСведений, она обязательно должна выполняться на стороне сервера. Однако вызываем мы её из модуля формы документа в процедуре с директивой &НаКлиенте. Чтобы этот "мост" между клиентом и сервером заработал, в свойствах общего модуля необходимо установить галочки:

Связь события формы с программным кодом

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

Проанализируем шаги для проверки этой связи:

  1. Откроем форму документа в конфигураторе.
  2. Выберем в табличной части ПереченьНоменклатуры поле Номенклатура.
  3. Перейдем в палитру свойств (обычно справа) на закладку События.
  4. Найдем событие ПриИзменении. В этом поле должно быть указано имя нашей процедуры: ПереченьНоменклатурыНоменклатураПриИзменении.

Если поле пустое, то 1С "не знает", что при выборе товара нужно запускать ваш код. Нужно нажать на лупу и выбрать процедуру из списка.

Безопасная работа с данными: обработка пустых значений

Рассмотрим еще один важный момент, который часто упускают при изучении основ. Метод ПолучитьПоследнее возвращает структуру. Если в регистре сведений "Цены" нет записи для выбранного товара, то обращение к ЗначенияРесурсов.Цена вызовет фатальную ошибку, так как поле Цена будет отсутствовать в результате.

Выясним, как сделать код более надежным. Рекомендуется добавить проверку на наличие данных:


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

Использование отладчика для поиска причины

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

  1. Поставим точку останова (клавиша F9) на строке СтрокаТабличнойЧасти.Цена = ... в модуле формы.
  2. Запустим 1С в режиме отладки и выберем товар в документе.
  3. Когда программа "замрет" на выбранной строке, нажмем F11, чтобы "войти" внутрь функции РозничнаяЦена.
  4. Посмотрим на значение переменной Отбор. Если там написано "ЭлементНоменклатуры" (в кавычках), значит, мы передаем текст вместо ссылки на товар.
  5. Проверим, что возвращает ЗначенияРесурсов. Если там пусто, значит, в регистре сведений на дату документа просто нет цен для этого товара.

Важный нюанс: Обратите внимание на дату документа. Если цены в регистр введены, например, 01.01.2024, а дата документа 31.12.2023, то метод ПолучитьПоследнее ничего не найдет, так как он ищет срез на указанный момент времени в прошлом.

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

← На главную