Альтернативный способ передачи произвольных параметров между процедурами/сеансами/фоновыми заданиями

21.08.17

Разработка - Универсальные функции

В статье описан возможно не новый, но полезный способ передачи параметров между сеансами/процедурами и функциями/фоновыми заданиями

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Конфигурация-пример "Дополнительные параметры процедур и функций"
.cf 11,12Kb
1
1 Скачать (1 SM) Купить за 1 850 руб.

Когда-то давно передо мной была поставлена задача добавить в документ определенный реквизит и доработать процедуру заполнения табличных частей этого документа с отбором по этому реквизиту.

Казалось бы, задача для опытного (да и не очень опытного) 1С-ника простая, нужно всего лишь добавить реквизит, вывести его на форму, найти процедуру заполнения и доработать её.

Однако, в моем случае процедура заполнения документа вызывалась через типовой механизм "Длительные операции" или по-простому через механизм "Фоновых заданий", т.е. по нажатию на кнопку "Заполнить", программа заполняла структуру параметров и запускала фоновое задание из модуля менеджера документа с этими параметрами. Далее, вызывались нужные процедуры по заполнению таблиц документа. Однако, в эти процедуры передавалась не вся структура параметров (куда я мог поместить и свой в том числе), а лишь некоторые из них. Плюс к этому одним вызовом нужной процедуры дело не ограничивалось, до того, как параметры доходили до нужной процедуры заполнения они преодолевали тернистый путь из последовательного вызова 7-8 типовых процедур.

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

Решено было создать простой регистр сведений, который был назван "ДополнительныеПараметрыПроцедурИФункций":

В результате чего алгоритм решения вышеописанной задачи свелся к следующему:

  1. Перед заполнением установить значение нужного нам параметра, записав его значение в регистр сведений
  2. В процедуре заполнения прочитать значение параметра из регистра 
  3. Непосредственно доработать саму процедуру с учетом нашего параметра

Почему я для данного случая не использовал:

  1. Константы - не подходят для данного случая, так как параметры могут быть различными (у константы должно быть уникальное имя) и не постоянными (зависят, например, от значения реквизита конкретного документа)
  2. Параметры сеанса - данные параметры уникальны только в разрезе конкретного сеанса. Т.е. на примере выше, когда "поднимается" фоновое задание у него уже "свои" значения параметров сеанса

Процедуры чтения/записи значения параметров:

Процедура УстановитьЗначениеДопПараметраПроцедурИФункций(ИмяПараметра, ЗначениеПараметра) Экспорт
	
	НаборЗаписей = РегистрыСведений.ДополнительныеПараметрыПроцедурИФункций.СоздатьНаборЗаписей();
	НаборЗаписей.Отбор.ИмяПараметра.Установить(ИмяПараметра);
	НаборЗаписей.Прочитать();
	НаборЗаписей.Очистить();
	
	НоваяЗапись = НаборЗаписей.Добавить();
	НоваяЗапись.ИмяПараметра = ИмяПараметра;
	НоваяЗапись.ЗначениеПараметра = ЗначениеПараметра;
	
	НаборЗаписей.Записать();
	
КонецПроцедуры

Функция ВернутьЗначениеДопПараметраПроцедурИФункций(ИмяПараметра) Экспорт
	
	ЗначениеПараметра = Неопределено;
	
	НаборЗаписей = РегистрыСведений.ДополнительныеПараметрыПроцедурИФункций.СоздатьНаборЗаписей();
	НаборЗаписей.Отбор.ИмяПараметра.Установить(ИмяПараметра);
	НаборЗаписей.Прочитать();
	
	Для каждого стр из НаборЗаписей Цикл 
		ЗначениеПараметра = стр.ЗначениеПараметра;	
	КонецЦикла;
		
	Возврат ЗначениеПараметра;
	
КонецФункции

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

В приложении к публикации находится простейшая конфигурация, демонстрирующая описанный выше механизм.

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

21.05.2024    20134    dimanich70    81    

144

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    4091    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    18068    atdonya    24    

56

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    5503    ke.92@mail.ru    16    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14735    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3581    56    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18479    171    sapervodichka    112    

135
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Goleff74 217 21.08.17 18:50 Сейчас в теме
Процедура УстановитьЗначениеДопПараметраПроцедурИФункций(ИмяПараметра, ЗначениеПараметра) Экспорт
	
	НаборЗаписей = РегистрыСведений.ДополнительныеПараметрыПроцедурИФункций.СоздатьНаборЗаписей();
	НаборЗаписей.Отбор.ИмяПараметра.Установить(ИмяПараметра);
	
	НоваяЗапись = НаборЗаписей.Добавить();
	НоваяЗапись.ИмяПараметра = ИмяПараметра;
	НоваяЗапись.ЗначениеПараметра = ЗначениеПараметра;
	
	НаборЗаписей.Записать();
	
