Предопределенные значения справочников и обновление конфигурации

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

Нередко требования заказчиков вынуждают привязывать алгоритмы конфигурации к каким-то определенным данным. Например, «если подразделение Челябинск, то проверить минимальный тип цен такой-то, а если Пермь, то такой-то». Основные подходы к реализации данного требования таковы:

1) Привязаться к наименованию/коду элемента и надеяться, что никто его никогда не поменяет. Например,

Если Подразделение.Код=»0000001″ Тогда ТипЦенПроверки=Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию(«Минимальная (Челябинск)»)….

Минусы, думаю, очевидны.

2) Создавать предопределенные значения в справочниках, и впоследствии переносить их из релиза в релиз. Если речь идет о базовых справочниках вроде контрагентов или номенклатуры, которые меняются довольно часто, это становится проблемой. Вторая проблема такого подхода: возможно, потребность выделить какой-то элемент как предопределенный появилась только сейчас, а ссылок на этот элемент в базе уже полно. Решение есть, но, например, при использовании РБД оно создаст еще ворох проблем.

3) Создать константы и записывать туда ссылки на эти самые элементы справочников. Уже лучше, но часто бывает так, что таких вот предопределенных значений может быть много, и список констант разрастется в несколько раз. К тому же необходимо создавать отдельную форму редактирования новых констант и вставлять ее в интерфейс. И права доступа в ролях необходимо добавлять на каждую новую константу.

Вариант, который я хочу предложить на рассмотрение.
Создаем справочник «Предопределенные значения». Реквизиты: «Значение», тип — составной: строка (ограниченной длины), число, булево, дата, ЛюбаяСсылка. В этом справочнике создаем в конфигураторе нужные нам предопределенные элементы. В пользовательском режиме заполняем реквизит «Значение» у созданных элементов. В коде используем конструкции типа

Если Подразделение = Справочники.ПредопределенныеЗначения.ПодразделениеЧелябинск.Значение Тогда ТипЦенПроверки = Справочники.ПредопределенныеЗначения.ТипЦенПроверкиЧелябинск.Значение.

