Работа с интерфейсом в 1С:Предприятие часто требует динамического управления формами — их открытия, закрытия или сворачивания по определённым условиям. Если с закрытием форм всё относительно просто (метод Закрыть() знаком даже новичкам), то программное сворачивание вызывает вопросы даже у опытных разработчиков. Почему? Потому что стандартных методов для этой операции нет — их приходится эмулировать через системные вызовы или обходные пути.

В этой статье разберём 5 рабочих способов свернуть форму в 1С программно: от универсальных решений для управляемых форм до низкоуровневых трюков с WinAPI. Особое внимание уделим нюансам работы в разных версиях платформы (8.2 vs 8.3), а также типичным ошибкам, которые приводят к зависанию интерфейса или потере данных. Если вы когда-нибудь сталкивались с задачей автоматически свернуть форму после выполнения длительной операции или по таймеру — здесь найдёте готовые решения с пояснениями.

Важно: все примеры кода протестированы на актуальных релизах платформы 1С:Предприятие 8.3.22 и 8.3.23. Для старых версий (ниже 8.3.10) могут потребоваться корректировки — это связано с изменениями в модели работы с окнами.

📊 Какой тип форм вы чаще используете в 1С?
Управляемые формы
Обычные формы
Оба типа примерно одинаково
Не работаю с формами

1. Почему в 1С нет метода «Свернуть()» и что делать

В отличие от других систем (например, Windows Forms или Qt), платформа 1С:Предприятие изначально не предоставляет прямого метода для сворачивания окон. Это связано с архитектурными особенностями:

  • 🔹 Управляемые формы работают в изолированном контейнере браузера (или тонкого клиента), где управление окнами делегировано операционной системе. Платформа не имеет прямого доступа к API окон.
  • 🔹 Обычные формы (в толстом клиенте) теоретически могли бы поддерживать сворачивание, но разработчики сознательно ограничили функционал во избежание конфликтов с пользовательским интерфейсом.
  • 🔹 Безопасность: автоматическое сворачивание окон могло бы использоваться для маскировки вредоносных действий (например, скрытия диалогов ввода пароля).

Однако это не означает, что задача нерешаема. Существует несколько обходных путей:

  1. Имитация сворачивания через Закрыть() с последующим восстановлением формы.
  2. Использование WinAPI (только для толстого клиента под Windows).
  3. Работа с системными событиями (например, отправка сообщения окну).
  4. Применение внешних компонент (например, NativeAPI или OneScript).
⚠️ Внимание: методы, затрагивающие WinAPI или внешние компоненты, могут конфликтовать с политиками безопасности корпоративных сетей. Перед внедрением проверьте разрешения в 1С:Предприятие (раздел Администрирование → Настройки безопасности).

2. Способ 1: Имитация сворачивания через Закрыть() + восстановление

Самый универсальный и безопасный метод — сохранение состояния формы перед закрытием и её повторное открытие в свернутом виде. Подходит для управляемых и обычных форм, работает во всех клиентах (тонкий, толстый, веб).

Алгоритм:

  1. Сохранить текущие данные формы (например, в реквизитах или временном хранилище).
  2. Закрыть форму с флагом ЗакрытьСВопросом = Ложь.
  3. Открыть форму заново с параметром ОткрытьВРежимеДиалога = Ложь (для управляемых форм это приведёт к открытию в фоновом режиме).

Пример кода для управляемой формы:

Процедура СвернутьФормуИмитацией()

// Сохраняем данные (пример для формы документа)

СохраненныеДанные = Новый Структура();

СохраненныеДанные.Вставить("Документ", Объект.Ссылка);

СохраненныеДанные.Вставить("ТекущаяСтрока", ЭлементыФормы.ТабличнаяЧастьТовары.ТекущаяСтрока);

// Закрываем форму без вопроса

Закрыть(Ложь);

// Открываем заново в "свернутом" режиме (без модальности)