КонецПроцедуры
Показать


Так, пожалуй, красивее будет :)
4. Skin123 189 22.08.17 09:30 Сейчас в теме
(1). Да, точно красивее:) Спасибо!
2. PerlAmutor 155 22.08.17 09:13 Сейчас в теме
Я подобную задачу решал иначе. В БСП есть справочник ДополнительныеОтчетыИОбработки, в каждой обработке можно хранить любые собственные настройки. Соответственно сначала туда записываются параметры, а потом туда же возвращается результат.
5. Skin123 189 22.08.17 09:36 Сейчас в теме
3. surikateg 22.08.17 09:26 Сейчас в теме
Чем плохо СохранитьЗначение(<Имя>, <Значение>) , ВосстановитьЗначение(<Имя>) ? Нет привязки к постоянно изменяющемуся бсп.
6. KilloN 59 22.08.17 09:50 Сейчас в теме
(3) СохранитьЗначение(<Имя>, <Значение>) , ВосстановитьЗначение(<Имя>) только для толстого клиента.
Лучше использовать ХранилищеОбщихНастроек.Сохранить, Загрузить, Удалить
7. PerlAmutor 155 22.08.17 10:03 Сейчас в теме
(6) Пока не пробовал. В качестве минуса наверное можно выделить то, что эти настройки засоряют базу, т.к. при удалении обработки данные там остаются.
8. KilloN 59 22.08.17 10:11 Сейчас в теме
(7) Да все верно, поэтому нужно вызывать Удалить, или сразу после загрузки, или перед завершением сеанса через функцию ХранилищеОбщихНастроек.ПолучитьСписок(...) очищаем все настройки
12. Skin123 189 22.08.17 12:44 Сейчас в теме
(8), с хранилищем общих настроек хорошая идея, но они же вроде сохраняются для определенного пользователя? В таком случае, как узнать в фоновом задании настройки какого пользователя читать?
22. DarkAn 1093 09.02.18 17:08 Сейчас в теме
(12) Вот тут и тут я как раз этим и пользуюсь :)
9. Altair777 645 22.08.17 12:23 Сейчас в теме
Это однопользовательский вариант? Так имя параметра быстрее всего одинаковое для документов одного вида, то коллизии будут возникать с вероятностью чуть менее, чем полностью :)
klinval; sergathome; +2 Ответить
10. Skin123 189 22.08.17 12:36 Сейчас в теме
(9) Хм, а ведь и правда, в случае, если два пользователя решат одновременно заполнить два разных документа, то коллизия неизбежна. По идее тут нужно еще одно измерение создавать, которое будет отвечать за уникальность значения данного параметра. Подумаю на эту тему, спасибо.
11. Altair777 645 22.08.17 12:38 Сейчас в теме
(10) достаточно ссылки на документ (?)
13. Skin123 189 22.08.17 12:49 Сейчас в теме
(11) В общем случае ссылки на документ будет достаточно, ну или как вариант уникального идентификатора, чтобы не привязываться к типу объекта. Однако, в моем случае в процедуре, в которую нужно было передать дополнительный параметр не было ссылки на заполняемый объект, поэтому тут и могут возникнуть сложности в определении значения параметра
18. Goleff74 217 22.08.17 15:58 Сейчас в теме
(13)
Почему проблемы?
Ключ = Строка(Новый УникальныйИдентификатор)

Параметр по этому ключу в РС. И фоновое задание запускать с этим ключом.
15. KilloN 59 22.08.17 14:35 Сейчас в теме
16. KilloN 59 22.08.17 14:36 Сейчас в теме
(9)
Это однопользовательский вариант? Так имя параметра быстрее всего одинаковое для документов одного вида, то коллизии будут возникать с вероятностью чуть менее, чем полностью :)


Не будут, тк. хранилище работает, если не указывать конкретного пользователя, для каждого пользователяотдельно!
17. Altair777 645 22.08.17 15:28 Сейчас в теме
(16) а разве в публикации говорилось о хранилище?!
Не морочьте людям голову
14. sergathome 4 22.08.17 13:08 Сейчас в теме
В общем случае метод годится только для случая, когда им пользуется только один сеанс. То есть не годится даже для регламентных заданий ;)) ИД сеанса нужно в измерения добавлять, как минимум. И передавать этот ИД в фоновое задание стандартным способом. Выигрыш только в том, что можно одним параметром передать сразу много, но что мешает передать структуру сразу ?
Вобсчем поржал. Спасибо.
19. VmvLer 22.08.17 16:13 Сейчас в теме
Относительно фоновых заданий хранилище имеет только обратную связь, т.е.

