Правила доработки типовых конфигураций 1С для облегчения их дальнейшего обновления (часть 2)

Logo_1c_8_Razradotka

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

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

0. Оглавление

  1. Использование хранилища конфигураций
  2. Самоидентификация тестовых баз
  3. Обработка инициализации
  4. Справочник предопределённых значений
  5. Просмотр временных таблиц в отладчике
  6. Версии внешних отчётов и обработок

1. Использование хранилища конфигураций

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

  1. Для разработочных и одной тестовой базы.
  2. Для рабочей базы и специальной базы — сборки.

pravila-razrabotki-tipovyx-konfiguracij-chast2__001

В этом случае задача с момента начала разработки до переноса в продуктивную базу проходит следующие этапы:

  1. Разработка ведется в одной из разработочных баз
  2. После выполнения, задача помещается в разработочное хранилище конфигурации
  3. Далее, через хранилище задача попадает в тестовую базу (Тестовая 1)
  4. Если по задаче есть замечания, разработчик исправляет их в своей разработочной базе, а затем через хранилище снова передает изменения на тест в тестовую базу.
  5. Когда все этапы тестирования пройдены, разработчик сохраняет файл конфигурации из тестовой базы и посредством сравнения / объединения конфигураций переносит свою задачу в специальную базу — сборку.
  6. В сборке происходит дополнительный тест задачи (после переноса).
  7. Затем, все затронутые объекты помещаются в хранилище рабочей базы и сборки.
  8. В назначенное время все задачи помещенные в хранилище переносятся в рабочую базу.

На совсем небольших проектах возможно подключение всех баз к одному общему хранилищу конфигурации:

pravila-razrabotki-tipovyx-konfiguracij-chast2__002

2. Самоидентификация тестовых баз

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

pravila-razrabotki-tipovyx-konfiguracij-chast2__003

pravila-razrabotki-tipovyx-konfiguracij-chast2__004

В результате каждая копия может определить, является она рабочей базой или нет.

Если база — не рабочая, то:

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

Функцию проверку можно добавить, например, в процедуру «ПриНачалеРаботыСистемы()» модуля управляемого приложения.

Процедура ПриНачалеРаботыСистемы()

    // СтандартныеПодсистемы
    СтандартныеПодсистемыКлиент.ПриНачалеРаботыСистемы();
    // Конец СтандартныеПодсистемы

    //++ VION 08.09.2016 Общие объекты
    АБ_ОбщегоНазначенияКлиент.УстановитьЗаголовокИнформационнойБазы();
    //-- VION 08.09.2016

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

Где процедура «УстановитьЗаголовокИнформационнойБазы()» имеет следующий вид:

//**************************************************
Процедура УстановитьЗаголовокИнформационнойБазы() Экспорт
    Если АБ_ОбщегоНазначенияСервер.ЭтоРабочаяБаза() Тогда
        Возврат;
    КонецЕсли;
    ИмяИнформационнойБазы = АБ_ОбщегоНазначенияСервер.ПолучитьИмяИнформационнойБазы();
    УстановитьКраткийЗаголовокПриложения("(! "+ИмяИнформационнойБазы+" !)");
КонецПроцедуры

Также в этом примере используются следующие серверные процедуры:

//**************************************************
Функция ЭтоРабочаяБаза() Экспорт
    Если Врег(ПолучитьИмяИнформационнойБазы() )= Врег(СокрЛП(Константы.АБ_ИмяРабочейБазы.Получить())) Тогда
        Возврат Истина;
    Иначе
        Возврат Ложь;
    КонецЕсли;
Конецфункции

//**************************************************
Функция ПолучитьИмяИнформационнойБазы() Экспорт

    СтрокаПодключения = СтрокаСоединенияИнформационнойБазы();

    НомерСимвола = СтрНайти(СтрокаПодключения,"File=");
    Если НомерСимвола > 0 Тогда
        //Это Файловая база
        СтрокаСправа = Сред(СтрокаПодключения,НомерСимвола+6);
        Возврат Сред(СтрокаСправа,1,СтрДлина(СтрокаСправа)-2);
    КонецЕсли;

    НомерСимвола = СтрНайти(СтрокаПодключения,"Ref=");
    Если НомерСимвола > 0 Тогда
        //Это серверная база
        СтрокаСправа = Сред(СтрокаПодключения,НомерСимвола+5);
        Возврат Сред(СтрокаСправа,1,СтрДлина(СтрокаСправа)-2);
    КонецЕсли;

    Возврат "";

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

Результат:

pravila-razrabotki-tipovyx-konfiguracij-chast2__005

Обработчик регламентного задания, связанного с обменом данными, должен иметь соответствующую проверку:

//**************************************************
Процедура ВыполнитьОбменДанными() Экспорт

    Если НЕ АБ_ОбщегоНазначенияСервер.ЭтоРабочаяБаза() Тогда
        Возврат;
    КонецЕсли;

    //... Код регламентной процедуры

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

3. Обработка инициализации

