Разработка в среде 1С:Предприятие 7.7 существенно отличается от современной платформы 1С 8.3. Одной из наиболее частых сложностей, с которой сталкиваются программисты, является отсутствие прямой коллекции открытых окон. Если в «восьмерке» мы привыкли использовать конструкцию ПолучитьОкна(), то в 7.7 механизмы взаимодействия между формами требуют иного подхода. В этой статье мы подробно разберем, как получить доступ к реквизитам открытого документа и передать измененные данные обратно, используя штатные средства и внешние инструменты.
Наиболее надежный и правильный способ взаимодействия между формой документа и внешней обработкой — это передача ключевого слова Контекст при открытии. Это позволяет «связать» две формы. Рассмотрим ситуацию: у нас есть открытый документ «Чек», и нам нужно вызвать обработку для расчета скидки, которая затем вернет результат в этот же чек.
Для начала проанализируем, как вызвать внешнюю обработку из формы документа. На форму документа необходимо добавить кнопку, в формуле которой прописать вызов:
// В модуле формы документа Чек
Процедура ВызватьРасчет()
// Передаем Контекст в качестве второго параметра функции ОткрытьФорму
ОткрытьФорму("Отчет", Контекст, КаталогИБ() + "ВнешниеФормы\РасчетСкидки.ert");
КонецПроцедуры
Теперь разберем, что происходит внутри внешней обработки РасчетСкидки.ert. Чтобы получить доступ к данным чека, мы должны считать переданный параметр при открытии. Разберем этот процесс по шагам:
ПриОткрытии получим ссылку на форму-владельца.Посмотрим на пример реализации кода в модуле внешней обработки:
Перем КонтекстДок; // Глобальная переменная модуля
Процедура ПриОткрытии()
// Получаем переданный контекст через Форма.Параметр
КонтекстДок = Форма.Параметр;
// Проверим, что контекст передан корректно
Если ТипЗначенияСтр(КонтекстДок) <> "ГрупповойКонтекст" Тогда
Предупреждение("Обработка должна запускаться только из формы документа!");
СтатусВозврата(0);
Возврат;
КонецЕсли;
// Теперь мы можем прочитать данные прямо из открытого чека
ТекущаяСумма = КонтекстДок.СуммаОплаты;
Сообщить("Сумма в открытом чеке: " + ТекущаяСумма);
КонецПроцедуры
Процедура ВыполнитьРасчет()
// Допустим, мы рассчитали новую сумму
НоваяСумма = КонтекстДок.СуммаОплаты * 0.9; // Скидка 10%
// Передаем значение обратно в открытую форму документа
КонтекстДок.СуммаОплаты = НоваяСумма;
// ВАЖНО: Чтобы пользователь увидел изменения на экране, нужно обновить форму
КонтекстДок.Форма.Обновить();
Сообщить("Скидка успешно применена!");
Форма.Закрыть(0);
КонецПроцедуры
Этот метод позволяет работать даже с незаписанными данными, которые пользователь только что ввел на экране. Обратите внимание, что изменения происходят в оперативной памяти (в контексте формы), и пользователю все равно нужно будет нажать «ОК» или «Записать» в самом документе, чтобы данные попали в базу.
Если перед нами стоит задача получить данные из открытого окна «без изменения конфигурации» (то есть мы не можем добавить кнопку в документ и передать Контекст), штатные средства 1С 7.7 бессильны. В этом случае на помощь приходит внешняя компонента FormEx.
Проанализируем возможности этой компоненты. Она позволяет получить коллекцию всех открытых окон приложения. С помощью объекта Сервис мы можем перебрать окна и найти нужное нам по заголовку или типу объекта.
Рассмотрим пример логики работы с FormEx:
// Пример использования FormEx (требуется загруженная компонента)
Сервис = СоздатьОбъект("Сервис");
ВсеОкна = Сервис.КоличествоОкон();
Для Номер = 1 По ВсеОкна Цикл
ТекОкно = Сервис.ПолучитьОкно(Номер);
Если ТекОкно.Заголовок = "Чек №..." Тогда
// Получаем контекст формы этого окна
Конт = ТекОкно.Контекст;
// Работаем с данными
Сумма = Конт.СуммаОплаты;
КонецЕсли;
КонецЦикла;
Этот способ является наиболее близким к поведению 1С 8.x. Однако он требует наличия сторонних библиотек (dll) в каталоге программы и их регистрации в системе или динамической загрузки через ЗагрузитьВнешнююКомпоненту().
Выясним еще одну хитрость, которую часто используют опытные разработчики. Если нужно обращаться к открытой форме из разных мест, можно создать в Глобальном модуле переменную глТекущийКонтекст.
В модуле формы документа (например, в процедуре ПриАктивизации или ПриОткрытии) мы пишем:
глТекущийКонтекст = Контекст;
Теперь любая внешняя обработка, запущенная через «Файл — Открыть», сможет прочитать данные из этой переменной. Но будьте осторожны: этот метод требует дисциплины в разработке, так как при переключении между разными окнами значение переменной должно корректно перезаписываться, иначе вы рискуете изменить данные не в том документе.
Проанализируем, какой метод выбрать в зависимости от условий задачи:
Контекст). Это самый стабильный, быстрый и «чистый» способ программирования в 7.7. Он гарантирует, что вы работаете именно с тем объектом, из которого вызвали обработку.СоздатьОбъект("Документ.Чек") и НайтиДокумент(). Но помните, что так вы не увидите изменений, которые пользователь внес, но еще не сохранил.В заключение отметим важный технический нюанс: при программном изменении реквизитов через контекст (КонтекстДок.Реквизит = Значение), 1С 7.7 не всегда автоматически пересчитывает связанные итоги или визуальные элементы. Всегда используйте КонтекстДок.Форма.Обновить() для синхронизации экранных данных.