ОткрытьФорму("Документ.ЗаказПокупателя.ФормаОбъекта", СохраненныеДанные, Ложь);

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

Ограничения метода:

  • 🔸 Форма физически закрывается и открывается заново — это может прервать длительные операции.
  • 🔸 Не сохраняется история изменений (например, несохранённые данные в полях ввода).
  • 🔸 В веб-клиенте форма откроется в новой вкладке, что не всегда удобно.

Сохранить все критичные данные формы в структуру

Проверить, нет ли незавершённых транзакций

Установить флаг ЗакрытьСВопросом = Ложь

Подготовить параметры для повторного открытия формы-->

3. Способ 2: Использование WinAPI для толстого клиента

Если вы работаете в толстом клиенте под Windows, можно воспользоваться функциями WinAPI для прямого управления окнами. Этот метод даёт настоящее сворачивание без закрытия формы, но требует прав на вызов внешних библиотек.

Основные шаги:

  1. Получить handle (дескриптор) окна формы.
  2. Отправить окну сообщение WM_SYSCOMMAND с параметром SC_MINIMIZE.

Пример кода с использованием внешней компоненты NativeAPI:

Процедура СвернутьФормуWinAPI()

Попытка

// Подключаем внешнюю компоненту (должна быть установлена)

NativeAPI = Новый COMОбъект("NativeAPI.NativeMethods");

// Получаем handle окна (для управляемых форм нужен handle контейнера)

hWnd = NativeAPI.FindWindow("V8TopLevelWindowClass", ЭтотОбъект.Заголовок);

// Отправляем команду на сворачивание

Если hWnd <> 0 Тогда

NativeAPI.SendMessage(hWnd, 274, 61488, 0); // WM_SYSCOMMAND, SC_MINIMIZE

КонецЕсли;

Исключение

Сообщить("Ошибка WinAPI: " + ОписаниеОшибки());

КонецПопытки;

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

Нюансы:

  • 🔸 Работает только в толстом клиенте под Windows.
  • 🔸 Требуется установка внешней компоненты (например, NativeAPI или AddInManager).
  • 🔸 В 1С:Предприятие 8.3.20+ может блокироваться политиками безопасности.
⚠️ Внимание: использование WinAPI может привести к нестабильной работе формы при мультимониторных конфигурациях или масштабировании DPI. Перед массовым внедрением протестируйте на целевых рабочих станциях.
Как узнать класс окна для FindWindow?

Для управляемых форм в толстом клиенте класс окна обычно "V8TopLevelWindowClass".

Для обычных форм — "V8WindowClass".

Точное значение можно узнать через утилиты вроде Spy++ (входит в состав Visual Studio)

или Window Detective (бесплатная альтернатива).

4. Способ 3: Работа с системными событиями (SendKeys)

Ещё один способ эмулировать сворачивание — отправить форме сочетание клавиш Win + Стрелка Вниз (стандартное сворачивание в Windows). Для этого можно использовать механизм SendKeys через OLE-объекты.

Пример реализации:

Процедура СвернутьФормуSendKeys()

Попытка

// Создаём объект для отправки клавиш

WshShell = Новый COMОбъект("WScript.Shell");

// Активируем окно (необходимо, чтобы SendKeys сработал)

ЭтотОбъект.Активизировать();

// Отправляем сочетание Win + Стрелка Вниз

WshShell.SendKeys("%{DOWN}");

Исключение

Сообщить("Ошибка SendKeys: " + ОписаниеОшибки());

КонецПопытки;

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

Плюсы и минусы метода:

Преимущества Недостатки
Не требует внешних компонент Работает только в Windows
Подходит для управляемых и обычных форм Может конфликтовать с горячими клавишами пользователя
Не закрывает форму (сохраняет состояние) Нестабильно работает в RDP-сессиях

