gifts2017

Ввод на основании

Опубликовал Сергей Перепечаев (perepechayev) в раздел Программирование - Практика программирования

На основе простого примера показана реализация механизма ввода на основании.

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

Рассмотрим работу механизма ввода на основании на следующем примере: Организация оказывает услуги пассажирского такси. Заказы покупателей регистрируются в документе «Заказ». Заказ может быть формируется диспетчером. Документ «Заказ» содержит следующую информацию:

  1. имя клиента
  2. адрес клиента
  3. адрес откуда
  4. адрес куда
  5. время подачи
  6. желаемый класс автомобиля
  7. список желаемых опций

Имя клиента, его адрес и телефон хранятся в справочнике «Клиенты». В данном примере будет реализован ввод документа на основании справочника. С целью упрощения примера справочник будет только один - «Клиенты», вся остальная информация будет вводиться вручную.

Создание объектов конфигурации

Справочник "Клиенты":

Документ «Заказ»:

Реализация

В свойствах документа «Заказ» перейдем на закладку «Ввод на основании»:

Нажмем кнопку «Редактировать элемент списка» и выберем из списка справочник «Клиенты»:

Далее запустим конструктор ввода на основании нажатием на кнопку "Конструктор ввода на основании":

В открывшемся окне нужно сопоставить поля справочника с реквизитами документа заказа. Это можно сделать, нажав кнопку «Заполнить выражения» и тогда система попытается сама определить, какие поля необходимо скопировать:

Поле адреса нужно сопоставлять вручную, выбрав поле «АдресОткуда» в нижней части, а затем двойным щелчком на реквизите «Адрес» в реквизитах объекта обоснования:

По нажатию «ОК» система генерирует следующий код в модуле документа «Заказ» в процедуре ОбработкаЗаполнения:

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
	//{{__КОНСТРУКТОР_ВВОД_НА_ОСНОВАНИИ
	// Данный фрагмент построен конструктором.
	// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
	Если ТипЗнч(ДанныеЗаполнения) = Тип("СправочникСсылка.Клиенты") Тогда
		// Заполнение шапки
		АдресОткуда = ДанныеЗаполнения.Адрес;
		Клиент = ДанныеЗаполнения.Ссылка;
		Телефон = ДанныеЗаполнения.Телефон;
	КонецЕсли;
	//}}__КОНСТРУКТОР_ВВОД_НА_ОСНОВАНИИ
КонецПроцедуры

Процедура ОбработкаЗаполнения вызывается в ряде случаев, таких как ввод нового документа интерактивно и ввод на основании. В данном случае, если переменная ДанныеЗаполнения является ссылкой на справочник клиентов, выполняется заполнение реквизитов документа. Код обработчика можно модифицировать. Предположим, что клиенты чаще всего хотят подачу такси в течение 15-20 минут. Тогда в код обработчика можно добавить инициализацию реквизита «ВремяПодачи». Также удалим комментарии, созданные конструктором:

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
	Если ТипЗнч(ДанныеЗаполнения) = Тип("СправочникСсылка.Клиенты") Тогда
		АдресОткуда = ДанныеЗаполнения.Адрес;
		Клиент = ДанныеЗаполнения.Ссылка;
		Телефон = ДанныеЗаполнения.Телефон;
		ВремяПодачи = ТекущаяДата() + 900; // 15 * 60 секунд
	КонецЕсли;
КонецПроцедуры

 Запустим приложение в режиме отладки и проверим, как работает ввод на основании. Добавим пару записей в справочник клиентов:

Откроем одну из них. В окне будет доступна кнопка «Создать на основании», по нажатию которой откроется список с опцией выбора «Заказ»:

При выборе «Заказ» система создает пустой документ и заполняет поля в процедуре ОбработкаЗаполнения:

Сохраним документ и убедимся, что документ был успешно создан, открыв его из спиcка документов заказа:

Теперь предположим, что у клиентов могут быть опции, которые всегда присутствуют в заказе данного клиента. Например, «Некурящий водитель». Тогда их можно задавать в справочнике клиентов и копировать в документ заказа. Расширим справочник «Клиенты» табличной частью «Опции»:

