Введение
Всех приветствую. Целью данной новой публикации будет разбор функционала подсистемы "Контроль ведения учета" в рамках библиотеки стандартных подсистем (БСП).
Как всегда, в статье разберем базовый практический пример контроля учета - создание собственного правила проверки и его выполнения. Данный материал будет полезен для программистов, администраторов, а так же любых пользователей, желающих расширить знания о возможностях типовых конфигураций.
Разработку примеров буду осуществлять на платформе 1С:Предприятия 8.3.20.1674 и типовой конфигурации - Библиотека стандартных подсистем 3.1.7.82 (последняя на момент написания статьи - середина июля 2022 г).
Создание собственного правила контроля в справочнике "Правила ведения учета"
Первым шагом, доработаем типовой системный справочник конфигурации - "Правила проверки учета". Выглядит он вот так:
Рис.1 Системный справочник "Правила проверки учета". Интерактивное создание элементов в справочнике запрещено.
Отмечу, что через интерфейс предприятия новые объекты - "проверки" не добавляются - интерактивное создание запрещено. Все проверки, "зашиты" в конфигурации.
Поэтому, я создам программно запись о новой проверке. Но, предварительно, я добавлю в справочник реквизит ОбработчикПроверки. Этот реквизит требуется мне в дальнейшем для определения модуля и процедуры выполнения проверки. В типовом БСП, поскольку все "залочено" в коде.
Воспользуюсь типовым функционалом БСП с некоторыми доработками. Напишу процедуру создания собственного элемента проверки. Выглядит это вот так:
&НаСервере
Процедура СоздадимПроверкуЗаполненияРеквизитаДокумента()
// Формируем шаблоны группыПроверки и ПравилаПроверки
ГруппыПроверок = КонтрольВеденияУчетаСлужебныйПовтИсп.НоваяТаблицаГруппПроверок();
ПравилаПроверки = КонтрольВеденияУчетаСлужебныйПовтИсп.НоваяТаблицаПроверок();
// Заполняем шаблоны
ГруппаПроверки = ГруппыПроверок.Добавить();
ГруппаПроверки.Наименование = НСтр("ru='Демонстрационные проверки документов'");
ГруппаПроверки.Идентификатор = "ДемонстрационныеПроверкиДокументов";
ГруппаПроверки.КонтекстПроверокВеденияУчета = "ДемонстрационныеПроверкиДокументов";
// Создаем типовую проверку
// Заполнение реквизитов объекта
Проверка = ПравилаПроверки.Добавить();
Проверка.ИдентификаторГруппы = "ДемонстрационныеПроверкиДокументов";
Проверка.Наименование = НСтр("ru='Проверка заполнения реквизитов в документе'");
Проверка.Причины = НСтр("ru='Не заполнены определенные реквизиты'");
Проверка.Рекомендация = НСтр("ru='Заполнить все необходимы реквизиты'");
Проверка.Идентификатор = "ПроверитьЗаполнениеРеквизитовВТестовомДокументе";
Проверка.ОбработчикПроверки = "ОбщийМодуль1.ПроверитьОпределенныеРеквизиты";
Проверка.ДатаНачалаПроверки = Дата('20220101000000');
Проверка.ЛимитПроблем = 3;
// Создаем собственную проверку.
//КонтрольВеденияУчетаПереопределяемый.ПриОпределенииПроверок(ГруппыПроверок, ПравилоПроверки);
// Создадим собсвенные проверки во так:
ПриОпределенииПроверок(ГруппыПроверок, ПравилаПроверки);
КонецПроцедуры
Здесь, я использую типовые бсп-шные функции подсистемы Контроль Учета - НоваяТаблицаГруппПроверок() и НоваяТаблицаПроверок(). Эти функции определяют ТаблицыЗначений с необходимыми колонками. Выглядят они вот так:
Функция НоваяТаблицаГруппПроверок() Экспорт
ГруппыПроверок = Новый ТаблицаЗначений;
КолонкиГруппыПроверок = ГруппыПроверок.Колонки;
КолонкиГруппыПроверок.Добавить("Наименование", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиГруппыПроверок.Добавить("Идентификатор", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиГруппыПроверок.Добавить("ИдентификаторГруппы", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиГруппыПроверок.Добавить("КонтекстПроверокВеденияУчета", Метаданные.ОпределяемыеТипы.КонтекстПроверокВеденияУчета.Тип);
КолонкиГруппыПроверок.Добавить("Комментарий", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
Возврат ГруппыПроверок;
КонецФункции
Функция НоваяТаблицаПроверок() Экспорт
Проверки = Новый ТаблицаЗначений;
КолонкиПроверок = Проверки.Колонки;
КолонкиПроверок.Добавить("ИдентификаторГруппы", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиПроверок.Добавить("Наименование", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиПроверок.Добавить("Причины", Новый ОписаниеТипов("Строка"));
КолонкиПроверок.Добавить("Рекомендация", Новый ОписаниеТипов("Строка"));
КолонкиПроверок.Добавить("Идентификатор", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиПроверок.Добавить("ДатаНачалаПроверки", Новый ОписаниеТипов("Дата", , , , , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)));
КолонкиПроверок.Добавить("ЛимитПроблем", Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(8, 0, ДопустимыйЗнак.Неотрицательный)));
КолонкиПроверок.Добавить("ОбработчикПроверки", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиПроверок.Добавить("ОбработчикПереходаКИсправлению", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиПроверок.Добавить("БезОбработчикаПроверки", Новый ОписаниеТипов("Булево"));
КолонкиПроверок.Добавить("ЗапрещеноИзменениеВажности", Новый ОписаниеТипов("Булево"));
КолонкиПроверок.Добавить("КонтекстПроверокВеденияУчета", Метаданные.ОпределяемыеТипы.КонтекстПроверокВеденияУчета.Тип);
КолонкиПроверок.Добавить("УточнениеКонтекстаПроверокВеденияУчета", Метаданные.ОпределяемыеТипы.УточнениеКонтекстаПроверокВеденияУчета.Тип);
КолонкиПроверок.Добавить("ДополнительныеПараметры", Новый ОписаниеТипов("ХранилищеЗначения"));
КолонкиПроверок.Добавить("ИдентификаторРодителя", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиПроверок.Добавить("Комментарий", Новый ОписаниеТипов("Строка", , , , Новый КвалификаторыСтроки(256)));
КолонкиПроверок.Добавить("Отключена", Новый ОписаниеТипов("Булево"));
КолонкиПроверок.Добавить("ПоддерживаетВыборочнуюПроверку", Новый ОписаниеТипов("Булево"));
Проверки.Индексы.Добавить("Идентификатор");
Возврат Проверки;
КонецФункции
Далее, я определяю собственную процедуру ПриОпределенииПроверок. В качестве параметров - беру готовые таблицы значений:
&НаСервере
Процедура ПриОпределенииПроверок(ГруппыПроверок, ПравилаПроверки)
// здесь доработаем немного процедуры создания, сделав их экспортными
КонтрольВеденияУчетаСлужебный.ДобавитьГруппыПроверок(ГруппыПроверок);
КонтрольВеденияУчетаСлужебный.ДобавитьПроверки(ПравилаПроверки);
КонецПроцедуры
Мне так же пришлось доработать процедуры записи новых проверок - ДобавитьГруппыПроверок и ДобавитьПроверки, сделав их экспортными в модуле КонтрольВеденияУчетаСлужебный. Так же, я немного подправил их по-мелочи.
После запуска своей процедуры, я получаю запись в справочнике "Правила проверки учета". Выглядит она вот так:
Рис.2. Мое новое правило, которое создано программно.
По-умолчанию, правило создается "по общему расписанию", но кто хочет определить собственное - может загрузить структуру такого типа (см.рис.3) в реквизит - хранилище - РасписаниеВыполненияПроверки. Структура выглядит вот так:
Рис.3 Структура - расписание для добавления в реквизит-хранилище "РасписаниеВыполненияПроверки".
На закладке "Дополнительно" - вот такая картина:
Рис.3. Здесь установлена собственная процедура проверки в собственном модуле.
Так, мы создали собственное правило проверки. Теперь, напишем шаблон процедуры выполнения - ОбщийМодуль1.ПроверитьОпределенныеРеквизиты.
Процедура ПроверитьОпределенныеРеквизиты(Проверка, ПараметрыПроверки) Экспорт
//Здесь расположить код выполнения проверки;
//ПараметрыПроверки - структура, из которой можно достать необходимые параметры для работы.
КонецПроцедуры
Далее, я немного доработаю код БСП в процедуре КонтрольВеденияУчетаСлужебный.ВыполнитьПроверку. Это делаю для того, что поиск правил правил проверок происходит только по "залоченному списку" в конфигурации.
Доработанная процедура выглядит вот так:
Процедура ВыполнитьПроверку(Проверка, ПараметрыВыполненияПроверки = Неопределено, ПроверяемыеОбъекты = Неопределено) Экспорт
Если ТипЗнч(Проверка) = Тип("Строка") Тогда
ВыполняемаяПроверка = КонтрольВеденияУчета.ПроверкаПоИдентификатору(Проверка);
Иначе
ВыполняемаяПроверка = Проверка;
КонецЕсли;
Если Не ОбновлениеИнформационнойБазы.ОбъектОбработан(ВыполняемаяПроверка).Обработан Тогда
Возврат;
КонецЕсли;
ЗаданыПараметрыВыполненияПроверки = ПараметрыВыполненияПроверки <> Неопределено;
ПараметрыПроверки = ПодготовитьПараметрыПроверки(ВыполняемаяПроверка, ПараметрыВыполненияПроверки);
Если ПроверкаУжеВыполняется(ПараметрыПроверки.ИдентификаторРегламентногоЗадания) Тогда
Возврат;
КонецЕсли;
Если ЗначениеЗаполнено(ПроверяемыеОбъекты) И Не ПараметрыПроверки.ПоддерживаетВыборочнуюПроверку Тогда
Возврат;
КонецЕсли;
ПроверкиВеденияУчета = КонтрольВеденияУчетаСлужебныйПовтИсп.ПроверкиВеденияУчета();
Проверки = ПроверкиВеденияУчета.Проверки;
//СтрокаПроверки = Проверки.Найти(ПараметрыПроверки.Идентификатор, "Идентификатор");
СтрокаПроверки = Справочники.ПравилаПроверкиУчета.НайтиПоРеквизиту("Идентификатор", ПараметрыПроверки.Идентификатор);
Если СтрокаПроверки = Неопределено Тогда
Возврат;
КонецЕсли;
//Если СтрокаПроверки.БезОбработчикаПроверки Тогда
// Возврат;
//КонецЕсли;
ПараметрыПроверки.Вставить("ПроверяемыеОбъекты", ПроверяемыеОбъекты);
РезультатПоследнейПроверки = Неопределено;
Если ЗначениеЗаполнено(ПроверяемыеОбъекты) Тогда
РезультатПоследнейПроверки = РезультатПоследнейПроверкиОбъекта(ПараметрыПроверки);
ИначеЕсли Не ЗаданыПараметрыВыполненияПроверки Тогда
ОчиститьРезультатыПередВыполнениемПроверки(ВыполняемаяПроверка);
КонецЕсли;
МодульОценкаПроизводительности = Неопределено;
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности") Тогда
МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
ОписаниеЗамера = МодульОценкаПроизводительности.НачатьЗамерДлительнойОперации(ПараметрыПроверки.Идентификатор);
КонецЕсли;
УстановитьСостояниеПроверкиВеденияУчета(ВыполняемаяПроверка);
ПараметрыСеанса.СчетчикПроблемВеденияУчета = 0;
ПараметрыОбработчика = Новый Массив;
ПараметрыОбработчика.Добавить(ВыполняемаяПроверка);
ПараметрыОбработчика.Добавить(ПараметрыПроверки);
ОбщегоНазначения.ВыполнитьМетодКонфигурации(СтрокаПроверки.ОбработчикПроверки, ПараметрыОбработчика);
Если ПараметрыСеанса.СчетчикПроблемВеденияУчета > 0
И ПараметрыПроверки.ВажностьПроблемы = Перечисления.ВажностьПроблемыУчета.Ошибка Тогда
Комментарий = НСтр("ru = 'При выполнении проверки ""%1"" обнаружены ошибки (%2)'");
Комментарий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Комментарий,
ПараметрыПроверки.Наименование, ПараметрыСеанса.СчетчикПроблемВеденияУчета);
ЗаписьЖурналаРегистрации(НСтр("ru = 'Контроль ведения учета'", ОбщегоНазначения.КодОсновногоЯзыка()),
УровеньЖурналаРегистрации.Ошибка,
,
,
Комментарий);
ПараметрыСеанса.СчетчикПроблемВеденияУчета = 0;
КонецЕсли;
Если РезультатПоследнейПроверки <> Неопределено Тогда
УдалитьРезультатыПредыдущейПроверки(РезультатПоследнейПроверки);
КонецЕсли;
Если МодульОценкаПроизводительности <> Неопределено Тогда
МодульОценкаПроизводительности.ЗакончитьЗамерДлительнойОперации(ОписаниеЗамера, 0);
КонецЕсли;
КонецПроцедуры
Далее, я доработаю процедуру выполнения, добавив код, который запишет результаты проверки в регистр. Выглядит это вот так:
Процедура ПроверитьОпределенныеРеквизиты(Проверка, ПараметрыПроверки) Экспорт
ПроверяемыеОбъекты = Неопределено;
ПараметрыПроверки.Свойство("ПроверяемыеОбъекты", ПроверяемыеОбъекты);
Результат = Новый Структура("ПроблемныйОбъект");
Результат.ПроблемныйОбъект = Документы._ДемоПоступлениеТоваров.НайтиПоНомеру("0000-000005");
Проблема = КонтрольВеденияУчета.ОписаниеПроблемы(Результат.ПроблемныйОбъект, ПараметрыПроверки);
Проблема.УточнениеПроблемы = "Тестовая проблема";
КонтрольВеденияУчета.ЗаписатьПроблему(Проблема, ПараметрыПроверки);
КонецПроцедуры
Затем, я выполняю проверку, нажав кнопку "Выполнить проверку" на элементе справочника.
Рис.4. Выполним проверку.
Смотрю результат выполнения в регистре "Результаты проверки учета". Все отработало.
Рис.5. Результат проверки учета.
Я разобрал базовый функционал работы в подсистеме "Контроль ведения учета" - программно создал собственную проверку, выполнил ее и записал результат. Теперь, перейдем к заключению и выводам.
Заключение и выводы
В данном материале был рассмотрен базовый типовой функционал конфигураций - подсистемы "Контроля ведения учета". Разобран практический пример использования данной подсистемы - создание собственной проверки, ее запуск с привязкой к определенной процедуре. Запись ошибок. Данная публикация дает представление о возможностях подсистемы контроля. Как я всегда пишу - можно брать и использовать.
Надеюсь, что данный материал будет вам интересен и полезен на практике. Развитие возможностей использования описываемое подсистемы "контроля ведения учета" оставляю на вашу фантазию и усмотрение.
Прошу обратить внимание на мои актуальные статьи по использованию возможностей и применению на практике готового функционала библиотеки стандартных подсистем.
Вот некоторые из них:
Печать макета MS Word в любом документе с помощью БСП
Базовые принципы работы с регламентными заданиями подсистем БСП
Оценка производительности с помощью БСП
Если вас интересуют другие мои материалы по системам БСП и разработки (платные и бесплатные), то всегда вы можете связаться со мой через личку этого профиля, а так же мой телеграмм. Комментарии закрыты - кто хочет подискутировать - в личку.