Каталог решений - Как облегчить обновление нетиповой конфигурации?

Как облегчить обновление нетиповой конфигурации?

Как облегчить обновление нетиповой конфигурации?

В наличии

или как я обновил УПП с 1.2.5 до 1.2.28…
В результате:
1с 8.1 УПП 1.2.28 со всеми изменениями и рабочими внешними обработками
размер базы 100 гб за счет частичной свертки базы за 2 года (пока без удаления документов — база будет ещё меньше).

Категория:

Описание

 

Было дано:
Сервер IBM на 2х четырехядерных XEON по 2Ггц, 16 Гб оперативной MS SQL 2000 1с 8.1 УПП 1.2.5 с изменениями в формах и модулях ключевых документов и справочников, несколько десятков внешних обработок и печатных форм — замена типовых. средний размер базы за время обновления 110-120 Гб содержание базы на начало обновления: производство, торговля(крупный и мелкий опт) и бухгалтерия с 2006 года; несколько тысяч контрагентов; от 10000 до 20000 торговых документов в месяц. перерыв в работе: с 19 часов субботы до 8 утра воскресенья. Ну и иногда 15-20 минут в день в районе обеда и 1 час где-то в промежуток между 23 и 4 часов ночи.

В результате: 1с 8.1 УПП 1.2.28 со всеми изменениями и рабочими внешними обработками размер базы 100 гб за счет частичной свертки базы за 2 года (пока без удаления документов — база будет ещё меньше).
После некоторых событий досталась мне одному УПП 1.2.5. Её конечно до этого периодически обновляли, но в тот момент последний доступный релиз был версии 1.2.19. Сначала я решил обновить сразу до последнего релиза. Но короткий анализ показал, что этого лучше не делать по нескольким причинам:

  1. При обновлении структуры конфигурации, а не только кода, требуется реструктуризация соответствующих метаданных. При больших объемах данных это занимает очень много времени.

  2. Дикое количество обновлений в типовых механизмах существенно усложняет перенос собственных изменений, т. к. нужно понять суть обновления и проследить как это повлияет на твой код и будет ли он вообще работать.

  3. После обновления базы рекомендуется (а иногда необходимо) запускать пакет специальных обработок. Данный пакет обработок от релиза к релизу дополняется, но иногда полностью удаляется и пишется с нуля.

  4. Иногда происходят тотальные изменения в конфигурации, требующие предварительной подготовки БД (например, переход с учета авансов на счетах, на учет на регистрах)

