Как реализовать автоматическое открытие окон предыдущей сессии после перезапуска 1С

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

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

Концепция решения задачи

Для того чтобы система «вспомнила», какие окна были открыты, нам необходимо решить три подзадачи: сбор данных об активных окнах перед выходом, хранение этих данных между сессиями и восстановление окон при следующем запуске. Проанализируем наиболее эффективные способы реализации каждого этапа.

В обычном приложении 1С нет штатной функции «запомнить всё», поэтому мы будем использовать программный подход. Основными точками входа для нашего кода станут обработчики событий в МодулеОбычногоПриложения.

Где хранить информацию об окнах

Разберем два основных варианта хранения данных о сессии:

  1. Регистр сведений: Создадим непериодический регистр (например, СохраненныеОкнаПользователей) с измерениями Пользователь и ИмяФормы, и ресурсом ПараметрыФормы (тип ХранилищеЗначения). Это надежный способ, данные в котором сохраняются даже при очистке кэша пользователя.
  2. Хранилище общих настроек: Использование системного объекта ХранилищеОбщихНастроек позволяет привязать настройки к конкретному пользователю без создания новых объектов метаданных в дереве конфигурации. Это более «чистый» с точки зрения архитектуры способ.

Алгоритм сохранения состояния окон

Проанализируем ситуацию: нам нужно перехватить момент закрытия программы. Для этого используем событие ПередЗавершениемРаботыСистемы. Поскольку в обычном приложении нет прямой коллекции всех открытых окон, доступной одной командой, мы можем пойти двумя путями:

Рассмотрим пример кода для сохранения данных в ХранилищеОбщихНастроек:


Процедура ПередЗавершениемРаботыСистемы(Отказ)
    
    СписокОкон = Новый СписокЗначений;
    
    // Предположим, у нас есть массив ОткрытыеФормы, 
    // который мы наполняли при открытии окон
    Для Каждого Форма Из ГлобальныйМассивОткрытыхФорм Цикл
        
        Если Форма.Открыта() Тогда
            ДанныеОкна = Новый Структура;
            ДанныеОкна.Вставить("ИмяМетаданных", Форма.Метаданные().ПолноеИмя());
            
            // Если это документ или элемент справочника, сохраняем ссылку
            Попытка
                ДанныеОкна.Вставить("Ссылка", Форма.ЭтотОбъект.Ссылка);
            Исключение
                ДанныеОкна.Вставить("Ссылка", Неопределено);
            КонецПопытки;
            
            СписокОкон.Добавить(ДанныеОкна);
        КонецЕсли;
        
    КонецЦикла;
    
    ХранилищеОбщихНастроек.Сохранить("СессияПользователя", "ОткрытыеОкна", СписокОкон);

КонецПроцедуры

Восстановление окон при запуске

Теперь выясним, как вернуть окна на место. В обработчике ПриНачалеРаботыСистемы нам нужно прочитать сохраненные данные и программно вызвать открытие форм. Важно учитывать, что простое открытие 50-ти окон одновременно может вызвать «зависание» интерфейса, поэтому рассмотрим поэтапное восстановление.


Процедура ПриНачалеРаботыСистемы()
    
    СохраненныеОкна = ХранилищеОбщихНастроек.Загрузить("СессияПользователя", "ОткрытыеОкна");
    
    Если СохраненныеОкна <> Неопределено Тогда
        Для Каждого ЭлементСписка Из СохраненныеОкна Цикл
            ДанныеОкна = ЭлементСписка.Значение;
            
            Попытка
                Если ЗначениеЗаполнено(ДанныеОкна.Ссылка) Тогда
                    // Открываем форму существующего объекта
                    ОткрытьФорму(ДанныеОкна.ИмяМетаданных + ".ФормаОбъекта", Новый Структура("Ключ", ДанныеОкна.Ссылка));
                Иначе
                    // Открываем форму списка или отчета
                    ОткрытьФорму(ДанныеОкна.ИмяМетаданных + ".ФормаСписка");
                КонецЕсли;
            Исключение
                ЗаписьЖурналаРегистрации("ВосстановлениеСессии", УровеньЖурналаРегистрации.Предупреждение, , , 
                    "Не удалось открыть окно: " + ДанныеОкна.ИмяМетаданных);
            КонецПопытки;
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Сложные случаи: Отчеты и новые объекты

Рассмотрим подробнее, с какими трудностями мы можем столкнуться:

Восстановление отчетов (СКД): Недостаточно просто открыть форму отчета. Пользователь ожидает, что сохранятся и его настройки (фильтры, группировки). Для этого необходимо использовать метод КомпоновщикНастроек.ПолучитьНастройки(), сериализовать их в XML-строку и сохранять в наш регистр или хранилище. При восстановлении нужно применить эти настройки обратно через ЗагрузитьНастройки().

Новые (незаписанные) объекты: Это самая сложная часть. Если пользователь создавал документ и не нажал «Записать», данных о нем в базе нет. Автоматическое восстановление таких окон «как в браузере» потребует реализации полноценного механизма черновиков (автосохранения данных объекта во временное хранилище каждые N минут). Без этого восстановить незаписанный объект невозможно.

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

Рекомендации по производительности

Чтобы процесс запуска системы не превратился в мучительное ожидание, проанализируем следующие советы:

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

← На главную