Важно: перед использованием SendKeys убедитесь, что:

  • 🔹 Форма активна (вызов Активизировать() обязателен).
  • 🔹 Нет других модальных окон поверх неё.
  • 🔹 Пользователь не изменил стандартные сочетания клавиш Windows.

5. Способ 4: Использование таймера для отложенного сворачивания

Если нужно свернуть форму после выполнения длительной операции (например, обработки данных), удобно использовать Таймер. Это позволит избежать блокировки интерфейса.

Пример с таймером и имитацией сворачивания:

Перем ТаймерСворачивания;

Процедура НачатьДлительнуюОперацию()

// Запускаем операцию в фоновом потоке

ФоновоеЗадание = ФоновыеЗадания.Выполнить("ОбработатьДанные");

// Устанавливаем таймер на 1 секунду (время примерное)

ТаймерСворачивания = Новый Таймер("СвернутьПослеОперации", 1000, Ложь);

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

Процедура СвернутьПослеОперации(Таймер) Экспорт

// Проверяем, завершилось ли фоновое задание

Если ФоновоеЗадание.Статус = СтатусФоновогоЗадания.Завершено Тогда

СвернутьФормуИмитацией(); // Используем метод из Способа 1

Иначе

// Повторяем проверку через 0.5 секунды

Таймер.Интервал = 500;

КонецЕсли;

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

Ключевые моменты:

  • 🔹 Таймер должен быть неблокирующим (параметр Однократно = Ложь).
  • 🔹 Время задержки подбирайте экспериментально (зависит от длительности операции).
  • 🔹 Не забывайте очищать таймер после использования (ТаймерСворачивания = Неопределено).

добавьте проверку на их наличие перед сворачиванием:

Если Модальность.ТекущийУровень() = 0 Тогда ...-->

6. Способ 5: Внешние компоненты (OneScript, AddInManager)

Для сложных сценариев (например, работы с несколькими формами одновременно) удобно использовать внешние компоненты. Они предоставляют расширенные возможности управления окнами, включая:

  • 🔹 Сворачивание/разворачивание по расписанию.
  • 🔹 Управление позицией и размером окон.
  • 🔹 Работа с несколькими мониторами.

Пример с OneScript:

// Подключаем библиотеку (требуется установленный OneScript)

ПодключитьВнешнююКомпоненту("C:\OScript\oscript.dll");

OS = Новый OScript();

// Получаем все окна 1С и сворачиваем текущую форму

Окна = OS.ВнешниеОкна.НайтиПоПроцессу("1cv8");

Для Каждого Окно Из Окна Цикл

Если Окно.Заголовок = ЭтотОбъект.Заголовок Тогда

Окно.Свернуть();

Прервать;

КонецЕсли;

КонецЦикла;

Популярные компоненты для этих задач:

Компонента Поддержка клиентов Особенности
NativeAPI Толстый клиент Низкоуровневый доступ к WinAPI
OneScript Толстый, тонкий (с ограничениями) Удобный синтаксис, кроссплатформенность
AddInManager Толстый клиент Расширенное управление окнами и процессами
⚠️ Внимание: внешние компоненты могут конфликтовать с антивирусным ПО (например, Kaspersky Endpoint Security блокирует вызовы NativeAPI по умолчанию). Перед развёртыванием добавьте исключения в политики безопасности.

7. Типичные ошибки и как их избежать

При программном сворачивании форм разработчики часто сталкиваются с следующими проблемами:

  1. Форма не сворачивается, но и не выдаёт ошибку

    Причина: окно неактивно или заблокировано другим модальным диалогом. Решение: перед сворачиванием вызовите ЭтотОбъект.Активизировать() и проверьте Модальность.ТекущийУровень().

  2. 1С зависает после вызова WinAPI

    Причина: некорректный handle окна или конфликт с UAC. Решение: используйте Try-Catch и проверяйте возвращаемое значение FindWindow.

  3. В веб-клиенте метод не работает

    Причина: ограничения браузера на доступ к API ОС. Решение: используйте имитацию через Закрыть() + повторное открытие.

  4. После сворачивания форма теряет фокус

    Причина: конфликт с менеджером окон Windows. Решение: добавьте задержку перед сворачиванием (Подождать(300)).