Теперь необходимо модифицировать процедуру ОбработкаЗаполнения документа. Это можно было бы сделать через конструктор, но тогда процедура обработки будет перезаписана, поэтому добавим код копирования табличной части вручную:

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
	Если ТипЗнч(ДанныеЗаполнения) = Тип("СправочникСсылка.Клиенты") Тогда
		// Заполнение шапки
		АдресОткуда = ДанныеЗаполнения.Адрес;
		Клиент = ДанныеЗаполнения.Ссылка;
		Телефон = ДанныеЗаполнения.Телефон;
		ВремяПодачи = ТекущаяДата() + 900; // 15 * 60 секунд
		
		Для Каждого ТекСтрока Из ДанныеЗаполнения.Опции Цикл
			НоваяЗапись = Опции.Добавить();
			НоваяЗапись.Опция = ТекСтрока.Опция;
			НоваяЗапись.Количество = ТекСтрока.Количество;
		КонецЦикла;
	КонецЕсли;
КонецПроцедуры

 Запустим конфигурацию в режиме отладки и посмотрим, что получилось. Добавим опции клиенту:

Сохраним данные и создадим заказ на основании записи справочника:

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

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Сергей (necropunk) 02.03.15 15:47
Как-то слишком уж просто. А как бы вы сделали на управляемых формах, к примеру, создание на основании группы документов/элементов справочника? Допустим, каждой строке табличной части документа соответствует один элемент справочника и нужно сформировать 10 элементов и открыть формы незаписанных элементов...
2. Макас (makas) 02.03.15 16:06
Плюсую за Карлсона, который живет на крыше + :-)
3. Андрей Карпов (karpik666) 03.03.15 03:46
(1) necropunk, у вас тоже какой то странный пример. Но даже он решается программным образом, я бы повесил обработчик перед записью на проверку. Ну а вообще что из этого получится, откроется куча немодальных окон и как в таком разобраться? А если будет не 10 позиций а 50 и начнется хаос
4. Артем Целовальников (slazzy) 03.03.15 09:34
(3) karpik666, нет ну теоретически это решается довольно легко, через каскад вызываемых асинхронных процедур.
Вызываем первую процедуру, и в дополнительные параметры передаем список элементов, которые ещё надо создать, при закрытии первой формы создаем один элемент и удаляем его из списка, ну и так по кругу ))
правда необходимость подобного действа очень сомнительна.
5. Сергей Перепечаев (perepechayev) 03.03.15 10:38
(1) necropunk, спасибо, я постараюсь развить тему. Вопрос в том, как сделать видным "лес из-за деревьев" при таком усложнении.
6. Андрей Карпов (karpik666) 03.03.15 12:16
(4) slazzy, а тут немного непонятно, первый доп параметр, содержащий список элементов, будет передаваться первой форме элемента из документа основания, а затем? Оставшийся список элементов передается из формы нового элемента или документа основания? Если документа основания, то планируется я так понимаю повесить это все на обработчик оповещения?
7. Артем Целовальников (slazzy) 03.03.15 12:29
(6) karpik666, Этот параметр будет передаваться через ОписаниеОповещения в доп параметрах, либо он может вообще не передаваться, а храниться в глобальной переменной.

Я просто предложил элементарный способ решения Вашей задачи :) хотя сама задача мне кажется крайне редкоиспользуемой. Вот примерно как-то так


Процедура СоздатьСледующийОбъект(МассивОбъектов) Экспорт
	Если НЕ МассивОбъектов.Количество() Тогда
		Возврат;
	КонецЕсли;
	СоздаваемыйОбъект = МассивОбъектов [ 0 ] ;
	МассивОбъектов.Удалить( 0 );
	ПараметрыОткрытия = Новый Структура("ЗначенияЗаполнения",СоздаваемыйОбъект);
	
	ОписаниеОповещения = Новый ОписаниеОповещения("ЗавершениеСоздатьСледующийОбъект",ЭтотОбъект,МассивОбъектов);
	ОткрытьФорму("ИмяФормы",ПараметрыОткрытия,,,,,ОписаниеОповещения);
КонецПроцедуры

Процедура ЗавершениеСоздатьСледующийОбъект(РезультатЗакрытия, МассивОбъектов) Экспорт
	
	Если МассивОбъектов.Количество() Тогда
		СоздатьСледующийОбъект(МассивОбъектов);
	КонецЕсли;
	
КонецПроцедуры
...Показать Скрыть
8. Aleksandr Filonov (AleksSF) 04.03.15 14:08
Скоро начнем писать статьи как создать справочник и в нем 1 реквизит. Неужели книжек мало, чтобы такой элементарщиной забивать полезный сайт.
Видимо пора уже модераторам фильтровать поток писательства.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа