Заполнение дополнительных реквизитов в модуле на сервере, в правилах КД 2.0, в модуле внешней обработки

31.01.20

Разработка - БСП (Библиотека стандартных подсистем)

Примеры заполнения дополнительных реквизитов.

Уважаемые коллеги, хотелось бы донести до Вашего сведения небольшой опыт работы по заполнению дополнительных реквизитов Справочников и Документов. Уже много статей посвящено теме этих самых реквизитов, добавлю и свои пять копеек.

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

  1. Заполнение доп.ревизитов в модуле на сервере.

Предыстория: в одной организации потребовался перенос данных из одной базы в другую одного из справочников. Да вот беда в базе источнике у справочника было два нужных реквизита объекта, а в базе приемнике их не было. Дабы не ломать типовую конфигурацию было принято решение в новой базе создать такое же количество реквизитов, но в качестве дополнительных. Дело оставалось за малым – поместить в эти реквизиты необходимые данные. Благо коды элементов в базе источнике и базе приёмнике были синхронизированы. Самым простым показалось выгрузить связку из трёх реквизитов (Код – Реквизит1 – Реквизит2) в обычный файл формата Excel на стороне источника и загрузить этот файл на стороне приёмника. Опуская момент выгрузки и последующей загрузки файла сразу перейду к моменту, когда файл уже загружен в базе приёмнике в таблицу значений и предстоит все эти данные разложить по нужным элементам справочника, для которого уже заведены два доп.реквизита с именами (для разработчика) «Реквизит1» и «Реквизит2». В общем-то в данном случае всё довольно таки просто. Будем использовать стандартную процедуру БСП.
 

Для Каждого ТекСтрока Из ТаблицаРеквизитовИсточника Цикл

  //Находим ССЫЛКУ на нужный нам элемент справочника
  СсылкаНаЭлемент = Справочник.НужныйНамСправочник.НайтиПоКоду(ТекСтрока.Код);

  //Находим те доп.реквизиты, которые требуются для заполнения
  СвойствоРеквизит1 = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя","Реквизит1");
  СвойствоРеквизит2 = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя","Реквизит2");
    

  //создаём массив доп.реквизитов для помещения их в нужный элемент
  МассивСтруктур = Новый Массив;
  МассивСтруктур.Добавить(Новый Структура("Свойство, Значение",СвойствоРеквизит1,ТекСтрока.Реквизит1));
  МассивСтруктур.Добавить(Новый Структура("Свойство, Значение",СвойствоРеквизит2,ТекСтрока.Реквизит2));

  //Используя стандартную процедуру БСП присваиваем значения доп.реквизитов элементу справочника
  УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(СсылкаНаЭлемент, МассивСтруктур);

КонецЦикла;

    

Обратите внимание, что никаких получений объекта элемента справочника делать не нужно в силу того, что процедура «ЗаписатьСвойстваУОбъекта» сама получает объект и записывает его на сервере. Это удобно, но это и подводный камень о котором будет упомянуто далее.

  1. Заполнение доп.реквизитов при переносе данных с помощью КД 2.0.

Предыстория: ситуация аналогичная предыдущей. Только на этот раз для переноса данных было решено использовать не файл Excel, а правила обмена, созданные в КД 2.0. Что для этого потребовалось: два реквизита, которые должны были быть перенесены из источника в приёмник в правилах прописывались как переменные. А уже на стороне приёмника в обработчике события «ПослеЗагрузки» из данных переменных заполнялись доп.реквизиты. И тут мы и натыкаемся на подводный камень процедуры БСП. Если использовать предыдущий алгоритм, то при загрузке данных система выдаст сообщение об ошибке «Ошибка при вызове метода контекста (Записать): Данные были изменены или удалены другим пользователем». Остаётся использовать другой вариант, либо делать разные ухищрения типа правил «повторная загрузка» и передавать данные в несколько этапов. Остановимся на первом варианте.

