Зейлек Энес | Руководитель проектов 1С | Otto Group

«Как продать разработку мобильного приложения существующим клиентам»

Данный доклад будет посвящен тому, какие болевые точки можно найти в розничных сетях, причем на примере крупных сетевых компаний, которые имеют магазины в разных странах. Тезисы: - Решение каких проблем РЕАЛЬНО можно продать клиентам - Как объяснить клиенту, что ему это не надо - На что надо обращать внимание при формировании ТЗ - Какое оборудование использовать (терминалы, принтеры, сканеры) - Кейсы продажи реальным клиентам - Послепродажное сопровождение клиентов - Мифы про "Универсальную мобильную конфигурацию"

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

Программирование - Практика программирования

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Скачать файлы

Наименование Файл Версия Размер
Конфигурация-пример "Дополнительные параметры процедур и функций"
.cf 11,12Kb
08.09.17
0
.cf 11,12Kb Скачать

См. также

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


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

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


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

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

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

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

Я считаю, что с броским названием тс перегнул, ибо
создать регистр хранения в конфигурации - это банальное решение в лоб не претендующее на рациональную идею и альтернативу. это костыль
20. Goleff74 110 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 42 19.03.18 13:20 Сейчас в теме
Добрый день!
Немного поздновато, но всё же.
У меня архиватор баз, где все необходимые процедуры выполняется в фоне для одного "робота", а другие пользователи просто читаю что-то.
Вот "пухнет" база, я так понял что постоянная перезапись данных идёт.
Сделано через хранилище данных. Весь результат "робот" складывает в хранилище, к нему все подключаются и читают данные, которые отображаются на главной форме любого пользователя (ЗначениеВДанныеФормы()) с определённой для клиента периодичностью. Тут получается что нет никаких справочников, регистров и т.п.

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

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