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

21.08.17

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

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

Файлы

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

Наименование Скачано Купить файл
Конфигурация-пример "Дополнительные параметры процедур и функций"
.cf 11,12Kb
1 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вступайте в нашу телеграмм-группу Инфостарт

См. также

Загрузка и выгрузка в Excel Универсальные функции Программист 1С:Предприятие 8 Россия Бесплатно (free)

Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).

30.10.2025    5304    Abysswalker    11    

47

Универсальные функции Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

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

14.05.2025    9844    DeerCven    15    

64

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

21.05.2024    60708    dimanich70    85    

175

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

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

1 стартмани

18.03.2024    8385    7    John_d    13    

59

Универсальные функции Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

12.02.2024    76097    atdonya    31    

74

Универсальные функции Программист 1С:Предприятие 8 Бесплатно (free)

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

30.11.2023    10507    ke.92@mail.ru    17    

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


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

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


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

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

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

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

Я считаю, что с броским названием тс перегнул, ибо
создать регистр хранения в конфигурации - это банальное решение в лоб не претендующее на рациональную идею и альтернативу. это костыль
20. Goleff74 219 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 1554 27.09.24 15:23 Сейчас в теме
Столкнулся с огромным минусом такого варианта решения:
Если код обернут в транзакцию, то данные в регистр сведений попадут только после завершения транзакции, т.е. после завершения алгоритма, а это уже поздно...
Вариант через систему взаимодействия, но она может быть не установлена...
Поэтому пользователь видит только форму и крутящееся окошко без прогресса.

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