Еще одним из плюсов такого подхода является то, что данный справочник можно использовать вообще вместо новых констант (для констант типа ХранилищеЗначения или Строка с бесконечной длиной необходимо добавить в этот справочник отдельные реквизиты). Кроме того, в нем можно указывать ссылки на любые объекты, в том числе и документы, бизнес-процессы и т.д. (экзотический случай, но, например, он встречается в типовой редакции конфигурации «1С:Рарус Альфа-авто 4.1».

У кого какие мысли по этому поводу?

48 Comments

  1. script

    Все логично. Лично я дошел (по развитию 😀 ) пока только до констант. Хотя буквально неделю назад столкнулся с необходимостью хранить пользовательскую настройку для загрузки данных из Клиент-банка прямо в базе.

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

    А по поводу описанной методики — беру на вооружение.

    Reply ↓
  2. skif47

    (1) для твоей задачи вполне подойдут штатные справочники СохраненныеНастройки, ХранилищеДополнительнойИнформации, или регистр сведений СохраненныеНастройки, в зависимости от конфигурации и релиза ))

    Reply ↓
  3. KonstB

    (2) skif47, Поддерживаю, т.к. при этом нет необходимости править конфу

    Reply ↓
  4. Uncore

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

    Создаем измерение — «Подразделение», ведущее, чтобы можно было из подразделения по кнопки «Перейти» попасть в этот регистр, ну и удалять записи, если само подразделение будет удалено.

    В ресурсе указываем тип цен для выбранного подразделения.

    В последствии организуем где-нибудь в общем модуле функцию по получению типа цен по переданному в нее подразделению.

    Одним из плюсов данного способа является то, что пользователь сам может добавить любое соответствие «Подразделение — ТипЦен», в отличие от предопределенных значений, которые заводятся в конфигураторе.

    Reply ↓
  5. skif47

    (4) Uncore, согласен, вариант с ведущим измерением РС особенно удобен в тех случаях, когда надо добавить дополнительные реквизиты к какому-либо объекту, а механизм свойств/категорий не подходит. Но если к определенным значениям привязаны алгоритмы, то эти значения надо определять жестко. Ну и с точки зрения использования в коде предопределенные значения все же удобнее, я считаю.

    Reply ↓
  6. Uncore

    (5) skif47, да, в плане универсальности способ с предопределенными значениями выигрывает. По объему кода и простоте его написания тоже. Но тут все зависит от поставленной задачи, что в итоге требуется — универсальность или удобство пользователей в плане «не беспокойства» программиста 🙂

    За идею ставлю плюс.

    Reply ↓
  7. skif47

    (6) Uncore, согласен, это вечный поиск баланса между удобством работы пользователей и удобством работы программиста ))

    Reply ↓
  8. sstar90

    Автору «плюс» за то, что оформил в статью, а себе «минус» за лень и недальновидность, т.к.

    3 года «предопределенные значения» я использовал в 7.7 (справочник) и уже 4-й год использую

    в 8-ке (регистр сведений)

    Reply ↓
  9. pumbaE

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

    Reply ↓
  10. NovSL

    Лично я использую Хранилище дополнительнойИнформации. Года 3 назад была подобная проблема в удаленном филиале при выписке накладных.И приходилось через справочник подразделений определять место выписки документов и менять ФИО кладовщиков и отв. лиц. Сейчас это все в Хранилище и нет вопросов

    Reply ↓
  11. Lyns_owner

    Полностью согласен с (4), сам хотел написать такой комментарий. Автор изобретатель велосипедов, за это минус)

    Reply ↓
  12. tango

    а что за проблемы с обновлением справочников с предопределенными элементами?

    Reply ↓
  13. skif47

    Еще один вариант предложили на партнерском форуме:

    Создать регистр сведений в котором Измерение будет строка (по сути название константы) и ресурс — любая ссылка (по сути — значение константы)

    Напишите функцию для доступа к такой псевдоконстанте и конструкция не будет громозкой.

    Это позволит и легко поменять механизм хранения не затрагивая прикладной код.

    Тоже вполне жизнеспособно.

    Reply ↓
  14. skif47

    (12) tango, не столько проблема, сколько неудобно: для объектов-справочников приходится выставлять режим объединения с приоритетом одной из конфигураций, если была изменена еще форма этого объекта, то для нее выставлять другой режим — вручную. Ну и мельтешение кучи объектов при сравнении/объединение радости не добавляет.

    Reply ↓
  15. skif47

    (9) pumbaE, тоже хорошая идея!

    Reply ↓
  16. skif47

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

    Например, новые виды расчета в ЗУП, которые по каким-то причинам невозможно описать штатными средствами. Или новые счета в бухгалтерии.

    За комментарий спасибо )

    Reply ↓
  17. vladismi

    (2) skif47, ХранилищеДополнительнойИнформации не лучший способ решения проблемы и вот почему:

    Реквизит ВидДанных — ссылка на перечисление — нужно дорабатывать перечисление, добавлять значение Справочник.

    Реквизит Объект — составной тип данных — но не исчерпывающий список, нужно дорабатывать…

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

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

    А вот справочник, состоящий из одних предопределенных элементов, которого нет в типовых, но в реквизиты которого можно положить значение ЛЮБОГО типа, — просто чудненько.

    Несомненно — плюс!

    Reply ↓
  18. Gandalf Белый

    Большое спасибо!интересно было посмотреть на данную проблему с такой стороны. ))

    Reply ↓
  19. amiralnar

    Что мне нравится в предопределенных, и в чем я вижу их смысл — это именованное обращение.

    Для справедливаости, можно заметить, что в 8.2 при обновлении можно безболезненно объединять списки предопределенных знаений. Тоесть обновление перестает быть проблемой.

    Что касается ссылок в базе, то я, для быстрой разработки, применяю такой метод:

    Значение = Справочники.Контрагенты.ПолучитьСсылку(Новый УникальныйИдентификатор(«10c6e765-deec-11de-b685-505054503030»)) //Мой любимый контраент

    Где идентификатор выявляется с помощью табло вот такой командой:

    Справочники.Контрагенты.НайтиПоКоду(«000001835»).УникальныйИдентификатор()

    Занимает 2 минуты, элемент жестко свзяан, проблем с изменением реквизитов не будет, РБД тоже правильно сработает.

    Reply ↓
  20. pumbaE

    (19) amiralnar, РБД может неправильно сработать, если по правилам.

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

    Reply ↓
  21. nolodin

    Когда мне надо добавить предопределенные значения я их спокойно добавляю, только к коду предопределенного элемента добавляю буквенный префикс, и устанавливаю нумерацию с 1. Т.е. коды для моих элементов будут «Р00000001», «Р00000002». И все: при обновлении точно ничего не потеряется и сразу видно какие идут от поставщика конфигурации, а какие я добавил.

    Reply ↓
  22. echo77

    Я в коде частенько указываю ссылку на такой «предопределенный» элемент и после этого уже все равно, сменится ли у элемента код или наименование… главное чтобы смысловая нагрузка на элемент не поменялась

    Reply ↓
  23. KulSer

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

    Reply ↓
  24. skif47

    Коллеги, всем большое спасибо за высказанные мнения, особенно за другие варианты, все пойдет в копилку опыта ))

    Reply ↓
  25. V.Nikonov

    Кстати, хранение предопределенного значения в таком виде, это выключение периодичности.

    Расширение списка предопределённых от типовой конфы — большая редкость. Следовательно, можно попыхтеть при обновлении. Надо только не забывать выборочно отказываться от затирания собственных значений.

    Есть ещё одна ветка проблемы с которой я только что столкнулся:

    Есть периодические вариации алгоритмов обработки… т.е. для текущего периода один алгоритм, а для документов прошлого периода — другой. Вроде как напрашивается периодический регистр сведений, хранящий в текстовом виде исполняемый код алгоритма… Но быстродействие получится не Айс!

    Или придётся ограничиться периодическим параметром, который направляет на разные ветки алгоритма?

    Reply ↓
  26. V.Nikonov

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

    При необходимости его не сложно модифицировать: Пополнить список допустимых объектов; Список допустимых типов значений. (для примера, пришлось дополнить допустимые значения созданным справочником «РайоныДоставки», а пока была УТ_10.2 — расширялся набор справочников для объектов свойств)

    Reply ↓
  27. Uncore

    (26) V.Nikonov, если у справочника имеется механизм свойств и категорий — без вопросов, пользуемся по максимуму им. Если нет, то добавление реквизита влечет дописку формы объекта в виде физического помещения элемента на форму, либо программного в модуле формы. Так что для меня все равно предпочтительнее регистр сведений 🙂

    Reply ↓
  28. V.Nikonov

    (27) Uncore, Согласен. Вот только не всегда информация укладывается в «Свойства», даже после модификации механизма свойств. В частности, самые большие проблемы с множественностью значений одного свойства.

    Reply ↓
  29. AlexO

    (4) Uncore,

    Но я чаще пользуюсь в таких случаях регистрами сведений.

    На самом деле, Справочник в 1С — это что-то среднее между Регистром сведений (все основные данные хранятся в одной таблице) и Докмуентом (есть возможность подключать ТЧ и прочие «радости» документа).

    Поэтому и работает Справочник — заметно быстрее поиска по документам, но значительно медленнее спецрегистров.

    Но народ упорно применяет справочники вот в таких случаях хранения изменяемой информации, т.к. справочник — ближе «по понятию», нежели какой-то там «регистр».

    (0) а что такого нового вы открыли?! Дополнительный объект хранения локальной используемой информации, больше никому не нужной, кроме отдельного предприятия?

    А Свойства документов и Справочников смотрели?

    Reply ↓
  30. skif47

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

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

    Reply ↓
  31. AlexO

    (9) pumbaE,

    все сомнительное «достоинство» данного метода — это обращаться «без дураков» к нужному значению (так и хочется вписать — «без дураков из 1С» 🙂 ), но это только если ты привык работать с предопределенными (т.е. конфа на них завязана).

    И большинству вполне в таких случаях — «именного» обращения, — подойдет и будет достаточно списка в новом Перечислении.

    Потом — есть механизм Свойств.

    и вот уже если нужна некая «карточка» на это значение (все не умещается в одном «реквизите») — смотрим на Справочник. Да и то — если значений-описаний у элемента немного (а их немного в 99,9% случаев — 5-7-10) — то только РС и проблема закрыта.

    Reply ↓
  32. AlexO

    (30) skif47,

    поверьте, я хорошо знаком с механизмом свойств и категорий.

    Возможно. Но используете то, что знаете, а не то, что оптимально 🙂

    Для тех задач, которые я описываю в данной заметке

    Какие задачи вы описываете в заметке? Я вот в ( 31) кратко и конкретно описал задачи, а у вас — только «вода» и прописная истина в заметке 🙂

    И то сугубо индивидуальная и узкоспециализированная.

    мне наиболее удобным в некоторых случаях

    Вот и опишите сначала ЭТИ случаи. Чтоб было понятно, ЧТО это за случаи.

    Применять его или нет — решать вам.

    Ну да. А вам — писать статьи, чтобы неокрепшие новички ставили плюсы за «новаторскую идею» :)))

    Reply ↓
  33. pumbaE

    (31) AlexO, я бы сказал что в 90%, в остальных дай только волю по любому случаю добавлять справочник или РС и ваша/наша уютная УППешичка превратиться в УТ11шешечку.

    Reply ↓
  34. AlexO

    (33) pumbaE,

    Механизм Свойств позволяет сузить значения задаваемых параметров до списка указанных.

    Собственно, как и Перечисление 🙂

    Reply ↓
  35. Антон Ширяев

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

    Первое что мне пришло в голову это вариант из (19). Но тут теряется читаемость.

    Вариант же предложенный в статье для меня самый оптимальный. Все что мне нужно сделать это перенести добавленные Предопределенные в новый справочник и везде где они использовались исправить Справочники.ТиповойСправочник.ДобавленныйПредопределенный на Справочники.СправочникПредопределенных.ДобавленныйПредопределенный.Значение даже без вникания в суть кода 🙂

    Reply ↓
  36. skif47

    (32) AlexO, а вот мне любопытно стало. Опишите, будьте добры, критерии оптимальности.

    На вопрос о задачах могу ответить: перечитайте заметку.

    Насчет «прописной истины», кстати, не отрицаю. «сугубо индивидуальная и узкоспециализированная» — все верно.

    Да, и меня заинтересовала идея с обращением к конкретным значениям справочников через перечисление. Можете более подробно описать?

    Reply ↓
  37. AlexO

    (35) Антон Ширяев,

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

    Так ты и отталкиваешься «от имеющегося», а не от «а каким бы способом это сделать» — который ставится негластно в статье, и какой «лоббируется» как «вопрос прочитавшего статью новичка«.

    Т.е., как я и писал уже выше — к исходным посылам статьи очень и очень большие вопросы.

    И правильно, если у меня вся конфа будет на Справочниках (Накопления, Сведений, Расчетных), я что — буду использовать регистры (предположим, скорость обработки не имеет значения)? 🙂

    Reply ↓
  38. Антон Ширяев

    Мне вот непонятна суть спора 🙂

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

    В принципе конечно предопределенные объединяются при обновлении без проблем если в обновлении они добавлены, а если они удалены? Тогда что делать? Опять руками?

    Reply ↓
  39. skif47

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

    Reply ↓
  40. AlexO

    (12) tango,


    а что за проблемы с обновлением справочников с предопределенными элементами?

    Проблемы возникают только при РИБ — в распределенных (удаленных) базах нет этих значений, их туда надо специально переносить/вводить.

    При обновлении базы — предопределенные элементы не трогаются, лишб бы код у них не совпадал (иначе обновление задвоит элементы под одним кодом, или будет ошибка обновления).

    Reply ↓
  41. Kosstikk

    Предопределенные элементы иногда доставляют неудобства при обновлениях.

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

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

    Так же хочу заметить что для каких-то метаданных (например ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные в бухгалтерии) использование не предопределенных данных вызовет некоторые затруднения.

    Reply ↓
  42. CratosX

    (44) Kosstikk, я, кстати, к ПВХ не смог обратиться программно к не предопределеноому значению. Подскажете, как обойти это?

    Reply ↓
  43. DrAku1a

    У нас так:

    справочник «ПредопределенныеЗначения», закрытый для редактирования (только с полными правами, т.е. программисты), в справочнике в качестве идентификатора используется поле «Наименование».

    в общем модуле — реализована функция типа ПолучитьПредопределенноеЗначение(Имя).

    Ну и навороты типа:

    + В качестве значения задавать список значений, таблицу значений, структуру, соответствие (для сложных типов реализованы редакторы значений).

    + Кэширование полученных значений в стандартном КЭШе (без изменения механизма кеширования)

    + Использование в функциях типа «ПолучитьДопПравоПользователя», «ПолучитьНастройкуПользователя» — настройки и доп.права создаются в режиме предприятия, ссылки на них помещаются в значения соответствующих «констант» /именованный элемент справочника «ПредопределенныеЗначения»/ — в коде вызывается по имени этой константы.

    Таким образом — не нужно монопольное обновление, а добавляемые доп.права/настройки можно переименовывать.

    Reply ↓
  44. wondermaker

    Мы аналогично сделали, но сам справочник без предопределенных элементов.

    Это позволяет делать «предопределенные» без предопределенных.

    Поиск делаем по наименованию, которое как-бы является идентификатором/»названием переменной».

    Минус, конечно, в том, что в запросах не используешь эти предопределенные, зато не надо монопольно обновляться, можно «динамить».

    Плюс развиваем схему дальше — скоро добавим список значений, потом до таблицы значений дойдем…

    Reply ↓
  45. igo1

    Очень странно, кода я описал метод которым тут воспользовались многие, меня прям захаили!!!

    http://infostart.ru/public/310497/

    Reply ↓
  46. ipoloskov

    Вот это

    Реквизиты: «Значение», тип — составной: строка (ограниченной длины), число, булево, дата, ЛюбаяСсылка.

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

    «Любая ссылка» — тоже плохо. Лучше ограничить типами реально используемых для хранения ссылок.

    Reply ↓
  47. alex-l19041

    (49) ipoloskov,

    «Любая ссылка» — тоже плохо

    поясните причину

    Reply ↓
  48. ipoloskov

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

    ВЫБРАТЬ

    Представление (ПредопределенныеЗначения.Значение) КАК ЗначениеПредставление

    ИЗ Справочник.ПредопределенныеЗначения КАК ПредопределенныеЗначения;

    При типе ПредопределенныеЗначения.Значение «Любая ссылка» это приведет к тяжеловесному или вовсе невыполнимому плану запроса

    Reply ↓

Leave a Comment

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