Некоторые модификации требуют действий, которые нельзя выполнить в конфигураторе. Например, заполнение реквизитов предопределённых элементов справочника (помимо кода и наименования), обязательное первоначальное заполнение каких-либо значений. Все подобные действия по разным задачам проекта следует выполнять в одном месте — в обработке инициализации.

Для данной обработки должны соблюдаться следующие правила:

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

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

Один из вариантов реализации такого механизма:

pravila-razrabotki-tipovyx-konfiguracij-chast2__008

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

В данном примере, добавлена константа «АБ_ВерсияВыполненнойОбработкиИнициализации»

pravila-razrabotki-tipovyx-konfiguracij-chast2__007

В модуле управляемого приложения в процедуру «ПриНачалеРаботыСистемы()» добавлен вызов серверной процедуры:

Процедура ПриНачалеРаботыСистемы()

    // СтандартныеПодсистемы
    СтандартныеПодсистемыКлиент.ПриНачалеРаботыСистемы();
    // Конец СтандартныеПодсистемы

    //++ VION 08.09.2016 Общие объекты
    АБ_ОбщегоНазначенияКлиент.УстановитьЗаголовокИнформационнойБазы();
    АБ_ОбщегоНазначенияСервер.ВыполнитьОбработкуИнициализации();
    //-- VION 08.09.2016

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

Которая проверяет наличие прав и вызывает обработку инициализации:

//**************************************************
Процедура ВыполнитьОбработкуИнициализации() Экспорт

    Если РольДоступна("ПолныеПрава") Тогда
        Обработки.АБ_ОбработкаИнициализации.Создать().ВыполнитьОбработку();
    КонецЕсли;

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

Код модуля обработки инициализации

//////////////////////////////////////////////////////////

// ОБРАБОТКА ИНИЦИАЛИЗАЦИИ
// --------------------------
// Обработку предполагается запускать многократно.
// Каждое действие должно корректно отрабатывать как при первом запуске обработки, так и при повторных запусках.
// Во втором случае не должно быть каких-либо побочных эффектов или потери введённых пользователем данных.
// В некоторых случаях (если того требует задача) возможно выявление и исправление настроек, уже сделанных,
// но некорректно изменённых пользователем с момента предыдущей инициализации.
// --------------------------
// Используемые объекты конфигурации:
//  1. Константа.ВерсияВыполненнойОбработкиИнициализации - Тип: Число (5,0)
//  2. Вызов обработки при старте системы: Обработки.ОбработкаИнициализации.Создать().ВыполнитьОбработку();
// --------------------------
// Алгоритм для разработчика:
//   1. В процедуре ПолучитьТекущуюВерсиюОбработки() увеличиваете весрию на 1, напрмер было 3, вы ставите 4.
//   2. В модуль обработки добавляете процедуру ОбработкаИнициализации_Весия_4(Отказ).
//   3. Если в процессе обработки возникли ошибки, необходимо установить переменную Отказ в значение Истина.
//   4. Необходимый код располагаете в данной процедуре.

//********************************************************
Функция ПолучитьТекущуюВерсиюОбработки() Экспорт

    // ВНИМАНИЕ!
    // Код не комментируем, просто увеличиваем текущую версию обработки
    // Тип версии - Число (5,0)
    Возврат 3;

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

//********************************************************
Функция ПолучитьПрошлуюВерсиюОбработки() Экспорт

    Возврат Константы.АБ_ВерсияВыполненнойОбработкиИнициализации.Получить();

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