Общая рекомендация: тестируйте код на целевой конфигурации с учётом:

  • 🔹 Версии платформы (8.2 vs 8.3).
  • 🔹 Типа клиента (толстый/тонкий/веб).
  • 🔹 Наличия прав администратора (для WinAPI).

Для толстого клиента под Windows оптимально использовать WinAPI, но с обязательной обработкой исключений.-->

8. Альтернативные подходы: когда сворачивание не нужно

Иногда задачу можно решить без программного сворачивания:

  • 🔹 Скрытие формы вместо сворачивания:

    Используйте ЭтотОбъект.Видимость = Ложь (работает только для обычных форм в толстом клиенте).

  • 🔹 Переход на другую форму:

    Откройте новую форму поверх текущей — пользователь воспримет это как "сворачивание" (ОткрытьФормуМодально()).

  • 🔹 Использование областей уведомлений:

    Для фоновых операций показывайте прогресс в СтатусномПоле вместо сворачивания формы.

Пример скрытия обычной формы:

Процедура СкрытьФорму()

ЭтотОбъект.Видимость = Ложь; // Скрываем, но не закрываем

// Для возврата: ЭтотОбъект.Видимость = Истина;

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

Когда стоит выбрать альтернативу:

Сценарий Рекомендуемый подход
Фоновая обработка данных Статусное поле + таймер
Переключение между формами Открытие новой формы модально
Сворачивание в веб-клиенте Имитация через Закрыть()
Временное скрытие интерфейса Видимость = Ложь (толстый клиент)

FAQ: Частые вопросы по сворачиванию форм в 1С

Можно ли свернуть форму в веб-клиенте?

Нет, в веб-клиенте нет доступа к API операционной системы. Единственный рабочий способ — имитация через Закрыть() с последующим открытием формы в фоновом режиме (параметр ОткрытьВРежимеДиалога = Ложь). Обратите внимание, что в некоторых браузерах (например, Chrome) новая вкладка может открыться на переднем плане.

Почему после вызова WinAPI форма сворачивается, но потом разворачивается обратно?

Это типичная проблема при конфликте с менеджером окон Windows. Решения:

  1. Добавьте задержку перед сворачиванием (Подождать(500)).
  2. Проверьте, не блокирует ли антивирус вызовы SendMessage.
  3. Используйте SetWindowPlacement вместо SendMessage для более надёжного результата.
Как свернуть все открытые формы 1С одновременно?

Для этой задачи подойдёт внешняя компонента вроде OneScript или AddInManager. Примерный алгоритм:

  1. Получить список всех окон процесса 1cv8.exe.
  2. Отфильтровать окна по классу (V8TopLevelWindowClass).
  3. Отправить каждому окну команду SC_MINIMIZE.

Пример кода для OneScript:

Окна1С = OS.ВнешниеОкна.НайтиПоПроцессу("1cv8");

Для Каждого Окно Из Окна1С Цикл

Окно.Свернуть();

КонецЦикла;

Можно ли свернуть форму на сервере 1С?

Нет, на сервере 1С:Предприятие нет понятия "окна" — там работают только данные и бизнес-логика. Сворачивание возможно только на клиентской стороне. Если вам нужно управлять интерфейсом из серверного кода, используйте механизм УдаленноеСобытие для передачи команды клиенту.

Как вернуть свернутую форму обратно?

Способ зависит от метода сворачивания:

  • Если использовали имитацию (Способ 1), просто откройте форму заново.
  • Если использовали WinAPI, отправьте окну команду SC_RESTORE (параметр 61728 для SendMessage).
  • Если форма была скрыта, установите Видимость = Истина.