Реальная ситуация: после полугода доработки конфигурации появилась необходимость привести ее структуру в порядок. Разработчики по всем вносимым доработкам, например, использовали один общий модуль. Настало время разделить процедуры и функции этого модуля на отдельные части. Для решения подобной задачи нужно определиться со структурой конфигурацией, четко определить границы подсистем, включаемых в ее состав. Затем перенести процедуры и функции в соответствующие модули.
Конечно же, останавливаться на этом нельзя. Нужно поправить все модули в конфигурации, а также запросы, чтобы код продолжал стабильно работать. Также нельзя забывать о переопределении ссылок на процедуры из регламентных заданий и других мест конфигурации, где они используются. Все это можно проделать с помощью механизма глобальной замены конфигуратора.
Но даже после этого остается еще одно НО! Нужно исправить код во внешних отчетах и обработках, используемых пользователями.
Чтобы решить задачу мы можем воспользоваться стандартной возможностью конфигуратора по поиску и замене текстов модулей. На этот раз нам нужно будет установить настройки на вкладке "Файлы", где мы укажем каталог с внешними обработками и отчетами, а также указать текст поиска и замены.
Остается только выгрузить все внешние обработки из информационной базы в назначенный каталог, обработать тексты их модулей и загрузить обратно. Мы, конечно, можем проделать это вручную, но мы ведь программисты! Напишем обработку для автоматизации выгрузки / загрузки внешний отчетов и обработок. Для примера решим эту задачу для конфигурации "Управление производственным предприятием" релиза 1.3.
Обработка будет достаточно простой. Все внешние обработки и отчеты, прикрепленные к информационной базе, хранятся в справочнике "ВнешниеОбработки". Вот так выглядит структура метаданных справочника:
И так, приступим! На следующем листинге представлен листинг обработчика выгрузки внешний обработок и отчетов в заданный каталог.
Процедура КнопкаВыполнитьНажатие(Кнопка) // Вызываем диалог выбора каталога для выгрузки Режим = РежимДиалогаВыбораФайла.ВыборКаталога; ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим); ДиалогОткрытияФайла.ПолноеИмяФайла = ""; ДиалогОткрытияФайла.МножественныйВыбор = Ложь; ДиалогОткрытияФайла.Заголовок = "Выберите каталог"; Если ДиалогОткрытияФайла.Выбрать() Тогда ПутьККаталогу = ДиалогОткрытияФайла.Каталог; Иначе Текст = "Каталог не выбран"; Предупреждение(Текст); КонецЕсли; // Получаем внешние обработки и отчеты из базы данных Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ВнешниеОбработки.Наименование КАК ИмяОбработки, | ВнешниеОбработки.ХранилищеВнешнейОбработки КАК ФайлОбработки, | ЛОЖЬ КАК ЭтоТабЧасть, | ВнешниеОбработки.КомментарийКФайлуИсточнику КАК КомментарийСРасширениемФайла, | ВнешниеОбработки.Код |ИЗ | Справочник.ВнешниеОбработки КАК ВнешниеОбработки |ГДЕ | НЕ ВнешниеОбработки.ПометкаУдаления | И НЕ ВнешниеОбработки.ЭтоГруппа"; Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл ДвоичныеДанные = Выборка.ФайлОбработки.Получить(); // Если элемент справочника "ВнешниеОбработки" содержит двоичные данные файла // записываем его в каталог Если ДвоичныеДанные Неопределено Тогда // Имя сохраняемой обработки - код элемента справочника "Внешние обработки" ПутьДляСохраненияФайлаОбработки = ПутьККаталогу + "\" + Выборка.Код + "." + ПолучитьРасширениеФайла(Выборка.КомментарийСРасширениемФайла); ДвоичныеДанные.Записать(ПутьДляСохраненияФайлаОбработки); КонецЕсли; КонецЦикла; КонецПроцедуры
Загрузка внешних обработок представлена на следующем листинге:
Процедура КнопкаВыполнитьНажатие(Кнопка) // Выбираем каталог выгруженных ранее внешних обработок Режим = РежимДиалогаВыбораФайла.ВыборКаталога; ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим); ДиалогОткрытияФайла.ПолноеИмяФайла = ""; ДиалогОткрытияФайла.Заголовок = "Выберите каталог с обработками"; Если ДиалогОткрытияФайла.Выбрать() Тогда КаталогОбработок = ДиалогОткрытияФайла.Каталог; Иначе Текст = "ru = ""Каталог не выбран!""; en = ""Folder not selected!"""; Предупреждение(НСтр(Текст)); Возврат; КонецЕсли; // Получаем все файлы в каталоге МассивВнешниеОбработки = НайтиФайлы(КаталогОбработок, "*.*"); ЕстьОшибки = Ложь; // Запись внешних обработок в инф. базу делам // в единой транзакции и проверяем на ошибки НачатьТранзакцию(); Для Каждого Стр Из МассивВнешниеОбработки Цикл // Ищем элемент справочника "Внешние обработки" // по имени файла (в имени был ранее записан код элемента) РезультатПоиска = Справочники.ВнешниеОбработки.НайтиПоКоду(Стр.ИмяБезРасширения); Если НЕ РезультатПоиска.Пустая() Тогда // Если обработка найдена - получаем объект элемента и помещаем // в него двоичные данные файла обработки/отчета ОбъектОбработка = РезультатПоиска.ПолучитьОбъект(); ОбъектОбработка.ХранилищеВнешнейОбработки = Новый ХранилищеЗначения(Новый ДвоичныеДанные(Стр.ПолноеИмя)); Попытка ОбъектОбработка.Записать(); Исключение ОбщегоНазначения.Сообщение("Не удалось записать обработку с кодом: " + ОбъектОбработка.Код); ЕстьОшибки = Истина; КонецПопытки; КонецЕсли; КонецЦикла; // Если были ошибки - отменяем транзакцию. Все изменения отменяются. Если ЕстьОшибки Тогда ОтменитьТранзакцию(); Иначе ЗафиксироватьТранзакцию(); КонецЕсли; КонецПроцедуры
Используя приведенный алгоритм проблем с выгрузкой/загрузкой внешний обработок и отчетов быть не должно. Нужно лишь учитывать, что коды элементов справочника должны иметь уникальные имена и у пользователя, запускающего обработку, должны быть соответствующие права доступа.
Стоит понимать, что в некоторых случаях внешние обработки и отчеты могут храниться не в реквезите справочника "ХранилищеВнешнейОбработки", а в табличной части "Принадлежность". Тогда необходимо доработать представленные выше алгоритмы выгрузки/загрузки.
В итоге, рефакторинг и внесение изменений в модули внешних обработок/отчетов сводятся к трем шагам:
Обработки, представленные в примере выше, можно скачать по следующим ссылкам: