Почему возникает ошибка «Доступ к файлу закрыт» при использовании Ctrl+P через FormEx в 1С 7.7?

Программист 1С v7.7
← На главную

Рассмотрим интересную и неочевидную ситуацию, с которой сталкиваются программисты при разработке на платформе 1С 7.7 с использованием популярной компоненты FormEx. Часто возникает задача повесить печать внешней печатной формы (ВПФ) на привычное пользователям сочетание клавиш Ctrl+P. Однако при реализации через событие FormEx мы можем столкнуться со странным «глюком»: на английской раскладке всё работает штатно, а при переключении на русскую периодически выскакивает сообщение «Доступ к файлу <имя_файла.ert> закрыт». Давайте проанализируем эту ситуацию и разберем по шагам, почему это происходит и как это правильно исправить.

Причина №1: Почему возникает ошибка доступа к файлу?

Выясним причину блокировки файла. В исходном варианте разработчики часто используют событие ПриНажатииКнопкиКлавиатуры. Это аналог стандартного системного события KeyDown. Однако у операционной системы Windows есть встроенный механизм автоповтора клавиатуры: если пользователь нажимает сочетание клавиш и удерживает его хотя бы на долю секунды дольше обычного, система начинает генерировать серию непрерывных событий нажатия.

Что происходит в 1С в этот момент?

  1. Первое мгновенное срабатывание события запускает обработчик, который открывает файл внешней обработки (ВПФ) .ert и накладывает на него системную блокировку для чтения/исполнения.
  2. Буквально через миллисекунды автоповтор генерирует второе событие нажатия.
  3. 1С пытается повторно обратиться к этому же файлу .ert для запуска процесса печати, но наталкивается на блокировку от первого процесса, который еще не успел завершиться. Отсюда и возникает предупреждение об ошибке доступа.

Причина №2: Влияние раскладки (ENG vs RU)

Посмотрим на пример исходного кода, вызывающего проблемы с раскладкой:


Если Найти(Симв(16), символ) > 0 Тогда 
    ФСО = 0; 
    ПоКнопкеПечать(); 
    Возврат; 
КонецЕсли;

Почему этот код работает только на английской раскладке? Использование функции Симв(16) обусловлено тем, что в английской раскладке комбинация Ctrl+P формирует системный управляющий ASCII-символ (Data Link Escape) с десятичным кодом 16. Компонента FormEx честно передает его в параметр Символ.

Однако при переключении на русскую клавиатуру пользователь физически нажимает ту же самую кнопку (на которой нарисованы «P» и «З»), но операционная система обрабатывает это как Ctrl+З. Генерируемый ASCII-код меняется, и условие в коде просто перестает находить совпадение. В результате скрипт отрабатывает нестабильно или игнорируется.

Решение 1: Правильный подход с использованием FormEx

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

  1. Используем событие отжатия клавиши. Событие ПриОтжатииКнопкиКлавиатуры (KeyUp) генерируется строго один раз при отпускании кнопок. Это полностью исключает эффект автоповтора и множественный вызов.
  2. Проверяем виртуальный код (Virtual-Key Code). Вместо текстового представления символа нужно опираться на параметр Код. Для физической клавиши «P/З» этот виртуальный код всегда равен 80, независимо от выбранного языка системы.

Перепишем процедуру правильно:


//******************************************************************************
// FORMEX 
Процедура ПриОтжатииКнопкиКлавиатуры(Код, Альт, Шифт, Контрол, Символ, ФСО)
    // Проверяем, что нажат Control (_к в оригинале, здесь Контрол = 1)
    Если Контрол = 1 Тогда
        // Виртуальный код 80 соответствует клавише P/З
        Если Код = 80 Тогда 
            ФСО = 0; // Отменяем стандартную обработку нажатия
            ПоКнопкеПечать(); // Вызываем нашу процедуру печати
            Возврат;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Решение 2: Штатный механизм 1С без использования FormEx

Рассмотрим альтернативный способ. Если в конфигурации нет жесткой необходимости использовать именно Ctrl+P, мы можем обойтись вообще без внешней компоненты FormEx, применив стандартные возможности платформы 1С 7.7.

Разберем по шагам, как это сделать:

  1. Добавляем на форму обычную кнопку, в свойствах которой указываем формулу: ПоКнопкеПечать().
  2. Переходим на вкладку «Дополнительно» в свойствах этой кнопки и назначаем ей горячую клавишу (акселератор).
    Важно: Штатно 1С 7.7 не поддерживает сочетания вида Ctrl + Буква. Мы можем использовать функциональные клавиши (например, F5) или комбинации с Alt (например, Alt + П).
  3. Делаем эту кнопку невидимой (убираем галочку «Видимый») или прячем её за пределы видимой области формы, если того требует дизайн интерфейса.

Этот метод будет работать абсолютно надежно и безотказно везде. Он не подвержен конфликтам с раскладками клавиатуры, не требует подгрузки внешних DLL-библиотек и на 100% защищен от блокировок файлов автоповтором.

← На главную