В процессе сопровождения информационных систем на базе 1С часто возникает задача автоматизации обновления внешних обработок. Особенно это актуально, когда обработка активно дорабатывается, а пользователей много. Вместо того чтобы вручную заходить в справочник ДополнительныеОтчетыИОбработки и обновлять файл, можно реализовать механизм самообновления при запуске. В этой статье мы подробно разберем, как правильно реализовать проверку версии и обновление двоичных данных обработки, а также проанализируем типичные ошибки, с которыми сталкиваются разработчики.
Рассмотрим сценарий: при открытии внешней обработки программа должна проверить, совпадает ли версия текущей обработки с версией, указанной в некоем внешнем источнике (например, в текстовом файле или сетевом ресурсе). Если версии различаются, система должна программно перезаписать двоичные данные в справочнике ДополнительныеОтчетыИОбработки и обновить номер версии.
Одной из первых проблем, с которой сталкиваются программисты, является неправильная работа с методом ПолучитьОбъект(). Проанализируем фрагмент кода, который часто приводит к ошибке:
Обработка = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Загрузка");
Обработка.ПолучитьОбъект(); // Ошибка! Объект не присвоен переменной
Обработка.Наименование = "Загрузка V2";
Важно помнить: метод ПолучитьОбъект() возвращает новый объект типа СправочникОбъект, но не преобразует саму ссылку в объект. Чтобы иметь возможность изменять реквизиты и записывать данные, необходимо обязательно присвоить результат выполнения метода переменной.
Правильный вариант кода выглядит так:
СсылкаНаОбработку = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Загрузка");
ОбъектОбработки = СсылкаНаОбработку.ПолучитьОбъект();
// Теперь мы можем менять реквизиты
ОбъектОбработки.Версия = "2.0";
ОбъектОбработки.Записать();
При работе в управляемом приложении крайне важно разделять код, выполняемый на клиенте и на сервере. Попытка записать объект справочника или обратиться к реквизиту типа ХранилищеЗначения непосредственно в процедуре ПриОткрытии (которая выполняется на клиенте) приведет к ошибке «Поле объекта недоступно для записи».
Выясним причину: запись в базу данных и работа с файловыми хранилищами объектов возможна только на стороне сервера. Рассмотрим правильную структуру вызовов:
ПриОткрытии на клиенте инициируется проверка.&НаСервере), где происходит поиск элемента справочника, сравнение версий и запись нового файла.Проанализируем пример реализации серверной части:
&НаСервере
Процедура ОбновитьОбработкуНаСервере(ВерсияИзФайла, ПутьКФайлу)
Ссылка = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("Загрузка");
Если Ссылка.Пустая() Тогда
Возврат;
КонецЕсли;
Объект = Ссылка.ПолучитьОбъект();
// Сравниваем версии
Если Объект.Версия <> ВерсияИзФайла Тогда
// Читаем новый файл в двоичные данные
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
// Помещаем в ХранилищеЗначения
Объект.ХранилищеОбработки = Новый ХранилищеЗначения(ДвоичныеДанные);
Объект.Версия = ВерсияИзФайла;
Попытка
Объект.Записать();
Сообщить("Обработка успешно обновлена до версии " + ВерсияИзФайла);
Исключение
ЗаписьЖурналаРегистрации("ОбновлениеОбработки", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецПроцедуры
При использовании клиент-серверного варианта работы 1С:Предприятия возникает нюанс: сервер приложений может не иметь доступа к локальным дискам вашего компьютера (например, к папке C:\Users\Desktop\). Если файл обновления лежит на вашем рабочем столе, сервер его не увидит.
Рассмотрим способы решения этой проблемы:
ПоместитьФайл(), а затем передаем адрес этого хранилища на сервер, где извлекаем данные.Простое сравнение строк (Обработка.Версия <> ВерсияФайл) — это самый быстрый способ, однако он не учитывает иерархию версий (например, что 1.10 больше чем 1.9). Для более сложных систем рекомендуется использовать нормализованные номера версий и функции сравнения из состава БСП (Библиотеки стандартных подсистем).
Также стоит обратить внимание на то, что после успешной записи новой версии в справочник, текущий сеанс пользователя все еще использует «старый» код, который уже загружен в память. Для вступления изменений в силу пользователю потребуется перезапустить обработку. Поэтому в процедуре обновления желательно добавить уведомление: «Доступна новая версия, пожалуйста, перезапустите форму».
Поскольку внешние обработки часто работают в Безопасном режиме, прямая попытка записи в справочник или чтение файлов может быть заблокирована профилями безопасности. Если вы столкнулись с ошибкой прав доступа, убедитесь, что:
УстановитьПривилегированныйРежим(Истина).ДополнительныеОтчетыИОбработки.Используя предложенные шаги и исправляя ошибки контекста, вы сможете создать надежный механизм актуализации ваших разработок без необходимости ручного вмешательства в справочники информационной базы.