Почему не обновляются изменения во внешней обработке 1С и как победить кэширование

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

Разработчики на платформе 1С:Предприятие 8.3 часто сталкиваются с крайне раздражающей ситуацией: во внешнюю обработку (файл .epf) вносятся изменения через Конфигуратор, файл сохраняется, но при повторном открытии в режиме «Предприятие» система упорно запускает старую версию кода. Создается впечатление, что платформа игнорирует новый файл. Рассмотрим подробнее, почему это происходит, как устроены механизмы кэширования в управляемом приложении и какими способами можно гарантированно заставить 1С увидеть ваши правки.

Природа проблемы: почему возникает «эффект памяти»

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

  1. Копирование во временные файлы: При запуске файл обработки копируется в локальный временный каталог пользователя (%TEMP%). Если платформа считает, что у нее уже есть актуальная копия этой обработки, она может не перезаписать ее.
  2. Идентификация по внутреннему имени: Платформа часто ориентируется не на имя файла на диске, а на внутреннее свойство Имя, заданное в метаданных обработки. Если в памяти сеанса уже зарегистрирован объект с таким именем, система может попытаться использовать его повторно.
  3. Кэш скомпилированных модулей: На стороне сервера (процесс rphost) скомпилированный «байт-код» модуля может сохраняться в рамках текущего сеанса пользователя.

Разберем по шагам все доступные методы решения этой проблемы — от простых к более сложным и глубоким.

Способ 1. Перезапуск сеанса и отладчика

Самый очевидный, но не всегда удобный метод — это полная остановка отладки и перезапуск приложения. Выясним, почему это помогает. При закрытии предприятия и прекращении отладки (Shift+F5) очищается оперативная память клиентского приложения и завершается сеанс на сервере. Это принудительно выгружает все кэшированные модули. Если вы работаете в режиме отладки, рекомендуется закрывать именно сеанс предприятия, а не просто форму обработки, так как отладчик может удерживать дескрипторы файлов, не давая системе обновить временные копии.

Способ 2. Очистка временных файлов (Temp)

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

C:\Users\ИмяПользователя\AppData\Local\Temp

Ищите там файлы с расширением .epf и папки, начинающиеся на v8_. Если файл «застрял» там, никакие сохранения в Конфигураторе не заставят 1С перечитать оригинал, пока временная копия не будет удалена или перезаписана.

Способ 3. Изменение внутренних метаданных

Если перезапуск не помогает, попробуем обмануть механизм идентификации объектов платформой. Для этого выполним следующие действия в Конфигураторе:

  1. Откроем дерево метаданных нашей внешней обработки.
  2. В поле Имя (не путать с именем файла!) добавим какой-нибудь префикс или цифру (например, было ЗагрузкаДанных, стало ЗагрузкаДанных1).
  3. Сохраним файл.
  4. В режиме «Предприятие» откроем файл заново.

Поскольку внутреннее имя изменилось, платформа воспримет обработку как абсолютно новый тип объекта и будет вынуждена полностью прочитать файл и скомпилировать его модули с нуля. Это один из самых надежных способов при разработке сложных алгоритмов в управляемых формах.

Способ 4. Управление глобальными переменными и торговым оборудованием

Иногда причина кроется не в самой платформе, а в коде конфигурации. В некоторых типовых решениях (например, УПП или старые версии БП) используются глобальные переменные или кэширующие модули для работы с торговым оборудованием. Рассмотрим пример, когда внешняя обработка «зависает» из-за регистрации в переменной глСерверТО.

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


Процедура ПриЗакрытии()
    // Если используется старая архитектура ТО
    Если ТипЗнч(глСерверТО) <> Тип("Неопределено") Тогда
        глСерверТО = Неопределено;
    КонецЕсли;
    
    // Или более современный вариант через отключение клиента
    Попытка
        ПолучитьСерверТО().ОтключитьКлиента(ЭтаФорма);
    Исключение
        // Обработка исключения, если сервер ТО недоступен
    КонецПопытки;
КонецПроцедуры

Этот прием принудительно разрывает связь формы с глобальными объектами системы, что позволяет платформе корректно уничтожить экземпляр объекта при закрытии окна.

Способ 5. Особенности работы с Дополнительными отчетами и обработками

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

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

Способ 6. Программный обход кэширования через уникальный ключ

Разберем продвинутый метод для тех, кто вызывает внешние обработки программно. При использовании метода ОткрытьФорму() можно передать параметр КлючУникальности. Если этот ключ всегда один и тот же, 1С будет пытаться найти уже открытую форму. Если же передавать туда уникальное значение (например, текущую дату в миллисекундах), система каждый раз будет создавать новый контекст.

Пример кода для вызова:


ПараметрыФормы = Новый Структура;
КлючУникальности = Строка(ТекущаяДатаСеанса()) + "_" + Строка(ТекущаяУниверсальнаяДатаВМиллисекундах());
ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма", ПараметрыФормы, , КлючУникальности);

Хотя этот метод больше относится к управлению окнами, он косвенно помогает избежать использования старого «состояния» объекта в памяти текущего сеанса.

Способ 7. Влияние версии платформы

Стоит отметить, что в версиях платформы 8.3.4 и 8.3.5 проблема кэширования стояла особенно остро и признавалась многими специалистами как программная ошибка (баг). В более поздних релизах (начиная с 8.3.12 и выше) механизмы обновления кэша стали работать стабильнее. Если вы столкнулись с тем, что ни один из вышеперечисленных методов не помогает на постоянной основе, стоит рассмотреть возможность обновления платформы до актуального релиза, где многие «фичи» кэширования были оптимизированы.

Подведем итог: для гарантированного обновления кода внешней обработки при разработке лучше всего использовать сочетание очистки папки %TEMP%, изменения внутреннего имени объекта в Конфигураторе и перезапуска сеанса под отладкой. Это сэкономит ваше время и убережет от поиска ошибок там, где их на самом деле уже нет.

← На главную