Механизм "быстрых констант"


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

Описание проблемы.

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

Например, такая ситуация:

Торговая конфигурация, элементом номенклатуры заведена «Упаковка», по мере необходимости добавляется в документы реализации. Далее правила меняются, ставится задача включать упаковку во ВСЕ документы реализации, сделать это программно. Нужно в коде программы инициализировать упаковку как, своего рода, константу. Как поступить? 

  1. Добавить ссылку на упаковку в константы.
  2. Завести предопределенный элемент номенклатуры (еще одна упаковка).
  3. Искать по коду, наименованию, реквизиту.

Все это не то. Для случая (1) — а если таких будет много? Плодить константы? Для случая (2) — явное дублирование сущностей, некрасиво. Для случая (3) — ненадежно. Отрезать пользователям возможность редактирования кода/наименования/реквизитов нельзя.

Методика решения.

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

Сопоставление в коде можно производить по коду/наименованию элемента соответствующего ПВХ.

Объекты и процедуры метода.

  1. Создаем ПВХ, в типизацию которого включаем все нужное из конкретной конфигурации. Код в этом ПВХ уникален и является «синонимом» как константы.
  2. Создаем регистр сведений который будет хранить конкретные значения (в том числе множественные) для элементов ПВХ. Делаем его периодическим.
  3. Определяем механизм проверок для изменения кода ПВХ и записей регистра на предмет некорректного изменения. Можно, конечно, этого и не делать, ведь полный доступ будет иметь только разработчик. Он, конечно, знает что делает, но все ошибаются.
  4. Достаточно только одной функции для получения данных в модули:
// Получение значений пользовательских констант
//
// Параметры:
//  Параметры  - Структура - запрос каких значений. Неопределено тогда все последние.
//                 Ключи:
//     НаДату  - ДатаВремя - на срез значения (до дня). Пустая, вообще нет или неопределено это последнее.
//     Имена  - Массив  - строки с именами ПВХ значений. Вообще нет или неопределено тогда все.
//
// Возвращаемое значение:
//   Структура    - Ключ   - ИмяКонстанты.
//     - Значение  - единичное или массив
//
// Пример вызова:
//
// Имена = Новый Массив;
// Имена.Добавить("ПользователиГлавногоОтчета");
// Имена.Добавить("Ответственный_РНК");
// Имена.Добавить("Доставка");
// // Выборочно последние
// Параметры = Новый Структура("Имена", Имена);
// // Выборочно на 30-05-2014
// Параметры = Новый Структура("Имена, НаДату", Имена, Дата('20140530'));
// // Все на 30-05-2014
// Параметры = Новый Структура("НаДату", Дата('20140530'));
// // Все последние
// Параметры = Неопределено; // тоесть можно не передавать
//
Функция БК_ПолучитьЗначенияКонстант(Параметры = Неопределено) Экспорт

Если Параметры = Неопределено Тогда
НаДату   = Неопределено;
Имена   = Неопределено;
ВыбратьВсе  = Истина;
Иначе

Если Параметры.Свойство("НаДату") Тогда
Если ЗначениеЗаполнено(Параметры.НаДату) Тогда
НаДату = Параметры.НаДату;
Иначе
НаДату = Неопределено;
КонецЕсли;
Иначе
НаДату = Неопределено;
КонецЕсли;

Если НЕ Параметры.Свойство("Имена") Тогда
Имена   = Неопределено;
ВыбратьВсе  = Истина;
Иначе
Имена   = Параметры.Имена;
ВыбратьВсе  = Ложь;
КонецЕсли;

КонецЕсли;

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

Запрос.УстановитьПараметр("НаДату",  НаДату);
Запрос.УстановитьПараметр("Имена",   Имена);
Запрос.УстановитьПараметр("ВыбратьВсе", ВыбратьВсе);

СтруктураВозврата = Новый Структура;
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат СтруктураВозврата;
КонецЕсли;

Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл

Если Выборка.ИспользоватьСписком Тогда
ЗначениеВыборки = Выборка.ЗначениеСписка.Получить();
Иначе
ЗначениеВыборки = Выборка.Значение;
КонецЕсли;

СтруктураВозврата.Вставить(Выборка.Код, ЗначениеВыборки);
КонецЦикла;

// Если выбираем все следует проверить заполненость всех имен
// Не найденные заполняем пустым значением типа
Если НЕ ВыбратьВсе Тогда

Если Имена.Количество()>СтруктураВозврата.Количество() Тогда

Для Каждого ИмяКонстанты Из Имена Цикл
Если НЕ СтруктураВозврата.Свойство(ИмяКонстанты) Тогда

СсылкаКонстанта = ПланыВидовХарактеристик.БК_ЗначенияКонстант.НайтиПоКоду(ИмяКонстанты);
ТипКонстанты  = СсылкаКонстанта.ТипЗначения;

Если СсылкаКонстанта.ИспользоватьСписком Тогда
ЗначениеКонстанты = Новый Массив;
Иначе
ЗначениеКонстанты = ПолучитьПустуюСсылкуТипа(ТипКонстанты);
КонецЕсли;

СтруктураВозврата.Вставить(ИмяКонстанты, ЗначениеКонстанты);

КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;

Возврат СтруктураВозврата;

КонецФункции // БК_ПолучитьЗначенияКонстант()

 Описание примера.

В выгрузке ИБ содержится два примера работы с механизмом:

  1. Для отчета «ГлавныйОтчет» при открытии формы выводится список пользователей, которые имеют право на его использование. Это пример константы имеющей списочный тип (массив).
  2. Для документа «РасходнаяНакладная» при записи получаем и записываем значения ответственного, доставку и упаковку.

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

 

1 Comment

  1. zqzq

    Сделал у себя похожее решение достаточно давно, хотел выложить на инфостарт, но всё лень…

    Принципиальные отличия от данного:

    1. 2 разных ПВХ для констант-элементов и констант-массивов. Т.к. работа с ними в коде принципиально разная и при смене «типа» константы в прикладном коде будут ошибки. (Оба вида периодические как и тут).

    2. Значения констант-массивов хранятся в табличной части справочника. Плюсы: есть типизация ТЧ по элементу ПВХ «из коробки», есть контроль ссылочной целостности (хранилище значений — зло). Для простоты для констант-массивов регистр сведений не используется, в том же справочнике и ссылка на ПВХ, и период.

    3. Элементы ПВХ создаются только предопределённые. Никаких поисков по коду/наименованию. Почему — разработка ведётся в тестовых базах, и иначе будет хаос и г0внокод.

    4. Для миграции значений «констант» в рабочую базу, есть выгрузка значений в текстовый документ, далее этот текст вставляется в общий макет конфигурации, далее при запуске рабочей базы незаполненные значения заполняются из этого макета. Естественно, ссылочные значения должны совпадать по ссылкам в рабочей и тестовой базе (элементы ПВХ сопоставляются по имени предопределенного).

    5. Так же как и тут, получения значения через функцию общего модуля.

    Reply

Leave a Comment

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