(подробнее читать тут  http://www.infostart.ru/public/18596/)

На первых 3 пункта по отдельности можно было забить (а до 4го ещё тогда не дошел), но все вместе их игнорировать сложно.

Опущу технологию обновления — в общих чертах она совпадала с:

http://www.infostart.ru/public/19310/

http://www.infostart.ru/public/18562/

 

Резонные вопрос — а о чем тогда писать дальше? А вот есть плохо раскрытый пункт про работу руками…в том смысле, что перенос изменений в обновленные объекты. Я хотел написать про облегчение/уменьшение внесения как раз этих ручных операций. Далее пойдет описание событий, кому не интересно переходите к Заключению.

Что облегчило первый перенос — так это почти полностью комментированные изменения. Если этого не было сделано, то сделать это нужно обязательно. Выявить изменения можно запустив Сравнение конфигураций — Конфигурации поставщика и Конфигурации базы данных. У меня уже это было сделано.

Долго ли коротко, последовательно начал переносить изменения. Просто копировать код не получилось. Обновились и модули, в которые вносились изменения, и вызываемые процедуры из общих модулей, и сама структура метаданных. Таким образом, сначала приходилось разбираться зачем сделали изменение, а потом уже частенько заново писать код. Но сложнее всего было с формами: заново вносить изменения в форму — нудная и долгая работа. И опять — это был не конец. Остались внешние печатные формы и обработки, которые использовали типовые функции и процедуры. В них точно также пришлось разбираться заново и искать вызов типовых процедур (менялись названия, модули размещения и кол-во параметров). Особо хочется поблагодарить разработчиков 1с за замену функции ЗначениеНеЗаполнено на ЗначениеЗаполнено… Но вот, наконец, было закончен перенос изменений и я выгрузил cf файл. Как раз к новогодним праздникам и поспел. Обновил конфигурацию на основной базе, объединил с cf файлом…и запустил обновление конфигурации БД… Через несколько часов выявилась и критичность 1 пункта — времени. Конфигуратор отвалился с радостным сообщение о нехватке памяти… Есть такая беда с фрагментированностью оперативной памяти (или как-то так, на старых платформах приводило к ошибке SDBL). Лечится перезагрузкой. В общем, перезагрузил и всё заново. Если бы не такие большие праздники — не успел бы. Хорошо хоть с пакетом обработок проблем не случилось (хотя чуть позже столкнулся с проблемой для Бухгалтерии — пакет обработок выдавал ошибку после длительного процесса). Обновление случилось на грани и заняло несколько сотен часов.

Повторять такое обновление мне хотелось — начал думать как облегчить следующее.

Для начала я решил уменьшить количество измененного кода в типовых модулях. Открываем конфигуратор — какая интересная ветка в конфигурации — «Подписки на события» http://v8.1c.ru/overview/Term_000000153.htm. Достаточно много изменений в конфигурации были сделаны для того, чтобы проверять и ограничивать изменение данных. Именно для таких изменений хорошо подходит подписки на события. Завел общий модуль для подписок и насоздавал оных для замены части измененного кода. Обычно изменения превращались в процедуры, которые:

устанавливает значение переменной Отказ, которая регулирует дальнейшую запись или проведение объекта;

устанавливает какое-то конкретное значение в объекте перед/при его записи

выводит некоторое сообщение

делает дополнительные движения

Но все изменения таким образом переделать не получилось. Остались изменения, связанные с работой форм, полностью самописные функции и процедуры и им подобные. Для того, чтобы облегчить перенос этих изменений при обновлений нужно было уменьшить их объем. Для этого создал общий модуль НашМодуль и загнал туда все самописные функции и процедуры, естественно с ключевым словом Экспорт, если необходимо. Но на этом останавливаться не стал — куски дописанного кода заменил вызовом функций и процедур, которые поместил опять-таки в НашМодуль. Далее последовали куски измененного кода — небольшие изменения я оставил на месте пометив в комментариях в том числе и причину изменений, а вот большие изменения перенес в НашМодуль вместе с последующим типовым кодом. В измененные типовые процедуры добавил вызовы этих процедуры и функций, а после них подходящие по смыслу переходы: Возврат, Прервать, Продолжить. Всё, конечно, изменить малой кровью не получилось, но при последующих обновлениях перенос измененного кода существенно облегчился. Теперь достаточно получить список измененных два раза (относительно основной конфигурации и относительно обновленной), переписать куда-нибудь (хоть в блокнот) список объектов с парой строк измененного кода и после обновления проверить работоспособность функции и процедур в модуле НашМодуль.

Следующее, что я сделал — это вдруг увидел замечательную обработку «Декомпиляция и анализ форм с генерацией кода формы» http://www.infostart.ru/public/22147/. С помощью этой обработки я перевел все изменения в формах в код, который запихнул в тот же самый НашМодуль, а их вызов в модули форм в процедуры ПриОткрытии или ПередОткрытием. И вуаля! Никаких изменений в формах — только код, обновлять который уже много легче.

И всё вроде бы было замечательно…Но осталось несколько десятков внешних обработок и печатных форм. Заново в них исправлять из-за смены модуля, где сидит нужная функция — то ещё удовольствие. Решение было логическим продолжением предыдущих — вызов типовых был перенесен в НашМодуль, а во внешних обработках используется обращение к НашемуМодулю. Таким образом, после обновления достаточно будет проверить НашМодуль и не лазить по всем обработкам.

Закончив все предварительные изменения в конфигурации, я перешел к следующему обновлению. Делал я его уже более классическим способом через файл обновления. Только теперь мне не пришлось сравнивать формы и заново переносить гигантские куски кода или переделать типовые процедуры в нескольких местах. Обычно изменения сводились к добавлению 1-5 строчек в начало или конец процедуры… Вместо предыдущих сотен часов — обновление заняло около 8 часов!!! Причем теперь время обновления не зависит от дотошного знания изменений в конфигурации, т. к. изменений этих в типовых объектах — минимум. Кроме того, не приходится каждый раз обновлять множество внешних обработок!

В дополнении хочу дать ссылку на ещё один способ, прекрасно дополняющий, всё что здесь написано: http://www.infostart.ru/public/16980/ .

 

Заключение

 

Итак, что нужно делать, чтобы облегчить обновление?

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

1. Комментировать все изменения в конфигурации. Найти отличия от типовой можно через Сравнение конфигураций в режиме Конфигурация поставщика — Конфигурация базы данных

2. Вынос изменений, связанных с записью и обновлением объектов в Подписки на события

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

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

5. Использование обработки «Декомпиляция и анализ форм с генерацией кода формы» http://www.infostart.ru/public/22147/ для изменения форм объектов — не нужно сравнивать формы и переносить изменения в них, а только вызов процедуры.

 В результате скорость обновления нетиповой конфигурации возрастает в несколько раз (в моем случае с пары сотен часов, до 8)

 

 

Приложение 1. Примеры процедур и функций

 

Пример процедуры обработки подписки «Перед записью» справочника номенклатуры. Процедура запрещает любые изменения в группах справочника, чтобы кривые руки на мышках, например, не перетащили ОС в Продукцию…Исключение составляют пользователи с полными правами.

 

Процедура НЕТРОГАЕМГРУППЫ(Источник,Отказ) Экспорт

    Если Источник.ОбменДанными.Загрузка ИЛИ ПользователиИнформационнойБазы.ТекущийПользователь().Роли.Содержит(Метаданные.Роли.ПолныеПрава) Тогда
        Возврат;
    КонецЕсли;

    Если Источник.ЭтоГруппа Тогда
       
Отказ=Истина;
    КонецЕсли;
КонецПроцедуры

 

Пример, когда при записи реализации в её свойства записывается основной менеджер контрагента, если ещё не заполнено

 

 

Процедура УстановкаТорговогоПредставителяРеализацииПриЗаписи(Источник, Отказ) Экспорт //mav

    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    Если (НЕ ПользователиИнформационнойБазы.ТекущийПользователь().Роли.Содержит(Метаданные.Роли.нашБухгалтер)
            И НЕ
ПользователиИнформационнойБазы.ТекущийПользователь().Роли.Содержит(Метаданные.Роли.ПолныеПрава))
            И
ПроверкаДатыНаЗапрет(Источник.Дата) Тогда

        Сообщить(«Число дней превышено. Проводить нельзя.»);
       
Отказ=Истина;
        Возврат;
    КонецЕсли;

    Запрос=Новый Запрос();
   
Запрос.Текст=«ВЫБРАТЬ
                 |  ЗначенияСвойствОбъектов.Значение
                 |ИЗ
                 |  РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
                 |ГДЕ
                 |  ЗначенияСвойствОбъектов.Свойство.Код = «»00032      «»
                 |  И ЗначенияСвойствОбъектов.Объект = &Ссылка»
;
   
Запрос.УстановитьПараметр(«Ссылка»,Источник.Ссылка);
   
Результат=Запрос.Выполнить().Выбрать();

    Если Результат.Следующий() Тогда
        Если
ЗначениеЗаполнено(Источник.Сделка) Тогда
           
Запрос.УстановитьПараметр(«Ссылка»,Источник.Сделка);
           
Результат1=Запрос.Выполнить().Выбрать();
            Если
Результат1.Следующий() Тогда
                Если
Результат1.Значение<>Результат.Значение Тогда
                   
Сообщить(«Не совпадают менеджеры. Заказ-«+Результат1.Значение+«, Реализация-«+Результат.Значение);
                КонецЕсли;
            Иначе
                Если
Результат.Значение<>Источник.Контрагент.ОсновнойМенеджерПокупателя Тогда
                   
Сообщить(«Не совпадает Основной менеджер-«+Источник.Контрагент.ОсновнойМенеджерПокупателя+» и Реализация-«+Результат.Значение);
                КонецЕсли;
            КонецЕсли;
        Иначе
            Если
Результат.Значение<>Источник.Контрагент.ОсновнойМенеджерПокупателя Тогда
               
Сообщить(«Не совпадает Основной менеджер-«+Источник.Контрагент.ОсновнойМенеджерПокупателя+» и Реализация-«+Результат.Значение);
            КонецЕсли;
        КонецЕсли;

    Иначе
        Менеджер=Справочники.Пользователи.ПустаяСсылка();
        Если
ЗначениеЗаполнено(Источник.Сделка) Тогда
           
Запрос.УстановитьПараметр(«Ссылка»,Источник.Сделка);
           
Результат=Запрос.Выполнить().Выбрать();
            Если
Результат.Следующий() Тогда
               
Менеджер=Результат.Значение;
            Иначе
               
Менеджер=Источник.Контрагент.ОсновнойМенеджерПокупателя;
            КонецЕсли;
        Иначе
           
Менеджер=Источник.Контрагент.ОсновнойМенеджерПокупателя;
        КонецЕсли;

        Если ЗначениеЗаполнено(Менеджер) Тогда
           
Рег=РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
           
Рег.Активность=Истина;
           
Рег.Значение=Менеджер;
           
Рег.Объект=Источник.Ссылка;
           
Рег.Свойство=ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоКоду(«00032      «);
           
Рег.Записать();
           
//Сообщить(«В реализации установлен менеджер «+Менеджер);
       
КонецЕсли;
    КонецЕсли;

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

Пример использования декомпиляции форм для создания дополнительных элементов формы. В данном случае добавляется новая колонка в форму реализации. Реквизит «Дата выработки» был предварительно добавлен в реквизиты табличной части документа — это совершенно не мешает обновлению

 

Процедура mavСформироватьВнешнийВидЗаказПокупателя(ЭлементыФормы) Экспорт

    //————————————-
   
Колонка = ЭлементыФормы.Товары.Колонки.Вставить(19,«ДатаВыработки»);
   
Колонка.УстановитьЭлементУправления( Тип(«ПолеВвода») );
   
Колонка.Имя = «ДатаВыработки»;
   
Колонка.Данные = «ДатаВыработки»;
   
Колонка.Ширина = 15;
   
Колонка.ТекстШапки = «Дата выработки»;
   
//……………………………….
   
Колонка.ЭлементУправления.ВертикальноеПоложение = ВертикальноеПоложение.Верх;
   
Колонка.ЭлементУправления.КнопкаОчистки = ложь;
   
Колонка.ЭлементУправления.ОграничениеТипа = Новый ОписаниеТипов(«»,,,);
   
//Колонка.ЭлементУправления.ТипЗначения = Новый ОписаниеТипов(«Строка»,,,);

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

 

Пример для пункта 4. Создание «ярлыков» на типовые модули:

Функция mavПолучитьКурсВалюты(Валюта, ДатаКурса) Экспорт

    Возврат(МодульВалютногоУчета.ПолучитьКурсВалюты(Валюта, ДатаКурса));

КонецФункции

 

 

has been added to your cart:
Оформление заказа