Пропишем в параметры правил конвертации свойств «Реквизит1» и «Ревизит2» нужные нам значения из источника.

 

 

А в обработчике «После загрузки» выполним следующий алгоритм

 

//запишем объект перед тем как устанавливать доп.реквизиты
Если НЕ ОбъектНайден Тогда
	Объект.Записать(режимЗаписиДокумента.Запись);
	ОбъектМодифицирован = ЛОжь;
КонецЕсли;

//Находим те доп.реквизиты, которые требуются для заполнения
СвойствоРеквизит1 = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя","Реквизит1"); 
СвойствоРеквизит2 = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя","Реквизит2");

//На всякий случай очистим табличную часть объекта – предполагается, что мы делаем первичную загрузку
Объект.ДополнительныеРеквизиты.Очистить();

//Добавим строки в табличную часть с заполнением необходимых доп.реквизитов и их значений
НовСтр = Объект.ДополнительныеРеквизиты.Добавить();
НовСтр.Свойство = СвойствоРеквизит1;
НовСтр.Значение = ПараметрыОбъекта["Реквизит1"];
НовСтр = Объект.ДополнительныеРеквизиты.Добавить();
НовСтр.Свойство = СвойствоРеквизит2;
НовСтр.Значение = ПараметрыОбъекта["Реквизит2"];

 

Далее при записи объекта будет записана и его табличная часть и при открытии элемента справочника в базе Приёмник доп.реквизиты будут на своих местах.

  1. Заполнение доп.реквизитов в модуле внешней обработки.

Переходим к ситуации, когда для заполнения дополнительных реквизитов будет использоваться внешняя вставляемая обработка с вариантом использования «Заполнения формы». В данном случае имеется форма документа, из которой и вызывает внешняя обработка заполнения. По своему алгоритму обработка должна получить значения доп.реквизитов Реквизит1 и Реквизит2 и поместить в табличную часть документа «Дополнительные реквизиты». В данном случае при использовании типовой процедуры «УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(…)» создаст те же сложности с различными версиями одного и того же объекта как реквизита формы и находящегося на сервере: после выполнения внешней обработки записать какие-либо ещё изменения реквизитов объекта на форме не представляется возможным. В этом случае потребуется не просто заполнить доп.реквизиты, но и поместить их в тот объект, что находится на сервере. Но это ещё не вся сложность. Дело в том, что дополнительные реквизиты хранятся в объекте как табличная часть, но форме они отображаются именно как реквизиты типа «Поле ввода». По сути дела разработчики заложили в БСП возможность программно создавать набор реквизитов формы по количеству строк заполненных в табличной части «Дополнительные реквизиты» объекта и отображать в них данные из табличной части (те кто занимался этим вопросом наверняка вспомнили реквизиты с длиннющими названиями). Можно конечно пытаться удалить все эти реквизиты и команды с ними связанные (что вполне реально ведь они созданы программно) и вызывать процедуру создания их из процедуры ПриСозданииНаСервере, но есть и более простой вариант. Можно воспользоваться типовой процедурой заполняющей значения реквизитов формы из табличной части объекта УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме(…) где в первом параметре передаётся сама форма, а во втором реквизит Объект этой самой формы. Важно отметить, что заполнение на форме этих реквизитов обязательно, так как если они останутся пустыми, что при закрытии формы с записью в доп.реквизиты запишутся эти самые пустые значения.

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

Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды) Экспорт
  
  //получим контекст формы для заполнения
  КонтекстФормыВызова = ПараметрыКоманды.ЭтаФорма;

  //для внесения изменения получим объект, которому принадлежит форма
  ДанныеОбъекта = КонтекстФормыВызова.Объект;

  //поместим в переменный значения, которые должны оказаться в доп.реквизитах
  Реквизит1 = «А»;
  Реквизит2 = «Б»;

  //Находим те доп.реквизиты, которые требуются для заполнения
  СвойствоРеквизит1 = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя","Реквизит1"); 
  СвойствоРеквизит2 = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя","Реквизит2");

  //далее перед заполнением нового значения доп.реквизита необходимо проверить, что его нет в табличной части
  //а если он есть заполнить новым значением
  СвойствоЕсть = Ложь;
  Для Каждого ТекСрока Из ДанныеОбъекта.ДополнительныеРеквизиты Цикл
  	Если ТекСтрока.Свойство = СвойствоРеквизит1 Тогда
	 ТекСтрока.Значение = Реквизит1;
	 СвойствоЕсть = Истина;
	КонецЕсли;
  КонецЦикла;
  Если Не СвойствоЕсть Тогда		
	НовСтр = Объект.ДополнительныеРеквизиты.Добавить();
	НовСтр.Свойство = СвойствоРеквизит1;
	НовСтр.Значение = Реквизит1;
  КонецЕсли;

  //те же действия повторит и для остальных доп.реквизитов (в данном случае для Реквизит2)
  //вполне возможно при большем значении устанавливаемых значениях доп.реквизитов код оптимизировать – в данном случае такой задачи не стоит

  //теперь необходимо поместить заполненную табличную часть в объект на сервере
  //получим объект с сервера
  ДокОбъектССервера = ДанныеОбъекта.Ссылка.ПолучитьОбъект();

  //передадим в него все доп.реквизиты с объекта на форме
  ТабДопРекв = ДанныеОбъекта.ДополнительныеРеквизиты.Выгрузить(); 	  
  ДокОбъектССервера.ДополнительныеРеквизиты.Загрузить(ТабДопРекв);

  //Запишем объект и поместим его на форму для того чтобы можно было вносить следующие изменения
  ДокОбъектССервера.Записать();
  КонтекстФормыВызова.ЗначениеВРеквизитФОрмы(ДокОбъектССервера,"Объект");
  
  //Обновим отображение значений доп.реквизитов на форме
  УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме(КонтекстФормыВызова, КонтекстФормыВызова.РеквизитФормыВЗначение("Объект"));

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

 

