Как программно обновить внешнюю обработку в справочнике Дополнительные отчеты и обработки при открытии

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

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

Разбор основной задачи

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

Типичная ошибка при получении объекта

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


Обработка = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Загрузка");
Обработка.ПолучитьОбъект(); // Ошибка! Объект не присвоен переменной
Обработка.Наименование = "Загрузка V2";

Важно помнить: метод ПолучитьОбъект() возвращает новый объект типа СправочникОбъект, но не преобразует саму ссылку в объект. Чтобы иметь возможность изменять реквизиты и записывать данные, необходимо обязательно присвоить результат выполнения метода переменной.

Правильный вариант кода выглядит так:


СсылкаНаОбработку = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Загрузка");
ОбъектОбработки = СсылкаНаОбработку.ПолучитьОбъект();
// Теперь мы можем менять реквизиты
ОбъектОбработки.Версия = "2.0";
ОбъектОбработки.Записать();

Проблема контекста: Клиент и Сервер

При работе в управляемом приложении крайне важно разделять код, выполняемый на клиенте и на сервере. Попытка записать объект справочника или обратиться к реквизиту типа ХранилищеЗначения непосредственно в процедуре ПриОткрытии (которая выполняется на клиенте) приведет к ошибке «Поле объекта недоступно для записи».

Выясним причину: запись в базу данных и работа с файловыми хранилищами объектов возможна только на стороне сервера. Рассмотрим правильную структуру вызовов:

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

Проанализируем пример реализации серверной части:


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

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

Особенности работы с путями к файлам

При использовании клиент-серверного варианта работы 1С:Предприятия возникает нюанс: сервер приложений может не иметь доступа к локальным дискам вашего компьютера (например, к папке C:\Users\Desktop\). Если файл обновления лежит на вашем рабочем столе, сервер его не увидит.

Рассмотрим способы решения этой проблемы:

Сравнение версий и логика обновления

Простое сравнение строк (Обработка.Версия <> ВерсияФайл) — это самый быстрый способ, однако он не учитывает иерархию версий (например, что 1.10 больше чем 1.9). Для более сложных систем рекомендуется использовать нормализованные номера версий и функции сравнения из состава БСП (Библиотеки стандартных подсистем).

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

Рекомендации по безопасности

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

  1. Код обновления выполняется в привилегированном модуле или с использованием метода УстановитьПривилегированныйРежим(Истина).
  2. У пользователя достаточно прав на редактирование справочника ДополнительныеОтчетыИОбработки.

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

← На главную