Как правильно реализовать отображение остатков товаров при активизации строки в управляемой форме 1С?

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

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

Разбор первой проблемы: Ошибка "Значение не является значением объектного типа (Номенклатура)"

Рассмотрим ситуацию: вы создали процедуру ТоварыПриАктивизацииСтроки, и программа выдает ошибку сразу при открытии документа. Проанализируем причину. Событие ПриАктивизацииСтроки срабатывает автоматически при инициализации формы. Если табличная часть документа пуста (например, при создании нового объекта), система все равно пытается "активизировать" строку, но фактически данных нет.

Посмотрим на ошибочный код:


&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
    Строка = Элементы.Товары.ТекущиеДанные.Номенклатура; // Ошибка здесь, если ТекущиеДанные = Неопределено
    // ... дальнейший код
КонецПроцедуры

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


&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
    ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
    
    // Обязательная проверка на Неопределено
    Если ТекущаяСтрока = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Теперь можно безопасно обращаться к реквизитам
    Остаток = ПолучитьОстатокНаСервере(ТекущаяСтрока.Номенклатура);
КонецПроцедуры

Выбор между &НаСервере и &НаСервереБезКонтекста

Важный момент, который часто обсуждается на форумах: можно ли вызывать серверные методы из события активизации строки? В справке 1С указано, что нельзя использовать методы с директивой &НаСервере. Однако, это ограничение касается только контекстных вызовов. Вызовы с директивой &НаСервереБезКонтекста разрешены и работают корректно.

Почему это важно? Контекстный вызов (&НаСервере) передает на сервер всю форму целиком (все данные объекта, реквизиты формы и т.д.), что создает огромную нагрузку на сеть. &НаСервереБезКонтекста передает только те параметры, которые вы явно указали, что делает работу интерфейса значительно быстрее.

Реализация функции получения остатков с учетом специфики запроса

Разберем, как эффективно написать запрос для получения остатков. Нам нужно получить данные из регистра накопления. Обратите внимание на использование параметров МоментВремени и фильтра по номенклатуре.


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

Проблема "запоздалого" обновления данных

Разработчики часто замечают, что при выборе товара в новой строке остаток не обновляется сразу. Это происходит потому, что при изменении значения в ячейке событие ПриАктивизацииСтроки повторно не вызывается (строка-то остается той же самой!).

Решение: необходимо дублировать логику обновления остатка в событии ПриИзменении поля Номенклатура. Рассмотрим комплексный подход:

  1. Создаем общую клиентскую процедуру для обновления информации на форме.
  2. Вызываем ее из ПриАктивизацииСтроки.
  3. Вызываем ее из НоменклатураПриИзменении.

&НаКлиенте
Процедура ОбновитьОтображениеОстатка()
    ТекДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекДанные <> Неопределено Тогда
        // Предположим, у нас есть реквизит формы "ТекущийОстатокНаСкладе"
        ТекущийОстатокНаСкладе = ПолучитьОстатокНаСервере(ТекДанные.Номенклатура, Объект.Склад);
    Иначе
        ТекущийОстатокНаСкладе = 0;
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
    ОбновитьОтображениеОстатка();
КонецПроцедуры

&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
    ОбновитьОтображениеОстатка();
КонецПроцедуры

Оптимизация производительности: Обработчик ожидания

Проанализируем ситуацию: пользователь быстро листает список товаров стрелками на клавиатуре. При каждом нажатии срабатывает ПриАктивизацииСтроки, и отправляется запрос на сервер. Это вызывает "фризы" (замирания) интерфейса. Профессиональным решением является использование обработчика ожидания.

Суть метода: мы не идем на сервер сразу, а ждем, например, 0.3 секунды. Если за это время пользователь переключился на другую строку, мы отменяем старый запрос и начинаем ждать заново. Вызов сервера произойдет только тогда, когда пользователь "задержится" на строке.


&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
    // Сбрасываем старый таймер и подключаем новый
    ОтключитьОбработчикОжидания("ВыполнитьОбновлениеОстатков");
    ПодключитьОбработчикОжидания("ВыполнитьОбновлениеОстатков", 0.3, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьОбновлениеОстатков()
    ОбновитьОтображениеОстатка();
КонецПроцедуры

Нюансы получения остатков для новых документов

При подготовке к экзамену "Специалист" важно помнить: если документ уже проведен, он сам делает движения по регистру. Если мы просто запросим остатки на дату документа, мы получим остаток вместе с товарами этого документа.

Рассмотрим рекомендации:

Заключение

Мы рассмотрели полный цикл реализации механизма отображения остатков в управляемых формах. Подведем итоги: во-первых, всегда делайте проверку на Неопределено для ТекущиеДанные; во-вторых, используйте &НаСервереБезКонтекста для минимизации трафика; в-третьих, комбинируйте обработчики активизации и изменения данных для актуальности информации; в-четвертых, применяйте обработчики ожидания для плавности работы интерфейса. Эти правила помогут вам не только успешно сдать экзамен, но и создавать качественные прикладные решения.

← На главную