При активном использовании расширений в системе 1С:Предприятие 8 часто возникает необходимость информировать пользователя или администратора о том, какая именно версия доработки сейчас используется. Особенно это актуально, когда расширение добавляет новые документы или изменяет бизнес-логику существующих. В этой статье мы подробно разберем, как программно извлечь данные о расширении и как решить проблему "потерянного" имени исходного файла. При большом количестве доработок также может оказаться полезным инструмент для контроля и анализа изменений в подключенных расширениях.
Для начала проанализируем штатные возможности платформы. В системе 1С:Предприятие существует глобальный контекст РасширенияКонфигурации, который предоставляет доступ к коллекции всех загруженных в базу расширений. Чтобы получить список этих объектов, мы используем метод Получить(). Этот метод возвращает массив объектов типа РасширениеКонфигурации.
Рассмотрим пример кода, который позволяет перебрать все расширения и найти нужное нам по внутреннему имени. Предположим, наше расширение называется ДоработкиУчета.
// Функция ищет расширение по имени и возвращает его версию
Функция ПолучитьВерсиюРасширения(ИмяРасширения) Экспорт
МассивРасширений = РасширенияКонфигурации.Получить();
Для Каждого ТекущееРасширение Из МассивРасширений Цикл
Если ТекущееРасширение.Имя = ИмяРасширения Тогда
Возврат ТекущееРасширение.Версия;
КонецЕсли;
КонецЦикла;
Возврат "Версия не определена";
КонецФункции
Разберем, какие свойства объекта РасширениеКонфигурации нам доступны для чтения:
Выясним причину, по которой стандартными средствами невозможно получить имя файла (например, MyExtension_v2.cfe), из которого расширение было загружено. Дело в том, что после загрузки файла в базу данных (через конфигуратор или программно), платформа считывает бинарные данные и сохраняет их во внутренних системных таблицах СУБД. Путь к файлу на диске или его оригинальное название не сохраняются, так как для работы системы они не имеют значения.
Проанализируем ситуацию: если нам критически важно выводить в шапку документа не только версию, но и имя исходного файла, нам придется организовать собственное хранилище этой информации. Рассмотрим два основных способа решения этой задачи.
Самый простой, но требующий дисциплины способ — это записывать имя файла или дату сборки в поле Синоним или Описание при загрузке расширения. Если загрузка производится вручную администратором, он может сам дополнить синоним. Если же загрузка автоматизирована, можно использовать метод Установить() менеджера расширений.
Посмотрим на пример программной загрузки расширения с сохранением имени файла в описание:
Процедура ЗагрузитьРасширениеСИменемФайла(ПутьКФайлу)
Файл = Новый Файл(ПутьКФайлу);
ИмяФайла = Файл.Имя;
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
// Получаем текущие расширения или создаем новое
// В данном примере предполагаем программное добавление
НовоеРасширение = РасширенияКонфигурации.Создать();
НовоеРасширение.Имя = "НашеНовоеРасширение";
НовоеРасширение.Описание = "Загружено из файла: " + ИмяФайла;
НовоеРасширение.Записать(ДвоичныеДанные);
КонецПроцедуры
Более надежный и профессиональный метод — это создание в основной конфигурации (или в самом расширении) регистра сведений, например, ИсторияЗагрузкиРасширений. При каждой операции обновления расширения мы будем записывать туда:
Это позволит не только выводить информацию в шапку документа, но и вести полноценный аудит изменений системы.
Теперь перейдем к практической реализации задачи автора: выводу версии в форму документа. Рассмотрим пошагово, как это сделать в управляемых формах.
Во-первых, создадим в общем модуле расширения функцию, которая будет возвращать строку с нужной информацией. Назовем модуль Расш1_ОбщийМодульСервер.
Функция СведенияОВерсииДляФормы() Экспорт
ИмяЭтогоРасширения = "МоеРасширениеДляДокументов"; // Должно совпадать с именем в свойствах
НайденноеРасширение = РасширенияКонфигурации.НайтиПоИмени(ИмяЭтогоРасширения);
Если НайденноеРасширение <> Неопределено Тогда
Возврат СтрШаблон("Версия расширения: %1 (Имя: %2)",
НайденноеРасширение.Версия,
НайденноеРасширение.Имя);
КонецЕсли;
Возврат "Расширение не найдено";
КонецФункции
Во-вторых, в форме документа, который был добавлен через расширение, найдем процедуру ПриСозданииНаСервере. Мы можем динамически добавить декорацию (надпись) в шапку формы или изменить заголовок формы. Для упрощения таких задач можно использовать готовый общий модуль для программного добавления элементов и команд на формы.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем информацию
ТекстВерсии = Расш1_ОбщийМодульСервер.СведенияОВерсииДляФормы();
// Вариант 1: Изменение заголовка окна
ЭтаФорма.Заголовок = ЭтаФорма.Заголовок + " [" + ТекстВерсии + "]";
// Вариант 2: Добавление новой надписи на форму
ЭлементВерсия = Элементы.Добавить("НадписьВерсияРасширения", Тип("ДекорацияФормы"), ЭтаФорма);
ЭлементВерсия.Вид = ВидДекорацииФормы.Надпись;
ЭлементВерсия.Заголовок = ТекстВерсии;
ЭлементВерсия.ЦветТекста = ЦветаСтиля.ПоясняющийТекст;
КонецПроцедуры
Рассмотрим ситуацию, когда имени файла нет, но нам нужно точно знать, совпадает ли текущее расширение с тем, что лежит у разработчика в папке Release. Для этого проанализируем метод ПолучитьДанные(). Этот метод позволяет извлечь тело расширения в виде двоичных данных прямо во время работы системы.
Мы можем вычислить MD5 или SHA хэш этих данных. Если хэш совпадает с хэшем эталонного файла, значит, расширение идентично. Это отличный способ верификации без привязки к переменчивым именам файлов.
ДанныеРасширения = НайденноеРасширение.ПолучитьДанные();
Хэш = ПолучитьХешСтроку(ДанныеРасширения); // Используется стандартная или самописная функция расчета хэша
Проанализируем влияние этих действий на систему. Постоянный вызов РасширенияКонфигурации.Получить() в цикле при каждом открытии формы может незначительно замедлять работу, если расширений десятки. Рекомендуется кэшировать информацию о версии в повторно используемом модуле или в параметрах сеанса при начале работы системы.
Также помните, что если вы используете расширения в распределенных базах данных (РИБ) или в режиме разделения данных (SaaS), работа с менеджером расширений может иметь свои особенности доступа. В режиме разделения данных вы получите информацию только о тех расширениях, которые подключены к вашей области данных.
Подводя итог, можно сказать, что хотя 1С и не "помнит" имя файла .cfe после его импорта, платформа предоставляет достаточно инструментов для построения собственной системы контроля версий. Используйте комбинацию свойств Версия и ведение логов в регистрах для обеспечения полной прозрачности работы ваших расширений.