БСП: Дополнительная обработка (Регламенты), примеры от простого к сложному
Для экспериментов я использовал Платформы 8.3.10.2650 и 8.3.12.1440, конфигурации БСП 2.4.6.56 и 3.0.1.135.
Завершили мы предыдущую часть так -> Два регламента, форма с ручным запуском и сохранение параметров для регламентов.
Как Вы понимаете, с одной стороны удобно добавлять регламентные задания в дополнительную обработку и обновлять ее, с другой стороны, если нам нужно только поправить код, это опять нужно править обработку и ее закидывать в дополнительные отчеты и обработки. Да и добавление новых регламентных заданий несет некий дискомфорт… Давайте попытаемся сделать мир лучше и удобнее!
Содержание:
Задача 1. Частичный перенос функционала в расширение 8.3.10
Задача 2. Используем расширение 8.3.12 по максимуму
Задачи и решения.
Задача 1: Вынести добавление регламентных заданий из обработки в расширение.
Добавляем расширение конфигурации
Добавляем модуль БПСПро_ОбщийМодуль и создаем процедуру ЗаполнитьКоманды (ПараметрыРегистрации) Экспорт
Нарочно оставляем ее пустой, это нужно, чтобы показать еще одну проблему.
Создаем копированием обработку из предыдущей части и в модуле меняем функцию описания:
Так же меняем у обработки имя(БСППро_Регламены) и синоним(БСППро: Регламенты)
Сохраняем обработку и добавляем ее в нашу конфигурацию для тестов БСП демо.
Теперь в расширение добавим регламенты.
Процедура ЗаполнитьКоманды(ПараметрыРегистрации) Экспорт
//Регламент1
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru = 'Задача 1 регламент'");
НоваяКоманда.Идентификатор = "Задача1Регламент";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
//Регламент2
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru = 'Задача 2 регламент'");
НоваяКоманда.Идентификатор = "Задача2Регламент";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
КонецПроцедуры
Заходим в нашу обработку и что мы видим? Регламентов нет. Открываем форму и видим, что список с регламентами работает.
Мы даже вручную его можем выполнить!
На самом деле все очень просто, список в дополнительных обработках обновляется в момент загрузки файла.
Давайте починим этот момент, тем более у нас на вооружении расширение конфигурации.
Находим справочник ДополнительныеОтчетыИОбработки и добавляем ФормуЭлемента в расширение.
Добавляем команду «ОбновитьКомандыПро» на форму
Прописываем действие:
//Обновляем регламентные задания
&НаКлиенте
Процедура БПСПро_ОбновитьКомандыПроПосле(Команда)
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Успех", Ложь);
ПараметрыРегистрации.Вставить("АдресДанныхОбработки", АдресДанныхОбработки);
ПараметрыРегистрации.Вставить("ИмяФайла", Объект.ИмяФайла);
ПараметрыРегистрации.Вставить("ОтключатьПубликацию", Ложь);
ПараметрыРегистрации.Вставить("ОтключатьКонфликтующие", Ложь);
ПараметрыРегистрации.Вставить("Конфликтующие", Новый СписокЗначений);
ПараметрыРегистрации.Вставить("ЭтоОтчет", Ложь);
ОбновлениеИзФайлаМеханикаНаСервере(ПараметрыРегистрации);
// Обработка результата работы сервера.
Если ПараметрыРегистрации.Успех Тогда
ОповещениеЗаголовок = НСтр("ru = 'Команды обновлены!'");
ПоказатьОповещениеПользователя(ОповещениеЗаголовок);
ОбновлениеИзФайлаЗавершение(Неопределено, ПараметрыРегистрации);
КонецЕсли;
КонецПроцедуры
//Обновляем регламентные задания
&НаКлиенте
Процедура БПСПро_ОбновитьКомандыПроПосле(Команда)
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Успех", Ложь);
ПараметрыРегистрации.Вставить("АдресДанныхОбработки", АдресДанныхОбработки);
ПараметрыРегистрации.Вставить("ИмяФайла", Объект.ИмяФайла);
ПараметрыРегистрации.Вставить("ОтключатьПубликацию", Ложь);
ПараметрыРегистрации.Вставить("ОтключатьКонфликтующие", Ложь);
ПараметрыРегистрации.Вставить("Конфликтующие", Новый СписокЗначений);
ПараметрыРегистрации.Вставить("ЭтоОтчет", Ложь);
//ОбновлениеИзФайлаМеханикаНаСервере(ПараметрыРегистрации);
ОбновитьИзФайлаИСообщить(ПараметрыРегистрации);
// Обработка результата работы сервера.
Если ПараметрыРегистрации.Успех Тогда
ОповещениеЗаголовок = НСтр("ru = 'Команды обновлены!'");
ПоказатьОповещениеПользователя(ОповещениеЗаголовок);
//ОбновлениеИзФайлаЗавершение(Неопределено, ПараметрыРегистрации);
ОбновитьИзФайлаЗавершение(Неопределено, ПараметрыРегистрации);
КонецЕсли;
КонецПроцедуры
Сразу скажу: Вырезал из типовой все, что понадобится для регламентов, для других типов команд не пробовал обновлять!
Проверяем:
Заполним параметры:
Проверим, работают ли регламенты, заполним время и подождем…
Первая задача выполнена!
Для решения этой задачи возможностей расширения 8.3.10 будет недостаточно. Все, что нужно нам умеет 8.3.11.
Повторюсь, я считал и считаю 8.3.11, как и 8.3.9 «Мертворожденными» релизами! Почему?
Потому, что:
1) 8.3.9 Фирма 1С официально перепрыгнула. То есть, шли релизы типовых конфигураций под 8.3.8, а затем сразу 8.3.10.
2) БСП 3.0 уже идет под 8.3.12 и планируемые конфигурации на сентябрь, тоже анонсируются с 8.3.12.
Поэтому данную задачу выполняем под 8.3.12 и БСП 3.0, с заделом на будущее.
Устанавливаем Демо БСП 3.0 и переносим в нее свои наработки.
Сразу скажу, я показываю только вариант, он еще будет далек от совершенства, поэтому прошу не ругать.
По-хорошему для универсального решения (не только для регламентов) нужно создавать справочник Команды с реквизитами и типами, соответствующими таблицы Команды справочника ДополнительныеОтчетыИОбработки.
Но, мы делаем решение по регламентам. Создадим справочник БПСПро_Регламенты.
-"КлючРЗ" с типом "Строка(256)"
-"Идентификатор" с типом "Строка(100)"
-"Активно" с типом "Булево"
Сделаем КлючРЗ - РежимВыбораИзСписка и создадим процедуру с заполнение списка. Я буду считать, что все обработки нужные нам начинаются с «БСППро»
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Запрос = Новый Запрос("ВЫБРАТЬ
| ДополнительныеОтчетыИОбработки.ИмяОбъекта КАК КлючРЗ
|ИЗ
| Справочник.ДополнительныеОтчетыИОбработки КАК ДополнительныеОтчетыИОбработки
|ГДЕ
| НЕ ДополнительныеОтчетыИОбработки.ПометкаУдаления
| И ДополнительныеОтчетыИОбработки.ИмяОбъекта ПОДОБНО ""БСППро%""");
Элементы.КлючРЗ.СписокВыбора.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("КлючРЗ"));
КонецПроцедуры
Создадим подсистему БПСПро_БСП и поправим модуль БПСПро_ОбщийМодуль (Процедура ЗаполнитьКоманды)
Процедура ЗаполнитьКоманды(ПараметрыРегистрации,КлючРЗ) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| БПСПро_Регламенты.Наименование КАК Наименование,
| БПСПро_Регламенты.Идентификатор КАК Идентификатор
|ИЗ
| Справочник.БПСПро_Регламенты КАК БПСПро_Регламенты
|ГДЕ
| НЕ БПСПро_Регламенты.ПометкаУдаления
| И БПСПро_Регламенты.КлючРЗ = &КлючРЗ
| И БПСПро_Регламенты.Активно";
Запрос.УстановитьПараметр("КлючРЗ", КлючРЗ);
РезультатЗапроса = Запрос.Выполнить();
//Заполняем команды из справочника регламентов
Если не РезультатЗапроса.Пустой() Тогда
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru = '"+ВыборкаДетальныеЗаписи.Наименование+"'");
НоваяКоманда.Идентификатор = ВыборкаДетальныеЗаписи.Идентификатор;
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
В модуле обработки изменяем функцию СведенияОВнешнейОбработке, меняем одну строчку.
Было: БПСПро_ОбщийМодуль.ЗаполнитьКоманды(ПараметрыРегистрации);
Стало: БПСПро_ОбщийМодуль.ЗаполнитьКоманды(ПараметрыРегистрации,ЭтотОбъект.Метаданные().Имя);
Обновляем и проверяем.
Возможность добавления регламентных заданий без входа в конфигуратор сделана, теперь сделаем возможность добавления кода.
По-хорошему, нужен справочник с Командами и параметрами, но я не ставлю целью сделать продукт для продажи. Моя цель показать сам принцип. Поэтому создаем справочник «БПСПро_КодВыполненияРегламенов»
-"Идентификатор" с типом "Строка(100)"
-"ТекстКоманды" с типом "Строка(неограниченной длинны)"
-"Параметры" таблица значений
-"Имя" с типом "Строка(50)" (но лучше создать справочник параметров и использовать ссылку)
-"ЗначениеПоУмолчанию" составной тип "Строка, ПеречислениеСсылка.ЦветаЗаметок"(для нашего примера)
Правим справочник «БПСПро_Регламенты», добавляем реквизит КодВыполнения с типом "СправочникСсылка.БПСПро_КодВыполненияРегламенов" и табличную часть Параметры.
При изменении «Код выполнения» выполняем следующий код:
&НаКлиенте
Процедура КодВыполненияПриИзменении(Элемент)
КодВыполненияПриИзмененииНаСервере();
КонецПроцедуры
&НаСервере
Процедура КодВыполненияПриИзмененииНаСервере()
//Чистим если надо
Если Объект.Параметры.Количество() > 0 Тогда
Объект.Параметры.Очистить();
КонецЕсли;
Если ЗначениеЗаполнено(Объект.КодВыполнения) Тогда
//Заполняем значениями по умолчанию
Для Каждого строкаПараметры из Объект.КодВыполнения.Параметры Цикл
новыйПараметр = Объект.Параметры.Добавить();
новыйПараметр.Имя = строкаПараметры.Имя;
новыйПараметр.Значение = строкаПараметры.ЗначениеПоУмолчанию;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
В модуль БПСПро_ОбщийМодуль добавляем процедуру ВыполнитьКомандуРЗ
Процедура ВыполнитьКомандуРЗ(ПараметрыВыполнения) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| БПСПро_Регламенты.Ссылка КАК Ссылка,
| БПСПро_Регламенты.КодВыполнения КАК КодВыполнения
|ИЗ
| Справочник.БПСПро_Регламенты КАК БПСПро_Регламенты
|ГДЕ
| НЕ БПСПро_Регламенты.ПометкаУдаления
| И БПСПро_Регламенты.КлючРЗ = &КлючРЗ
| И БПСПро_Регламенты.Активно
| И БПСПро_Регламенты.Идентификатор = &Идентификатор";
Запрос.УстановитьПараметр("КлючРЗ", ПараметрыВыполнения.КлючРЗ);
Запрос.УстановитьПараметр("Идентификатор", ПараметрыВыполнения.Идентификатор);
РезультатЗапроса = Запрос.Выполнить();
//Заполняем параметры и выполняем команду
Если не РезультатЗапроса.Пустой() Тогда
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
//Параметры заполнения
ПараметрыРЗ = Новый Структура;
Для Каждого СтрокаПараметровПоУмолчанию из ВыборкаДетальныеЗаписи.КодВыполнения.Параметры Цикл
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Имя", СтрокаПараметровПоУмолчанию.Имя);
НайденныеСтроки = ВыборкаДетальныеЗаписи.Ссылка.Параметры.НайтиСтроки(ПараметрыОтбора);
Если НайденныеСтроки.Количество() = 0 Тогда
ПараметрыРЗ.Вставить(СтрокаПараметровПоУмолчанию.Имя, СтрокаПараметровПоУмолчанию.ЗначениеПоУмолчанию);
Иначе
ПараметрыРЗ.Вставить(СтрокаПараметровПоУмолчанию.Имя, НайденныеСтроки[0].Значение);
КонецЕсли;
КонецЦикла;
ПараметрыВыполнения.Вставить("ПараметрыРЗ",ПараметрыРЗ);
//Выполняем команду по регламенту
Попытка
Выполнить(ВыборкаДетальныеЗаписи.КодВыполнения.ТекстКоманды);
Исключение
//СообщениеОбОшибке = ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В модуле обработки правим ВыполнитьКоманду. По идее можно оставить только ВыполнитьКоманду и СведенияОВнешнейОбработке остальное можно удалить.
Из формы обработки убираем все лишнее:
Теперь нам нужно сохранить все изменения и в клиентской части заполнить текст команды, параметры, обновить обработку и назначить время для РЗ.
Создаем новый элемент справочника «Код выполнения регламентов (БСППро)»
Текст команды забираем тот, что был написан в 3 задании предыдущей статьи (Процедура СоздатьНовыйЭлементСправочникаЗаметки)
//Создаем новый элемент справочника
ТекущийОбъект = Справочники.Заметки.СоздатьЭлемент();
ДатаТекСеанса = ТекущаяДатаСеанса();
//Формируем текст для Содержания
ФорматированныйТекст = Новый ФорматированныйДокумент;
//Обрабатываем Параметры
перТекстСодержания = "Заметка создана ";
перПометка = Перечисления.ЦветаЗаметок.Красный;
Если ПараметрыВыполнения.Свойство("ПараметрыРЗ") Тогда
Если ТипЗнч(ПараметрыВыполнения.ПараметрыРЗ) = Тип("Структура") Тогда
Если ПараметрыВыполнения.ПараметрыРЗ.Свойство("ТекстСодержания") Тогда
Если ЗначениеЗаполнено(ПараметрыВыполнения.ПараметрыРЗ.ТекстСодержания) Тогда
перТекстСодержания = ПараметрыВыполнения.ПараметрыРЗ.ТекстСодержания;
КонецЕсли;
КонецЕсли;
Если ПараметрыВыполнения.ПараметрыРЗ.Свойство("Пометка") Тогда
Если ЗначениеЗаполнено(ПараметрыВыполнения.ПараметрыРЗ.Пометка) Тогда
перПометка = ПараметрыВыполнения.ПараметрыРЗ.Пометка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Добавили проверку регламент\форма
ФорматированныйТекст.Добавить(перТекстСодержания + ?(ПараметрыВыполнения.ВидЗапускаРегламент,"регламентом","вручную") + " в "+Строка(ДатаТекСеанса), Тип("ТекстФорматированногоДокумента"));
ТекущийОбъект.Содержание = Новый ХранилищеЗначения(ФорматированныйТекст, Новый СжатиеДанных(9));
ТекстHTML = "";
Вложения = Новый Структура;
ФорматированныйТекст.ПолучитьHTML(ТекстHTML, Вложения);
ТекущийОбъект.ТекстСодержания = СтроковыеФункцииКлиентСервер.ИзвлечьТекстИзHTML(ТекстHTML);
ТекущийОбъект.ДатаИзменения = ДатаТекСеанса;
ТекущийОбъект.Автор = ПараметрыСеанса.ТекущийПользователь;
ТекущийОбъект.Пометка = перПометка;
ТекущийОбъект.ДляРабочегоСтола = Истина;
ТекущийОбъект.Записать();
Добавляем параметры:
Теперь отредактируем ранее созданные регламенты. Выберем в них данную команду и заполним параметры.
Записываем и заменяем предыдущую дополнительную обработку на эту.
Проверяем ручной запуск и регламеты:
Вторая задача выполнена!
Хочу еще упомянуть решение Петра Малыгина
В данный момент у него есть практически готовое решение по автоматизации в части Выполнения кода. С его решением можно сделать универсальный (или почти универсальный) регламент.
Кому интересно, можно ознакомиться с видео его решения:
Ссылка на статью Петра Малыгина
В первой части мы рассмотрели, как сделать сложные регламенты без доработки конфигурации, но, как вы понимаете, есть свои неудобства с обновлением регламентов.
Во второй части мы сделали решение, позволяющее в будущем создавать регламенты без доработки конфигурации и без изменений в конфигураторе.
Старался расписаться максимально доступно и примеры выбрал не «Hello, world!».
Надеюсь, статьи будут вам полезны (не забывайте нажимать на звездочку), удачи в работе!