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

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

В типовых конфигурациях на управляемых формах «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 не будет опубликован. Обязательные поля помечены *