//********************************************************
Функция УстановитьВерсиюОбработки(ТекущаяВерсия) Экспорт

    //Запишем текущую версию в константу
    Попытка
        Константы.АБ_ВерсияВыполненнойОбработкиИнициализации.Установить(ТекущаяВерсия);
        Возврат Истина;
    Исключение
        Сообщить("Обработка инициализации: " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;

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

//********************************************************
Функция ВыполнитьОбработку(ВсеОбработчики = Ложь) Экспорт

    //Обработку инициализации может выполнить только пользователь с полными правами
    Если Не РольДоступна("ПолныеПрава") Тогда
        Сообщить("Обработка инициализации: Недостаточно прав для выполнения обработки!");
        Возврат Ложь;
    КонецЕсли;

    Если ВсеОбработчики Тогда
        ПрошлаяВерсия = 0;
    Иначе
        ПрошлаяВерсия = ПолучитьПрошлуюВерсиюОбработки();
    КонецЕсли;
    ТекущаяВерсия = ПолучитьТекущуюВерсиюОбработки();

    //Обработка не нужна
    Если ТекущаяВерсия <= ПрошлаяВерсия Тогда
        Возврат Истина;
    КонецЕсли;

    //В цикле выполняем все необходимые обработки
    Отказ = Ложь;
    Для Сч = ПрошлаяВерсия+1 По ТекущаяВерсия Цикл
        Выполнить("ОбработкаИнициализации_Весия_"+Сч+"(Отказ);");
    КонецЦикла;

    Если Отказ Тогда
        Сообщить("Обработка инициализации: Ошибка выполнения обоработки!");
        Возврат Ложь;
    КонецЕсли;

    //Запишем текущую версию в константу
    Если УстановитьВерсиюОбработки(ТекущаяВерсия) Тогда
        Сообщить("Обработка инициализации: Переход на версию " + ТекущаяВерсия + " выполнен успешно!");
        Возврат Истина;
    Иначе
        Возврат Ложь;
    КонецЕсли;

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

//********************************************************
Процедура ОбработкаИнициализации_Весия_1(Отказ)

    //Действия обработчика
    Сообщить("Обработка инициализации, выполнен переход на версию 1");

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

Форма обработки:

pravila-razrabotki-tipovyx-konfiguracij-chast2__006

Скачать обработку можно, например, здесь.

4. Справочник предопределённых значений

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

pravila-razrabotki-tipovyx-konfiguracij-chast2__009

Далее по каждой возникшей задаче в этот справочник добавляется предопределенный элемент.

pravila-razrabotki-tipovyx-konfiguracij-chast2__011

Реквизит «Значение» данного элемента заполняется обработкой инициализации или вручную.

pravila-razrabotki-tipovyx-konfiguracij-chast2__010

Обращение к такому значению осуществляется подобным кодом:

КонтрагентАгроимпульс = Справочники.АБ_ПредопределенныеЗначения.Контрагент_Агроимпульс.Значение;

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

5. Просмотр временных таблиц в отладчике

При отладке сложных запросов с временными таблицами нужна возможность просматривать содержимое этих таблиц, которую отладчик не предоставляет.

Для просмотра временных таблиц запроса в отладчике удобно использовать специальную функцию. Данная функция парсит текст запроса, вычленяет все временные таблицы, вычисляет их и результат складывает в структуру.

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

funkciya-prosmotra-vremennyx-tablic-zaprosa-v-otladchike_03

funkciya-prosmotra-vremennyx-tablic-zaprosa-v-otladchike_04

Функция предназначена для использования в окне «Вычислить выражение» отладчика — возвращает значение, удобное для просмотра в этом окне. Функция максимально автоматизирована и может работать с входными данными разных типов. Назначение аргументов функции понятно из их имён.

funkciya-prosmotra-vremennyx-tablic-zaprosa-v-otladchike_01

Текст процедур можно посмотреть — здесь.

6. Версии внешних отчётов и обработок

При использовании внешних отчетов и обработок в поле «Комментарий» следует указывать строку, отображающую условную версию объекта. Например, начиная с «v1.0» и далее увеличивая старший или младший номер (в зависимости от объёма изменений) при каждом цикле доработки объекта.

pravila-razrabotki-tipovyx-konfiguracij-chast2__012

Данный комментарий доступен из кода, и при открытии формы его следует добавлять к заголовку окна:

#Область СобытияФормы

////////////////////////////////////////////////////////////
// ОБРАБОТЧИКИ СОБЫТИЙ ФОРМЫ

//**********************************************************
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    //Заголовок формы
    ЭтаФорма.АвтоЗаголовок = Ложь;
    ЭтаФорма.Заголовок = ЗаголовокОтчета();

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

//**********************************************************
&НаСервере
Функция ЗаголовокОтчета()

    ТекОбъект = РеквизитФормыВЗначение("Объект");
    Комментарий = ТекОбъект.Метаданные().Комментарий;
    Возврат ТекОбъект.Метаданные().Синоним
        + ?(ЗначениеЗаполнено(Комментарий)," (" + Комментарий + ")","");

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

#КонецОбласти

Тогда версия обработки или отчета всегда будет видна в заголовке формы.

pravila-razrabotki-tipovyx-konfiguracij-chast2__013

Помогла ли вам данная статья?
Да, спасибо, помогла.
Немного помогла.
Совсем не помогла.
Не то, что я искал(а).
Смотреть результаты
Запись опубликована в рубрике Разработка в 1С. Добавьте в закладки постоянную ссылку.


2 Responses to Правила доработки типовых конфигураций 1С для облегчения их дальнейшего обновления (часть 2)

  1. Владимир говорит:

    В качестве префиксации объектов метаданных и реквизитов все таки лучше использовать символы в нижнем регистре. Очень отвлекает внимание и мешает чтению кода префиксы вида НАШАСУПЕРКОМПАНИЯ_ДатаНачалаПримененияФункционала. Особенно если доработку ведет франчайзи.

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

    Посмотрите например как сделано в «Инструментах разработчика» ир_ДатаНачалаДейстия. Гораздо удобнее читать код с ас_ДобавленныйРеквизит, чем АС_ДобавленныйРеквизит.

    Конечно это дело вкуса, но думаю многие с этим согласятся.

  2. Владимир говорит:

    Дополнительно стоит отметить что префиксация с заглавных букв часто применяется для придания префиксу логического смысла. «ФСС_НашДокумент», «ККТ_Настройки», конечно это не в принятой в 1С нотации , но встречается часто. И префикс в верхнем регистре сразу настраивает на поиск логического смысла в этом префиксе. Префиксы в нижнем регистре являются стандартным способом выделить внешний по отношении к конфигурации добавленный объект и не сбивают с толку.

    В общем советую попробовать ))

Добавить комментарий для Владимир Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *