Использование макетов вместо дополнительных реквизитов или регистров сведений

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

В типовых конфигурациях на управляемых формах «1С Бухгалтерия предприятия 8», «1С Зарплата и управление персоналом 8», «1С Управление Торговлей 8» и т.д., которые реализованы с использованием БСП (библиотека стандартных подсистем) – есть  такая замечательная вещь, как регистр сведений «Пользовательские макеты печати». Помимо своего прямого предназначения  — дать пользователю возможность самостоятельно редактировать печатные формы (конечно в разумных пределах), его можно использовать и по другому назначению. А именно  —  хранить в нём некоторую информацию. Бывают ситуации, когда поставленная задача казалось бы не даёт возможности её выполнить, не внеся изменений в типовую конфигурацию. А менять типовую без крайней необходимости – ой, как не хочется. На мой взгляд — с помощью регистра сведений "Пользовательские макеты" — можно решать некоторые задачи. Регистр сведений "ПользовательскиеМакетыПечати" — имеет два измерения: "Объект" и "ИмяМакета", которые имеют тип "Строка" и один ресурс "Макет" с типом "ХранилищеЗначений", где можно хранить что угодно. Почему бы этим не воспользоваться. Ниже примеры из моей практики, где применял.

Пример для «1С Зарплата и управление персоналом 8»:

Необходимо из внешней торговой системы загружать данные о продажах и на основании этих данных рассчитывать премии продавцам. Продавцы имеют процент в зависимости от должности («стажер», «консультант» и т.д) и от места расположения магазина. Никакой линейной зависимости нет: одна и та же должность в разных  магазинах имеет разный процент. В прежней редакции Зарплаты 2.5 был заведен «регистр сведений» в разрезе должность/подразделение со ставкой процента. При переходе на 3.1 – было решено использовать макет. Это позволило оставить конфигурацию полностью типовой. Использовать дополнительные реквизиты не получалось, т.к. тогда пришлось бы прописывать для каждого магазина должности и ставки процентов. Оставался бы открытым вопрос с хранением истории изменения ставок, да и забивать форму кучей дополнительных реквизитов тоже не хотелось.

Пример использования при печати:

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

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

Ниже пример реализации по примеру с записью ставок процентов продаж:

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

С записью всё просто:

&НаКлиенте
Процедура ЗаписатьПользовательскийМакет()

ЗаписатьПользовательскийМакетНаСервере();

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

&НаСервере
Процедура ЗаписатьПользовательскийМакетНаСервере()

ТаблДокумент = Новый ТабличныйДокумент;

ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
Макет = ОбработкаОбъект.ПолучитьМакет("Макет");

ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Для каждого стр из ПроцентыПродаж цикл
ОбластьСтрока.Параметры.КодПодразделения  = стр.Подразделение.Код;
ОбластьСтрока.Параметры.Подразделение     = стр.Подразделение.Наименование;
ОбластьСтрока.Параметры.Должность         = стр.Должность.Наименование;
ОбластьСтрока.Параметры.Процент           = стр.Процент;
ОбластьСтрока.Параметры.ПечДатаСведений   = ДатаСведений;
ТаблДокумент.Вывести(ОбластьСтрока);
КонецЦикла;

ИмяВладельца = "Справочник.Организации";
ИмяМакета    = "Процент_продаж";

Запись = РегистрыСведений.ПользовательскиеМакетыПечати.СоздатьМенеджерЗаписи();
Запись.Объект = ИмяВладельца;
Запись.ИмяМакета = ИмяМакета;
Запись.Использование = Истина;
Запись.Макет = Новый ХранилищеЗначения(ТаблДокумент, Новый СжатиеДанных(9));
Запись.Записать();

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

«ИмяВладельца» и «ИмяМакета» — большой роли не играют. Главное чтобы потом при считывании макета они были такими же.

Считываем макет и выводим на печать:

&НаКлиенте
Процедура ПечатьСписка(Команда)

ТабличныйДок = ПечатьСпискаНаСервере();

//========= эта конструция нужна, чтобы открыть общую форму "Печать документов"
КоллекцияПечатныхФорм.Очистить();
МассивОбъектов=Новый Массив;
МассивОбъектов.Добавить(ТабличныйДок);
Стр=КоллекцияПечатныхФорм.Добавить();
Стр.ИмяМакета="Процент_продаж";
Стр.ИмяВРЕГ="ПРОЦЕНТ_ПРОДАЖ";
Стр.ТабличныйДокумент=ТабличныйДок;
Стр.СинонимМакета="Процент продаж";
Стр.Экземпляров=1;
Стр.ОфисныеДокументы = "";

ПараметрыОткрытия = Новый Структура("ИмяМенеджераПечати,ИменаМакетов,ПараметрКоманды,ПараметрыПечати");
ПараметрыОткрытия.ИмяМенеджераПечати="Справочник.Организации";
ПараметрыОткрытия.ПараметрКоманды = Новый Массив;
ПараметрыОткрытия.ПараметрыПечати = Новый Структура;
ПараметрыОткрытия.Вставить("КоллекцияПечатныхФорм", КоллекцияПечатныхФорм);
ПараметрыОткрытия.Вставить("ОбъектыПечати", МассивОбъектов);
ПараметрыОткрытия.Вставить("ОфисныеДокументы","");
ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия, ЭтаФорма.ВладелецФормы);

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

&НаСервере
Функция ПечатьСпискаНаСервере()

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

Запрос = Новый Запрос(ТекстЗапроса);
Запрос.Параметры.Вставить("Объект", "Справочник.Организации");
Запрос.Параметры.Вставить("ИмяМакета", "Процент_продаж");

Выборка = Запрос.Выполнить().Выгрузить();
Если Выборка.Количество()=1 Тогда
МакетВХранилище = Выборка[0].Макет;
МакетСоставаПоказателей = МакетВХранилище.Получить();
КонецЕсли;

Таб = Новый ТабличныйДокумент;

Если МакетСоставаПоказателей = Неопределено Тогда
СообщитьПользователю("Ставки не загружены в программу!");
Возврат Таб;
КонецЕсли;

//===========заполнение таблицы значений.Для вывода на печать она не нужна, можно сразу заполнять табличный документ
//=========== ТЗ нужна, чтобы прочитанные данные из макета использовать для дальнейших расчетов.
//=========== Например в какой-нибудь обработке по расчету премий - уже на основании полученных ставок из макета.

Табл = Новый ТаблицаЗначений;
Табл.Колонки.Добавить("Подразделение", Новый ОписаниеТипов("СправочникСсылка.ПодразделенияОрганизаций"));
Табл.Колонки.Добавить("Должность", Новый ОписаниеТипов("СправочникСсылка.Должности"));
Табл.Колонки.Добавить("Процент",Новый ОписаниеТипов("Число"));
Табл.Колонки.Добавить("ПечДатаСведений",Новый ОписаниеТипов("Дата"));

Для а = 1 по МакетСоставаПоказателей.ВысотаТаблицы Цикл
КодПодразделения  = МакетСоставаПоказателей.Область(а,1,а,1).Текст;
Подразделение   = МакетСоставаПоказателей.Область(а,2,а,2).Текст;
Должность   = МакетСоставаПоказателей.Область(а,3,а,3).Текст;
Процент     = МакетСоставаПоказателей.Область(а,4,а,4).Текст;
ПечДатаСведений     = МакетСоставаПоказателей.Область(а,5,а,5).Текст;
Если Процент = "" Тогда
Процент = 0;
КонецЕсли;
НовСтрока = Табл.Добавить();
НовСтрока.Подразделение = Справочники.ПодразделенияОрганизаций.НайтиПоКоду(КодПодразделения);
НовСтрока.Должность = Справочники.Должности.НайтиПоНаименованию(СокрЛП(Должность));
НовСтрока.Процент = Число(Процент);
НовСтрока.ПечДатаСведений = Дата(ПечДатаСведений);
КонецЦикла;

//========= вывод на печать
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
Макет = ОбработкаОбъект.ПолучитьМакет("Макет");
Шапка = Макет.ПолучитьОбласть("Шапка");
Таб.Вывести(Шапка);
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Для каждого стр из Табл цикл
ОбластьСтрока.Параметры.КодПодразделения  = стр.Подразделение.Код;
ОбластьСтрока.Параметры.Подразделение     = стр.Подразделение.Наименование;
ОбластьСтрока.Параметры.Должность         = стр.Должность.Наименование;
ОбластьСтрока.Параметры.Процент           = стр.Процент;
ОбластьСтрока.Параметры.ПечДатаСведений   = Формат(стр.ПечДатаСведений,"ДФ=dd.MM.yyyy");
Таб.Вывести(ОбластьСтрока);
КонецЦикла;

Возврат Таб;

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

Для вывода на печать, чтобы использовать общую форму "Печать документов", нужно будет ещё в реквизиты формы добавить Таблицу значений с колонками произвольного типа "ИмяМакета", "ТабличныйДокумент", "ИмяВРЕГ", "СинонимМакета", "Экземпляров", "ПолныйПутьКМакету", "ИмяФайлаПечатнойФормы", "ОфисныеДокументы".

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

Пример с обработкой прилагаю: работает и "1С Зарплатой 8" и с "1СБухгалтерией 8". В "1С Управлении торговлей 8" не сработает по причине отсутствия справочников "Должности" и "Подразделения", но сам принцип рабочий.

Обработка тестировалась на релизах "1С Зарплата 8" 3.1.7.144, 3.1.8.216; "1С Бухгалтерия 8" 3.0.67.54.

22 Comments

  1. konstruktiv

    Ужас какой-то. Для этого теперь есть расширения.

    Reply
  2. olbu

    Я использую для хранения не большего массива данных в УПП 1.3 — справочник «СохраненныеНастройки», у которого так же имеется реквизит «ХранилищеНастроек», в него и помещаю данные. Это в основном таблица значений. Что бы не создавать новый Регистр Сведений.

    Reply
  3. echo77

    (2) интересно, на сколько большие таблицы помещаются в справочник. Вспомнилась необходимость сохранить таблицу на 400К строк, думаю, в моем случае — поместить все в элемент справочника плохая затея.

    Что скажете?

    Reply
  4. Darklight

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

    Reply
  5. Darklight

    (3)400 строк — это ни о чём. Вот 400 тыс строк — это да, можно было бы подумать, но…. всё-равно — для ХранилищаЗначений это не так важно — всё-равно будут храниться в СУБД как MEMO данные в отдельной области. Дальше нужно обращать внимание только как часто получается значение объекта справочника (когда не нужно это значение ХранилищаЗначений) — думаю для таких «системных» справочников доля таких холостых считываний ничтожна — так что вполне можно хранить в справочнике. Но это я про сотни тысяч строк. А сотник строк — можно хранить где угодно (если, конечно, в реквизитах самих строках не хранится что-то гигантское).

    Reply
  6. Comandante

    (1) — Как в приведенном примере, например по расчету премий во внешней обработке получить значения ставок используя расширения? Поделитесь пожалуйста.

    Reply
  7. Comandante

    Идея статьи — показать место, где в типовых конфигурациях можно ещё хранить данные. Упомянутый регистр сведений -неплохое место. К нему есть доступ у пользователей и с ограниченными правами. Есть ресурс с типом «Хранилище значений». Не обязательно там хранить именно макеты — можно ведь и таблицу значений. В статье получилось, что я сконцентрировал внимание именно на работе с макетами — надо бы поправить наверное … Но и в макетах особо плохого, при малом объеме данных, ничего нет. 1С в типовых их активно использует, например при выгрузке той же регламентированной отчетности.

    Reply
  8. the1

    (5) 400К и есть 400.000

    Reply
  9. the1

    (6) Завести непериодический регистр сведений прямо в расширении

    Reply
  10. olbu

    (3)Да, это очень плохая идея…, этот справочник Я использую для хранения не большего массива данных, ну например до 50 строк

    Reply
  11. Darklight

    (8)Ооо, простите букву K не разглядел 😉

    Reply
  12. androidT1C

    А какой смысл сохранять в хранилище значений именно макет, а не сразу готовую таблицу значений?

    Reply
  13. Comandante

    (12) — в конкретном приведенном примере ТЗ. Удобней. Согласен. Макет скорее как вариант.

    Reply
  14. Comandante

    (9) Вот только не отвалился бы этот регистр при обновлении конфигурации или платформы. Сообщения такие были.

    Или возможен вариант с телодвижениями, как описано тут: https://infostart.ru/public/784534/

    Reply
  15. Shmell

    Мне тоже нравиться данный механизм БСП. Я у себя задействовал его для хранения правил интеграции:

    Каждый макет — набор правил для конкретного вида объекта

    Удобно что можно в пользовательском режиме «на лету» менять правила не лазя в конфигуратор. И по-мне, такой подход удобнее чем произвольные тексты в справочниках, здесь все перед глазами.

    Reply
  16. ilialin

    (7) Это плохая идея — вы пытаетесь натянуть сову на кактус…

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

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

    Reply
  17. leemuar

    (4) хранилище настроек — прекрасный инструмент. Но насколько я помню без административных прав даже в привилегированном режиме невозможно получить чужие настройки. Это даже в документации было описано. Что-то поменялось с тех пор в платформе?

    Reply
  18. Darklight

    (17)Да, я напутал, установка привилегированного режима не даёт возможность обращаться не к своим настройкам в хранилище системных настроек без адм. прав

    Reply
  19. 7OH

    А как по таким «данным» отчет построить ?

    Мы же их не ради хранения записываем, а явно где-то должны потом использовать.

    Reply
  20. Comandante

    (19) — Если Вы в регистр положили табличный документ, то уже в готовом виде его и получаете. Достаточно реквизит на форму вывести типа «ТабличныйДокумент». Ниже в примере — «Реквизит1».

    &НаСервере
    Функция Команда1НаСервере()
    
    ТекстЗапроса =
    «ВЫБРАТЬ
    | ПользовательскиеМакетыПечати.Макет КАК Макет,
    | ПользовательскиеМакетыПечати.ИмяМакета КАК ИмяМакета
    |ИЗ
    | РегистрСведений.ПользовательскиеМакетыПечати КАК ПользовательскиеМакетыПечати
    |ГДЕ
    | ПользовательскиеМакетыПечати.Объект = &Объект
    | И ПользовательскиеМакетыПечати.ИмяМакета ПОДОБНО &ИмяМакета
    | И ПользовательскиеМакетыПечати.Использование»;
    
    Запрос = Новый Запрос(ТекстЗапроса);
    Запрос.Параметры.Вставить(«Объект», «Справочник.Организации»);
    Запрос.Параметры.Вставить(«ИмяМакета», «Процент_продаж»);
    
    Выборка = Запрос.Выполнить().Выгрузить();
    Если Выборка.Количество()=1 Тогда
    МакетВХранилище = Выборка[0].Макет;
    МакетСоставаПоказателей = МакетВХранилище.Получить();
    КонецЕсли;
    
    Возврат МакетСоставаПоказателей;
    
    
    
    КонецФункции
    
    &НаКлиенте
    Процедура Команда1(Команда)
    Реквизит1 = Команда1НаСервере();
    КонецПроцедуры
    

    Показать

    Или как я в статье писал (и обработка в примере) — там вывод на Общую форму «Печать документов» — для красоты.

    Reply
  21. Comandante

    Напишите ваше сообщение

    (16) — Не вижу, где бы я получил кучу проблем в перспективе. Ну правда. В регистр, который 1С разработали под хранение макетов — я положил макет. Какие тут могут быть проблемы?

    Reply
  22. EVKash

    (21) Выпустят к примеру БСП 4, где полностью пересмотрят данный механизм — и что тогда?

    Правильно, ВСЁ придется переделывать/переписывать.

    Вон прогеры 1С тоже не думали, что НДС будет меняться…

    Reply

Leave a Comment

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