Примечательно, что процедура «ЗаполнитьДополнительныеРеквизитыВФорме(…)» можно так же использовать и в том случае если доп.реквизиты заполняются по кнопочке из формы.

На этом завершаю рассмотрение программного заполнения доп.реквизитов и надеюсь, это поможет кому-то ускорить процесс разработки.

дополнительные реквизиты заполнение

См. также

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Пример шаблона для многопоточного выполнения фонового задания на основе БСП. Шаблоны сделаны для процедуры и функции.

2 стартмани

03.05.2024    1231    18    Hitcher    3    

12

БСП (Библиотека стандартных подсистем) Адаптация типовых решений Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Понадобилось в подменю "Создать на основании" добавить свою команду, которая открывает обработку. В процессе доработок появилась проблема двух подменю "Создать на основании". В статье о том, как решились проблемы.

01.03.2024    3441    dimanich70    8    

15

Механизмы платформы 1С БСП (Библиотека стандартных подсистем) Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Небольшая шпаргалка по функциям БСП касательно адреса. Так скажем, еще один способ помимо https://infostart.ru/1c/articles/1060970/

12.02.2024    1120    FilippovRI    0    

17

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

Уже не одна веб-страница исписана знаниями о дополнительных обработках, как создать, как подключить. Есть масса вариантов, как их можно отладить. Я разобрался в кишках работы библиотеки и покажу, как можно расширить возможности дополнительных отчетов, а также покажу удобный способ отладки.

07.02.2024    3413    YA_418728146    11    

52
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Megaiff 11.02.20 01:32 Сейчас в теме
Годно. Больше хитростей с КД в студию.
Gal4onoK_89; reneyr; +2 Ответить
2. vikb11 02.04.24 12:25 Сейчас в теме
На текущий момент пример с функцией "ЗаписатьСвойстваУОбъекта" не работает - второй параметр у этой функции должен быть ТЗ!
Оставьте свое сообщение