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

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

В процессе разработки прикладных решений на платформе «1С:Предприятие 8.3» (особенно в управляемом приложении) часто возникает задача автоматического расчета зависимых показателей в табличных частях. Типичный пример: расчет суммы строки на основе цены и количества или, как в нашем случае, расчет Значимости риска на основе его Вероятности и Последствий.

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

Анализ типичных ошибок: почему код не работал?

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

Ошибка №1: Ошибка преобразования значения к типу Число

В первой попытке код выглядел следующим образом:


&НаСервере
Процедура ПричиныПланиуремыеПоследствияРискаПриИзмененииНаСервере
    Элементы.ПричиныПланируемаяЗначимостьРиска = Элементы.ПричиныПланируемаяВероятностьРиска * Элементы.ПричиныПланиуремыеПоследствияРиска;
КонецПроцедуры

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

Ошибка №2: Текущие данные таблицы недоступны на сервере

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


// Ошибка: Попытка обратиться к ТекущиеДанные в серверном контексте
ТекДанные = Элементы.Причины.ТекущиеДанные;

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

Правильный интерактивный расчет на клиенте

Для выполнения простых арифметических расчетов нет необходимости отправлять запрос на сервер. Это лишняя нагрузка на каналы связи и сервер приложений. Расчет должен выполняться мгновенно прямо на компьютере пользователя — в контексте &НаКлиенте.

Рассмотрим правильный алгоритм реализации:

  1. Перехватываем событие изменения физических данных в ячейке табличной части.
  2. Получаем текущую строку таблицы через свойство ТекущиеДанные элемента управления таблицы.
  3. Выполняем математическую операцию напрямую с реквизитами строки данных.

Посмотрим на практическую реализацию обработчика события на клиенте:


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

Подводные камни: почему этого решения недостаточно?

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

Создаем профессиональное и отказоустойчивое решение (Best Practice)

Чтобы избежать дублирования кода на форме и гарантировать 100% корректность данных при любых сценариях работы системы, применим комплексный архитектурный подход.

Шаг 1. Оптимизация клиентской логики на форме

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


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

&НаКлиенте
Процедура ПричиныВероятностьРискаПриИзменении(Элемент)
    РассчитатьЗначимостьСтроки(Элементы.Причины.ТекущиеДанные);
КонецПроцедуры

&НаКлиенте
Процедура ПричиныПоследствияРискаПриИзменении(Элемент)
    РассчитатьЗначимостьСтроки(Элементы.Причины.ТекущиеДанные);
КонецПроцедуры

Шаг 2. Защита целостности данных на уровне Модуля Объекта

Для того чтобы колонка "Значимость" гарантированно рассчитывалась при программной записи объекта (без участия формы), продублируем логику расчета в модуле объекта бизнес-процесса в предопределенном обработчике ПередЗаписью:


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

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

← На главную