При разработке интерфейсов в платформе 1С:Предприятие 7.7 часто возникает задача размещения дополнительной таблицы значений (ТЗ) на форме списка справочника. Если справочник настроен для редактирования в отдельном диалоговом окне, стандартные события вроде ПриРедактированииСтроки не вызываются, из-за чего данные в ТЗ могут оставаться устаревшими после изменения или добавления элементов пользователем.
Разберем детально, как отловить создание и редактирование элемента, передать контекст родительской формы и вовремя обновить данные на форме списка.
Основной и самый надежный способ заключается в переопределении стандартного открытия формы элемента из формы списка. Для этого мы подавляем штатное поведение платформы с помощью команды СтатусВозврата(0) и вручную открываем форму нужного элемента или группы, передавая в качестве параметра контекст самой формы списка.
Рассмотрим реализацию в модуле формы списка справочника:
Процедура ПриВводеСтроки()
// Отменяем стандартное создание строки платформой
СтатусВозврата(0);
// Открываем форму нового элемента и передаем контекст текущей формы списка
ОткрытьФорму("Элемент." + Вид(), Контекст);
КонецПроцедуры
Процедура ПриВыбореСтроки()
// Проверяем, не открыта ли форма в режиме выбора значения (для подбора в документы)
Если Форма.РежимВыбора() = 1 Тогда
Возврат;
КонецЕсли;
// Подавляем штатное открытие формы
СтатусВозврата(0);
Если ТекущийЭлемент().Выбран() = 1 Тогда
// Открываем форму редактирования существующего элемента с передачей контекста
ОткрытьФорму(ТекущийЭлемент(), Контекст);
КонецЕсли;
КонецПроцедуры
// В теле модуля формы списка инициализируем нужный режим
РедактироватьВДиалоге(0, 0);
Форма.ОбработкаВыбораСтроки(1);
Теперь разберем, как принять переданный параметр и обновить форму списка из модуля формы элемента справочника. В платформе 1С 7.7 переданный контекст доступен через конструкцию Форма.Параметр. При закрытии или записи элемента мы проверяем тип параметра и обновляем список.
// В модуле формы элемента справочника
Процедура ПриОткрытии()
// Проверяем, передан ли контекст формы списка
// ТипЗначения 100 соответствует групповому контексту формы
Если ТипЗначения(Форма.Параметр) = 100 Тогда
КонтекстСписка = Форма.Параметр;
КонецЕсли;
КонецПроцедуры
Процедура ПриЗаписи()
// Инициируем обновление формы списка сразу при записи элемента
Если ТипЗначения(КонтекстСписка) = 100 Тогда
Если ПустоеЗначение(КонтекстСписка) = 0 Тогда
КонтекстСписка.Форма.Обновить(0);
// Либо вызываем процедуру пересчета ТЗ напрямую через контекст
// КонтекстСписка.ОбновитьТаблицуЗначений();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ПриЗакрытии()
// Дополнительная проверка на случай закрытия формы
Если ТипЗначения(КонтекстСписка) = 100 Тогда
Если ПустоеЗначение(КонтекстСписка) = 0 Тогда
КонтекстСписка.Форма.Обновить(0);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важные нюансы данного способа:
Форма.РежимВыбора() = 1 в процедуре ПриВыбореСтроки, иначе при выборе элемента в документ или отчет форма элемента будет принудительно открываться вместо выбора значения в поле ввода.ПриВводеСтроки срабатывает как на клавишу Insert (новый элемент), так и на Ctrl+F9 (новая группа). Если справочник многоуровневый, платформенный метод ЭтоГруппа() вернет признак текущей выделенной строки, а не того, что именно пытается создать пользователь. Если структура иерархии фиксированная или группы создаются редко, этот нюанс не вызовет проблем.ПриЗаписи(), так и в ПриЗакрытии(), чтобы список актуализировался даже в случае, если пользователь нажал «Записать», но оставил карточку элемента открытой.Если по каким-либо причинам стандартная передача через Форма.Параметр занята другими данными, можно использовать глобальную переменную, объявленную в глобальном модуле (ГлобальныйМодуль).
Разберем реализацию по шагам:
Перем глКонтекстФормыСписка Экспорт;.глКонтекстФормыСписка = Контекст;.
Процедура ПриЗакрытии()
Если ТипЗначения(глКонтекстФормыСписка) = 100 Тогда
Если ПустоеЗначение(глКонтекстФормыСписка) = 0 Тогда
глКонтекстФормыСписка.Форма.Обновить();
КонецЕсли;
глКонтекстФормыСписка = 0; // Очищаем переменную
КонецЕсли;
КонецПроцедуры
Существует альтернативный механизм пассивного обновления без ручного перехвата диалогов. На форму списка помещается элемент диалога типа «Текст», а в поле «Формула» указывается пользовательская функция (например, гфОбновитьТЗ()).
Проанализируем специфику данного подхода:
Если перехватить открытие формы не удается (например, элементы создаются вводом на основании из сторонних документов), можно использовать штатный механизм таймера формы.
// В модуле формы списка справочника
Процедура ПроверитьИОбновить()
// Проверяем флаг модификации или статус изменений
Если глДанныеСправочникаИзменены = 1 Тогда
ОбновитьТаблицуЗначений();
глДанныеСправочникаИзменены = 0;
КонецЕсли;
КонецПроцедуры
Процедура ПриОткрытии()
// Запускаем опрос каждые 2 секунды
ОбработкаОжидания("ПроверитьИОбновить", 2);
КонецПроцедуры
Процедура ПриЗакрытии()
// Обязательно останавливаем таймер при закрытии окна
ОбработкаОжидания("", 0);
КонецПроцедуры
Данный вариант обеспечивает автономность обновления формы списка вне зависимости от того, откуда именно была изменена запись справочника.