При разработке интерфейсов для сенсорных терминалов и планшетов на базе 1С 7.7 программисты часто сталкиваются с дилеммой: как обеспечить обновление данных в главном окне (десктопе) после закрытия формы документа, не прибегая к модальному режиму. Штатный модальный режим в 7.7 имеет неприятную особенность — он блокирует интерфейс и часто разворачивает дочерние окна во весь экран, что ломает эргономику тачскрин-приложения.
В данной статье мы разберем, почему метод ВыключитьМодальныйРежим() может не давать ожидаемого результата, как правильно организовать взаимодействие между формами через контекст и как реализовать удобную навигацию «вверх-вниз» в условиях ограниченности стандартных методов журналов.
Для начала проанализируем ситуацию с методом ВыключитьМодальныйРежим(). Важно понимать, что эта функция не является встроенной в платформу 1С 7.7. Это возможность, предоставляемая внешней компонентой FormEx. Многие ошибочно полагают, что вызов этого метода в процедуре ПриОткрытии() превратит модальное окно в обычное.
На самом деле, ВыключитьМодальныйРежим() предназначен для снятия блокировки системной очереди сообщений Windows. Это позволяет работать некоторым внешним обработчикам событий, которые обычно «замирают», когда 1С находится в состоянии DoModal. Однако этот метод не отменяет того факта, что выполнение кода в вызывающей форме будет остановлено до закрытия дочерней. Для полноценной работы тачскрин-интерфейса нам нужно полностью отказаться от ОткрытьФормуМодально() в пользу альтернативных механизмов.
Рассмотрим самый надежный и «чистый» способ обновления родительской формы. Вместо того чтобы ждать завершения модального окна, мы откроем форму обычным способом, но передадим ей ссылку на саму себя. Это позволит дочерней форме «знать» о родителе и вызывать его методы.
Разберем алгоритм по шагам:
ОткрытьФорму(), где вторым параметром передаем ключевое слово Контекст.ПриЗакрытии(), мы обращаемся к переданному параметру и вызываем обновление.Пример кода в форме «Десктопа»:
Процедура ПриНажатииКнопкиОткрыть()
// Открываем форму документа немодально, передавая свой контекст
ОткрытьФорму("Документ.Реализация", Контекст);
КонецПроцедуры
Пример кода в форме Документа:
Процедура ПриЗакрытии()
// Проверяем, был ли передан контекст родителя
Если ТипЗначенияСтр(Форма.Параметр) = "Контекст" Тогда
// Вызываем обновление родительской формы
Форма.Параметр.Обновить();
КонецЕсли;
КонецПроцедуры
Важный момент: Если в родительской форме (десктопе) используется не просто список, а сложная выборка или ТаблицаЗначений, метод Обновить() может не перечитать данные из базы. В этом случае в родительской форме стоит создать экспортную процедуру, например, ПеречитатьДанные(), и вызывать её через Форма.Параметр.ПеречитатьДанные().
Проанализируем еще одну интересную возможность платформы 7.7. Если форма уже открыта, повторный вызов ОткрытьФорму() для этого же объекта не создает новое окно, а активизирует существующее и вызывает в нем процедуру ПриПовторномОткрытии(). Это можно использовать для «пробуждения» десктопа.
В дочерней форме в процедуре ПриЗакрытии() можно прописать:
Процедура ПриЗакрытии()
// Попытка "открыть" уже открытый десктоп
ОткрытьФорму("Обработка.РабочийСтолТачскрин");
КонецПроцедуры
А в модуле формы рабочего стола:
Процедура ПриПовторномОткрытии()
// Здесь размещаем код перечитывания журналов или таблиц
ОбновитьФорму();
КонецПроцедуры
Выясним причину сложности работы с обычными журналами. В 1С 7.7 у объекта «Журнал» отсутствуют методы типа ТекущаяСтрока() (в контексте программной установки) или АктивизироватьСтроку(). Для сенсорного экрана, где пользователю неудобно попадать пальцем в мелкую полосу прокрутки, необходимы большие кнопки «Вверх» и «Вниз».
Для решения этой задачи воспользуемся эмуляцией нажатия клавиш клавиатуры через объект WScript.Shell. Это позволит нам имитировать нажатие стрелок на клавиатуре при нажатии на экранные кнопки.
Рассмотрим пример кода для кнопок управления:
Процедура КнопкаВниз()
Попытка
Сервис = СоздатьОбъект("WScript.Shell");
Сервис.SendKeys("{DOWN}");
Исключение
Предупреждение("Ошибка эмуляции клавиатуры: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура КнопкаВверх()
Попытка
Сервис = СоздатьОбъект("WScript.Shell");
Сервис.SendKeys("{UP}");
Исключение
Предупреждение("Ошибка эмуляции клавиатуры: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Этот метод универсален и работает с любыми списками, табличными частями и журналами, которые находятся в фокусе в данный момент.
Если штатные возможности журнала ограничивают дизайн (например, нужно сделать строки очень высокими), профессионалы рекомендуют использовать ТаблицуЗначений (ТЗ), размещенную на форме.
В отличие от журнала, ТЗ обладает следующими преимуществами для тачскрина:
ТекущаяСтрока(): Позволяет программно переходить на любую строку, просто меняя индекс.Пример программной прокрутки в ТаблицеЗначений:
Процедура ПрокрутитьТЗ_Вниз()
Если ТЗ.КоличествоСтрок() > ТЗ.ТекущаяСтрока() Тогда
ТЗ.ТекущаяСтрока(ТЗ.ТекущаяСтрока() + 1);
КонецЕсли;
КонецПроцедуры
Чтобы ваш интерфейс выглядел как законченное терминальное приложение, воспользуйтесь возможностями расширения форм. Если вы используете FormEx, в процедуре ПослеОткрытия() можно программно убрать заголовок окна и развернуть его, скрыв элементы управления Windows. Это предотвратит случайное закрытие программы пользователем и обеспечит визуальную чистоту интерфейса.
Используя комбинацию передачи контекста для обновления данных и эмуляции нажатий для навигации, вы сможете создать стабильное и удобное решение для работы на сенсорных устройствах в среде 1С:Предприятие 7.7.