Как открыть вторую форму в 1С, рассчитать данные и вернуть результат в исходную форму?

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

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

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

Выясним причины ошибок при расчете данных во второй форме

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

  1. Сравнение ссылки со строкой. Если реквизит Профиль передается как ссылка на справочник или значение перечисления, сравнение вида Если Профиль = "Квадрат" Тогда всегда вернет Ложь. Ссылочные типы нельзя напрямую сравнивать со строковыми литералами. Для исправления следует использовать получение представления через Строка(Профиль) или сравнивать реквизит с конкретной ссылкой (например, Справочники.Профили.Квадрат).
  2. Использование нулей в формулах перемножения. Числовые реквизиты формы по умолчанию инициализируются нулем. Если при изменении хотя бы одного поля вызывается пересчет формулы (например, Длина * Ширина * Высота * Плотность), а одно из полей еще не заполнено пользователем, результат вычисления будет равен 0.
  3. Путаница в параметрах функций. При передаче значения материала в серверную функцию для получения плотности важно следить за типами и именами параметров. Передача ссылочного объекта вместо конкретной характеристики приводит к ошибке обращения к свойствам.

Передача параметров и вызов формы расчета

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

В первой форме создаем процедуру-обработчик команды, подготавливаем структуру параметров и вызываем метод ОткрытьФорму. Чтобы получить результат расчета обратно, формируем объект ОписаниеОповещения, указывающий на клиентскую процедуру обработки завершения.

Рассмотрим пример кода первой формы:


&НаКлиенте
Процедура РассчитатьВес(Команда)
    
    // Формируем структуру параметров для передачи во вторую форму
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Профиль", Объект.Профиль);
    ПараметрыФормы.Вставить("Материал", Объект.Материал);
    
    // Создаем описание оповещения о закрытии подчиненной формы
    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗакрытияФормыРасчета", ЭтотОбъект);
    
    // Открываем форму калькулятора асинхронно
    ОткрытьФорму("ОбщаяФорма.ФормаРасчета", ПараметрыФормы, ЭтотОбъект, , , , ОписаниеОповещения);
    
КонецПроцедуры

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

Прием параметров и расчет во второй форме

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

Посмотрим на пример обработки параметров в событии ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Параметры.Свойство("Профиль") Тогда
        Объект.Профиль = Параметры.Профиль;
    КонецЕсли;
    
    Если Параметры.Свойство("Материал") Тогда
        Объект.Материал = Параметры.Материал;
    КонецЕсли;
    
КонецПроцедуры

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


&НаКлиенте
Процедура РасчетВеса()
    
    Плотность = ПолучитьПлотностьМатериала(Объект.Материал);
    ИмяПрофиля = Строка(Объект.Профиль);
    
    Если ИмяПрофиля = "Квадрат" Тогда
        Вес = Объект.Длина * Объект.Ширина * Плотность;
    ИначеЕсли ИмяПрофиля = "Круг" Тогда
        Вес = 3.14 / 4 * Объект.Диаметр * Объект.Диаметр * Объект.Длина * Плотность;
    ИначеЕсли ИмяПрофиля = "Полоса, лист" Тогда
        Вес = Объект.Длина * Объект.Ширина * Объект.Высота * Плотность;
    Иначе
        Вес = 0;
    КонецЕсли;
    
    Объект.Вес = Вес;
    
КонецПроцедуры

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

Возврат рассчитанного значения в первую форму

Чтобы перенести полученный результат обратно в вызвавшую форму, используем штатную процедуру закрытия формы с передачей параметра. На управляемую форму добавляем кнопку «Перенести» или «ОК», в обработчике которой вызывается метод Закрыть().

Разберем код закрытия формы с возвратом результата:


&НаКлиенте
Процедура ПеренестиЗначение(Команда)
    
    // Закрываем форму и передаем рассчитанное значение в РезультатЗакрытия
    Закрыть(Объект.Вес);
    
КонецПроцедуры

При вызове метода Закрыть(Объект.Вес) платформа автоматически закрывает текущую форму калькулятора и передает значение реквизита Объект.Вес в параметр РезультатЗакрытия процедуры ПослеЗакрытияФормыРасчета исходной формы.

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

← На главную