при запуске фонового задания в него можно передать адрес хранилища и после завершения фонового задания в точке его
запуска получить значения из хранилища.

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

Именно поэтому возникают задачи как в (0)

Я считаю, что с броским названием тс перегнул, ибо
создать регистр хранения в конфигурации - это банальное решение в лоб не претендующее на рациональную идею и альтернативу. это костыль
20. Goleff74 217 22.08.17 16:39 Сейчас в теме
Ну, можно поизвращаться.

На клиентском компутере:

1. Получаем новый УИД.
2. Блокируем по нему исключительно запись в РС.
3. Запускаем фоновое задание, в которое передаем-таки этот уид (только в функцию самого задания).
4. В бесконечном цикле (можно с паузой) опрашиваем фоновое задание на предмет сообщений пользователю.
5. Как только появляется сообщение в РС фигачим по номеру в этом собщении необходимый параметр и снимаем блокировку с записи РС из п.2.

В функции ФЗ:
1. Получаем номер сеанса.
2. Создаем сообщение пользователю, в которое добавляем этот номер сеанса.
3. Делаем запрос к РС по УИДу преданному в качестве параметра ФЗ.
4. Ждем на блокировке...
5. Выполняем свой код. В функции, где нужен параметр с клиента обращаемся в РС по НомерСеансаИнформационнойБазы().
6. Профит

PS Ну, и не забываем, где надо, транзакции всунуть, чтоб блокировка отработала.
PPS Но лучше, каеш, параметр протолкнуть по функциям :)
21. VmvLer 22.08.17 17:32 Сейчас в теме
чтобы не изобретать велосипед советую использовать БСП

ДлительныеОперации.ЗапуститьВыполнениеВФоне()
23. ybatiaev 59 19.03.18 13:20 Сейчас в теме
Добрый день!
Немного поздновато, но всё же.
У меня архиватор баз, где все необходимые процедуры выполняется в фоне для одного "робота", а другие пользователи просто читаю что-то.
Вот "пухнет" база, я так понял что постоянная перезапись данных идёт.
Сделано через хранилище данных. Весь результат "робот" складывает в хранилище, к нему все подключаются и читают данные, которые отображаются на главной форме любого пользователя (ЗначениеВДанныеФормы()) с определённой для клиента периодичностью. Тут получается что нет никаких справочников, регистров и т.п.

Можно сделать через параметры сеанса, где данные тоже в виде хранилища. Вот данные хранилища будет оценивать "робот" и "распихивать" по таблицам (справочники, регистры). А у других пользователей на форму просто будет выведены стандартные динамические списки.

Кто сталкивался? Как правильнее сделать? Главный вопрос, на который я не нашёл ответа - при перезаписи хранилища каким образом данные заносятся в ТЧ СУБД. К примеру, старое хранилище с ТЧ помечается не актуальным, а новая информация ДОПИСЫВАЕТСЯ. Или в то же физическое пространство перезаписывается информация?
24. Xershi 1555 27.09.24 15:23 Сейчас в теме
Столкнулся с огромным минусом такого варианта решения:
Если код обернут в транзакцию, то данные в регистр сведений попадут только после завершения транзакции, т.е. после завершения алгоритма, а это уже поздно...
Вариант через систему взаимодействия, но она может быть не установлена...
Поэтому пользователь видит только форму и крутящееся окошко без прогресса.

По поводу параметров, гуглил ПараметрыСеанса.
Суть в чем мы нажали кнопку, параметр установился, но запуская фоновое задание параметр не будет установлен.
Выход при создании фонового задания параметр сеанса добавить в параметры задания. И затем в задании прописать код установки параметра сеанса:
//В форме на сервере
ПараметрыВыполненияОбработки = Новый Структура;
// Здесь указываете параметры, передаваемые в процедуру, выполняемую в фоне
ПараметрыВыполненияОбработки.Вставить("Таблица",										ПолучитьТаблицуКоманды(ИмяКоманды));
ПараметрыВыполненияОбработки.Вставить("ИмяКоманды",										ИмяКоманды);
ПараметрыВыполненияОбработки.Вставить("ПроводитьБезКонтроляОстатковТоваровОрганизаций",	ПараметрыСеанса.ПроводитьБезКонтроляОстатковТоваровОрганизаций);
	
//В модуле объекта на сервере
Если ПроводитьБезКонтроляОстатковТоваровОрганизаций Тогда
		
	ПараметрыСеанса.ПроводитьБезКонтроляОстатковТоваровОрганизаций = Истина;
		
КонецЕсли;
Показать
Оставьте свое сообщение