В процессе разработки отчетов на системе компоновки данных (СКД) часто возникает задача интерактивного взаимодействия с пользователем. Типичный сценарий: пользователь кликает по ячейке отчета, открывается форма записи регистра сведений для ввода комментария или статуса, и после сохранения данных внесенные изменения должны мгновенно отобразиться в отчете. При этом крайне важно избежать полного переформирования отчета, которое может занимать длительное время на больших объемах данных. Разберем детально, как реализовать этот механизм в управляемом приложении 1С.
Рассмотрим самый распространенный способ — использование метода Оповестить. Этот метод позволяет передать данные из одной формы во все другие открытые формы в рамках текущего сеанса. Это особенно удобно, когда форма записи регистра не знает напрямую о том, кто её вызвал, но нам нужно передать сигнал об обновлении.
Проанализируем шаги реализации:
ПослеЗаписи. Именно здесь мы будем отправлять сигнал.Оповестить, передавая имя события и структуру с данными записи.Пример кода в модуле формы записи регистра:
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("Комментарий", Объект.Комментарий);
СтруктураДанных.Вставить("ОбъектСвязки", Объект.ОбъектСвязки); // Ключевое поле для поиска строки в отчете
Оповестить("ОбновлениеКомментарияВОтчете", СтруктураДанных, ЭтаФорма);
КонецПроцедуры
Теперь перейдем к форме отчета. Чтобы «поймать» это сообщение, в модуле формы отчета должен быть определен обработчик события ОбработкаОповещения. Рассмотрим, как это выглядит:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ОбновлениеКомментарияВОтчете" Тогда
// Здесь мы вызываем процедуру обновления конкретной ячейки
ОбновитьТекстЯчейкиВТабличномДокументе(Параметр);
КонецЕсли;
КонецПроцедуры
Более современный и архитектурно «чистый» подход заключается в использовании объекта ОписаниеОповещения. Этот метод позволяет четко определить процедуру, которая должна выполниться именно после закрытия конкретной формы. Рассмотрим подробнее, как это реализовать при программном открытии формы записи.
Для начала, в форме отчета, когда мы инициируем открытие формы записи, мы создаем объект ОписаниеОповещения. Выясним, как правильно передать параметры:
&НаКлиенте
Процедура ОткрытьФормуЗаписи(ВыбраннаяОбласть)
// Сохраняем адрес текущей области, чтобы знать, куда вернуть значение
АдресЯчейки = ВыбраннаяОбласть.Имя;
ПараметрыОповещения = Новый ОписаниеОповещения("ЗавершитьРедактированиеКомментария", ЭтаФорма, АдресЯчейки);
ПараметрыФормы = Новый Структура;
// Настраиваем отбор, чтобы открылась существующая запись или заполнились поля новой
ПараметрыФормы.Вставить("Ключ", ПолучитьКлючЗаписи(ВыбраннаяОбласть));
ОткрытьФорму("РегистрСведений.Комментарии.Форма.ФормаЗаписи", ПараметрыФормы, ЭтаФорма, , , , ПараметрыОповещения);
КонецПроцедуры
Проанализируем ситуацию в процедуре завершения. Когда форма записи закроется, управление передастся в указанный нами метод ЗавершитьРедактированиеКомментария. Важно помнить: чтобы данные вернулись в этот обработчик, в форме записи при закрытии нужно вызвать Закрыть(Результат), где Результат — это наши данные.
Самый ответственный момент — визуальное обновление данных. Чтобы пользователь сразу увидел свой комментарий, мы должны программно изменить текст в ТабличныйДокумент (реквизит формы, где отображается результат СКД). Для этого нам нужно знать адрес ячейки или найти её по контексту.
Посмотрим на пример процедуры обновления, которая работает с объектом Результат (стандартное имя элемента формы для отчета):
&НаКлиенте
Процедура ОбновитьТекстЯчейкиВТабличномДокументе(Данные)
// Допустим, мы сохранили адрес в контексте или ищем по текущей области
ТекущаяОбласть = Элементы.Результат.ТекущаяОбласть;
Если ТекущаяОбласть <> Неопределено Тогда
// Устанавливаем текст напрямую в ячейку табличного документа
Элементы.Результат.Документ.Область(ТекущаяОбласть.Имя).Текст = Данные.Комментарий;
// Дополнительно можно изменить цвет фона ячейки, чтобы выделить изменения
Элементы.Результат.Документ.Область(ТекущаяОбласть.Имя).ЦветФона = ЦветаСтиля.ЦветФонаФайла;
КонецЕсли;
КонецПроцедуры
Важный нюанс: Такое обновление является чисто визуальным. Если пользователь нажмет кнопку «Сформировать», отчет будет перестроен заново из данных базы. Поэтому крайне важно, чтобы форма записи регистра действительно записывала данные в БД, а в схеме компоновки данных было предусмотрено ЛЕВОЕ СОЕДИНЕНИЕ с этим регистром сведений. Тогда при следующем формировании данные подтянутся автоматически.
Если форма отчета указана владельцем открываемой формы записи (третий параметр в ОткрытьФорму), можно использовать стандартный механизм ОбработкаВыбора. Рассмотрим по шагам:
Записать вызываем: ОповеститьОВыборе(Объект.Комментарий).ОбработкаВыбора у элемента формы Результат или у самой формы.Этот метод считается более простым в реализации, так как не требует явного описания оповещений, однако он менее гибкий, если из одной формы может производиться выбор разных типов данных.
Чтобы сделать интерфейс еще более дружелюбным, рекомендуем обратить внимание на следующие моменты:
ЗначениеЗаполнения, чтобы пользователю не приходилось заново выбирать аналитику (например, контрагента или номенклатуру), по которой он кликнул в отчете.Редактирование у табличного документа. Это позволит вводить данные прямо в ячейку, а событие ПриИзмененииСодержимогоОбласти использовать для фоновой записи в регистр через ВнешнееСоединение или фоновое задание.Выяснив все технические детали, мы видим, что наиболее надежным и современным способом является связка ОписаниеОповещения и прямого манипулирования областью ТабличногоДокумента. Это обеспечивает высокую скорость отклика интерфейса и корректную работу с данными в базе.