Переопределение ввода по строке в управляемой форме 1С

26.08.13

Разработка - Механизмы платформы 1С

Повествование о событиях: «Автоподбор», «ОкончаниеВводаТекста», «ПриПолученииДанныхВыбора»; о глобальном методе «ПолучитьДанныеВыбора»; и о том, как с их помощью полностью переопределить стандартный автоподбор (ввод по строке) для поля управляемой формы.

Скачать файл

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

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

Предыстория

К написанию статьи меня подтолкнула задача, для решения которой я должен был разработать сложную форму с большим количеством полей, связанных с разными объектами и, что главное, «c одной кнопкой». Тут и родилась мысль воспользоваться функцией «ввода по строке» в управляемом приложении 1С. В процессе решения задачи пришлось «набить шишек», но, надеюсь, приобретенный опыт будет полезен не только мне.

Механика

Думаю, правильным будет начать с краткого описания механики клиент-серверного взаимодействия при «вводе по строке».

Все начинается с поля ввода формы, у которого есть события «Автоподбор» и «ПриОкончанииВводаТекста».

Событие «АвтоПодбор» возникает при остановке ввода текста или нажатии на кнопку «стрелка вниз».

Событие «ОкончаниеВводаТекста» вызывается, как нам сообщает справка, при формировании значения из текста ввода. Кстати, это событие интересно тем, что если значение не сформировано, система не даст нам выйти из режима редактирования элемента. Иными словами, если введенный в поле текст не соответствует какому либо значению из данных выбора, то редактирование не будет завершено.

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

Обращаясь к труду «Разработка управляемого интерфейса» госпожи Хрусталевой и прочих уважаемых авторов, находим упоминание о методе «ПолучитьДанныеВыбора». Если спросить об этом методе синтаксис помощник, он выдаст нам список методов менеджеров для всех видов объектов платформы. Но, что толку от методов менеджеров, которые выполняются на сервере, если серверные вызовы нам недоступны? На самом деле, этот вопрос здесь, только по той причине, что если бы я был более внимательным человеком, я сразу решил бы свою задачу, и никакой статьи не появилось бы. Достаточно просто пролистать до конца список ссылок, и в конце обнаружится  глобальный метод «ПолучитьДанныеВыбора». С помощью этого метода мы на клиенте можем получить данные выбора для любого ссылочного объекта системы, что дает возможность переопределить стандартный алгоритм получения выбора данных. Например, для поля строчного типа, у которого вообще нет стандартных данных выбора, использовать алгоритм справочника «Контрагенты».

Но для нас основная ценность метода «ПолучитьДанныеВыбора» в том, что он провоцирует вызов события «ПриПолученииДанныхВыбора», котрое выполняется в контексте менеджера выбранного нами типа объекта. Иными словами мы, наконец, получаем возможность работать с сервером, а значит и самостоятельно сформировать данные выбора. И с этого момента на возможность работать с автоподбором влияют только фантазия и здравый смысл. 

Задача

Мы разобрались с взаимодействием клиента и сервера, теперь я предлагаю подкрепить теорию практикой. Решим небольшую задачу, которая звучит следующим образом.

Дано:

  1. Демонстрационная конфигурация «Управляемое приложение»
  2. Покупатели «Компании» являются частными лицами
  3. Наименования клиентов по правилам «Компании» состоят из фамилии и инициалов.
  4. ФИО клиентов могут периодически изменяться

Реализовать в форме документа «РасходТовара» подбор покупателя по ФИО.

Решать сохранение нового покупателя и его ФИО не будем, так как к «вводу по строке» это не относится.

Решение:

Добавим в конфигурацию «Управляемое приложение» новый периодический регистр сведений «ФИОКонтрагентов». Периодичность «день», единственное и ведущее измерение «Контрагент» (Тип(«СправочникСсылка.Контрагенты»)), ресурсы «Фамилия», «Имя», «Отчество» (Тип(«Строка(50)»)).

На форме документа «РасходТовара» также добавим три новых реквизита «ПокупательФамилия», «ПокупательИмя», «ПокупательОтчество».  Также, для удобства, добавим кнопку и команду «ОчиститьФИО».

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

В модуле формы реализуем метод «ПолучитьДанныеВыбораПоФИО» с директивой компиляции &НаКлиенте

&НаКлиенте
Функция ПолучитьДанныеВыбораПоФИО(Элемент, ПокупательФамилия, ПокупательИмя, ПокупательОтчество, СтандартнаяОбработка)

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

КонецФункции

В модуле менеджера справочника «Контрагенты» реализуем обработчик «ОбработкаПолученияДанныхВыбора»

Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
	Перем ДополнительныеПараметры;
	Если Параметры.Свойство("ДополнительныеПараметры", ДополнительныеПараметры) Тогда
			
		// Выключим стандартную обработку
		СтандартнаяОбработка = Ложь;
		
		ДанныеВыбора	=	РегистрыСведений.ФИОКонтрагентов.ПолучитьДанныеВыбораФИО(ДополнительныеПараметры.Фамилия, 
																						ДополнительныеПараметры.Имя, 
																						ДополнительныеПараметры.Отчество, 
																						ДополнительныеПараметры.Дата);
			
	КонецЕсли;
КонецПроцедуры

В модуле менеджера регистра сведений «ФИОКонтрагентов» реализуем экспортную функцию

«ПолучитьДанныеВыбораФИО»

Функция ПолучитьДанныеВыбораФИО(Знач Фамилия, Знач Имя, Знач Отчество, Период) Экспорт
	
	спВыбора	=	Новый СписокЗначений;
	
	// Подготовим шаблоны поиска по вхождению
	Если НЕ ЗначениеЗаполнено(СокрЛП(Фамилия)) Тогда
		Возврат Неопределено;	
	Иначе
		Фамилия	=	СокрЛП(Фамилия) + "%";
	КонецЕсли;
	
	Имя	=	СокрЛП(Имя) + "%";

	Отчество	=	СокрЛП(Отчество) + "%";
	
	// Сформируем запрос в котором достаточно данных для наглядного представления контрагентов
	Запрос	=	Новый Запрос;
	Запрос.Текст	=	"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 50
	            	 	|	ФИОКонтрагентовСрезПоследних.Фамилия,
	            	 	|	ФИОКонтрагентовСрезПоследних.Имя,
	            	 	|	ФИОКонтрагентовСрезПоследних.Отчество,
	            	 	|	ФИОКонтрагентовСрезПоследних.Контрагент,
	            	 	|	ПРЕДСТАВЛЕНИЕССЫЛКИ(ФИОКонтрагентовСрезПоследних.Контрагент) КАК КонтрагентПредставление,
	            	 	|	ВЫРАЗИТЬ(ФИОКонтрагентовСрезПоследних.Контрагент КАК Справочник.Контрагенты).Код КАК КонтрагентКод
	            	 	|ИЗ
	            	 	|	РегистрСведений.ФИОКонтрагентов.СрезПоследних(&Период, ) КАК ФИОКонтрагентовСрезПоследних
	            	 	|ГДЕ
	            	 	|	ФИОКонтрагентовСрезПоследних.Фамилия ПОДОБНО &Фамилия
	            	 	|	И ФИОКонтрагентовСрезПоследних.Имя ПОДОБНО &Имя
	            	 	|	И ФИОКонтрагентовСрезПоследних.Отчество ПОДОБНО &Отчество";
						
	Запрос.УстановитьПараметр("Период", Период);
	Запрос.УстановитьПараметр("Фамилия", Фамилия);
	Запрос.УстановитьПараметр("Имя", Имя);
	Запрос.УстановитьПараметр("Отчество", Отчество);
	
	Выборка	=	Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		
		ПредставлениеКонтрагента	=	Выборка.Фамилия;
		Если ЗначениеЗаполнено(Выборка.Имя) Тогда
			ПредставлениеКонтрагента	=	ПредставлениеКонтрагента + " " + Выборка.Имя;
		КонецЕсли; 
		Если ЗначениеЗаполнено(Выборка.Отчество) Тогда
			ПредставлениеКонтрагента	=	ПредставлениеКонтрагента + " " + Выборка.Отчество;
		КонецЕсли;
		ПредставлениеКонтрагента	=	ПредставлениеКонтрагента + "(" + Выборка.КонтрагентКод +":" + Выборка.КонтрагентПредставление + ")";
		
		спВыбора.Добавить(Выборка.Контрагент, 
								ПредставлениеКонтрагента);	
	
	КонецЦикла; 
	
	Возврат спВыбора;

КонецФункции // ПолучитьДанныеВыбораФИО()

Теперь определим в форме документа обработчики «ФамилияАвтоПодбор», «ИмяАвтоПодбор», «ОтчествоАвтоПодбор».

&НаКлиенте
Процедура ФамилияАвтоПодбор(Элемент, Текст, ДанныеВыбора, Параметры, Ожидание, СтандартнаяОбработка)
	
	// Если в уже заполненом текстовом поле нажать "вниз", то параметр "Текст" окажется пустым
	// учтем это
	знТекст	=	?(ПустаяСтрока(Текст), Фамилия, Текст);
	ДанныеВыбора	=	ПолучитьДанныеВыбораПоФИО(Элемент, знТекст, Имя, Отчество, СтандартнаяОбработка);
	
КонецПроцедуры

&НаКлиенте
Процедура ИмяАвтоПодбор(Элемент, Текст, ДанныеВыбора, Параметры, Ожидание, СтандартнаяОбработка)
	
	знТекст	=	?(ПустаяСтрока(Текст), Имя, Текст);
	ДанныеВыбора	=	ПолучитьДанныеВыбораПоФИО(Элемент, Фамилия, знТекст, Отчество, СтандартнаяОбработка);
	
КонецПроцедуры

&НаКлиенте
Процедура ОтчествоАвтоПодбор(Элемент, Текст, ДанныеВыбора, Параметры, Ожидание, СтандартнаяОбработка)
	
	знТекст	=	?(ПустаяСтрока(Текст), Отчество, Текст);
	ДанныеВыбора	=	ПолучитьДанныеВыбораПоФИО(Элемент, Фамилия, Имя, знТекст, СтандартнаяОбработка);
	
КонецПроцедуры

Обработчики «ФИООбработкаВыбора» , «ФИОПриИзменении», «ФИОПриИзмененииНаСервере» подойдут для всех полей ФИО.

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

&НаКлиенте
Процедура ФИОПриИзменении(Элемент)
	
	ФИОПриИзмененииНаСервере(Элемент.Имя);
	
	// Обработаем изменение "Покупателя"
	ПокупательПриИзменении(Элементы.Покупатель);
	
КонецПроцедуры

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

Готово! Можем заходить и проверять, что у нас получилось.

Решенный вариант можно получить с помощью обновления (cfu) в приложении к статье. Для этого создайте из "Демонстрационной конфигурации "Управляемое приложение" (1.0.16.1)" файл поставки и обновите его приложенным файлом.  Для тех, кто редко делает поставки вот нехитрая процедура:

  1. Получите на users.v8.1c.ru демонстрационную конфигурацию  1.0.16.1 в разделе «Технологическая платформа 8.3/Демонстрационная информационная база»
  2. Установите
  3. Запустите конфигуратор с демонстрационной конфигурацией
  4. Выберите в меню «Конфигурация»/ «Поставка конфигурации»/ «Создать файлы поставки и обновления конфигурации»
  5. Уберите «Создать файл обновления конфигурации»
  6. Нажмите «Выполнить»
  7. Загрузите полученный файл поставки в информационную базу: «Конфигурация»/ «Загрузить конфигурацию из файла»
  8. Обновите поставку файлом, приложенным к статье: «Конфигурация»/ «Поддержка»/ «Обновить конфигурацию»/ «Выбор файла обновления»/ «Далее» /Выбираем и файл и обновляем.
  9. Сохраните конфигурацию и запустите информационную базу
  10. Задавайте вопросы и конструктивно критикуйте.

P.S. Хочу напомнить, что выход из режима «подбора по строке» без выбора осуществляется через “Esc”, табуляция по умолчанию принимает текущую строку как выбор.

Ввод по строке

См. также

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

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    6208    bayselonarrend    19    

153

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

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5370    dsdred    16    

79

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

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

24.01.2024    14853    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    10514    dsdred    44    

129

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    22869    SeiOkami    46    

133

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    17626    human_new    27    

80

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

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

28.08.2023    13678    YA_418728146    7    

165
Вознаграждение за ответ
Показать полностью
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. yukon 152 27.08.13 10:27 Сейчас в теме
На самом деле, этот вопрос здесь, только по той причине, что если бы я был более внимательным человеком, я сразу решил бы свою задачу, и никакой статьи не появилось бы.


Да если бы всегда так.

Дело в том, что мы не имеем права вызывать для этих событий серверные методы с директивой компиляции &НаСервере.


Можно, конечно, обойти через метод с директивой &НаСервереБезКонтекста, но правильнее, как раз, через ДанныеВыбора.
a-novoselov; +1 Ответить
4. i.kovtun 180 28.08.13 22:57 Сейчас в теме
(1) yukon,
Можно, конечно, обойти через метод с директивой &НаСервереБезКонтекста, но правильнее, как раз, через ДанныеВыбора.

Да, действительно "артефактов" с "&НаСервереБезКонтекста" не наблюдается.
2. CagoBHuK 32 28.08.13 11:32 Сейчас в теме
Просто плюсик за труд.
3. haggart 28.08.13 17:19 Сейчас в теме
5. karnilaev 106 15.10.15 23:12 Сейчас в теме
Спасибо, статья помогла решить проблему.
6. Михаська 12 13.05.16 17:48 Сейчас в теме
7. wakc 30.05.16 16:33 Сейчас в теме
ПолучитьФИОКонтрагента - что за процедура?
8. Jen1978 19 01.03.17 09:01 Сейчас в теме
ссылка на демонстрационную базу битая, где еще можно скачать данную версию демонстрационной базы ?
на версию 1.0.22.2 Ваше обновление уже не встает.
10. Jen1978 19 02.03.17 08:48 Сейчас в теме
не получается, в ссылке 1.0.16.2 а обновление 1.0.16.1
11. i.kovtun 180 16.03.17 12:47 Сейчас в теме
Извините за паузу, я вероятно пропустил уведомление.
Конфу с изменениями не смог найти. Могу выслать ДТ 1.0.16.1.
16. AndrewUs 13 29.08.18 09:13 Сейчас в теме
(11) Здравствуйте. Можете выслать ДТ 1.0.16.1, т.к. не получается обновить?
12. aero07 21.05.17 17:26 Сейчас в теме
13. jsunny 3 15.01.18 16:19 Сейчас в теме
ОГРРРРОМНОЕ СПАСИБО. По аналогии сделал через расширения вывод ИНН у контрагента для автоподбора в своем документе.
14. wash 2 01.06.18 08:47 Сейчас в теме
ПолучитьФИОКонтрагента - что за процедура?
15. Jen1978 19 01.06.18 09:11 Сейчас в теме
17. MMihailova 16.09.18 20:51 Сейчас в теме
Спасибо, ценная статья - помогла решить проблему.
18. gdu199 27 21.02.19 11:26 Сейчас в теме
Здравствуйте. Вышлите пожалуста ДТ 1.0.16.1
19. i.kovtun 180 22.02.19 13:42 Сейчас в теме
20. Ellestrago 18.10.19 09:35 Сейчас в теме
Спасибо!
Статья супер, очень помогла.
Если кому-то будет полезно, то описание "Ввод по строке" находится в книге 1С: Разработка управляемого интерфейса\стр.564
21. zharkyn 14.09.20 18:01 Сейчас в теме
Статья до сих пор актуально. Никак не могу найти Можете выслать ДТ 1.0.16.1, т.к. не получается обновить?
22. vipetrov2 11.10.21 11:45 Сейчас в теме
Можно было бы попроще сделать. Обычно если нужно физ.лицо к чему то прикрутить, то добавляют именно 1 реквизит Справочник.ФизическиеЛица, а не отдельно 3 строки для ФИО.

И тогда в самой форме вообще ни какого кода писать не надо, просто добавляем на форму поле физ.лицо. Если надо, что новый поиск работал только на этой форме, тогда в свойствах этого поля добавляем в ПараметрыВыбора новую строчку с именем "НовыйПоиск", и значением "Истина".

В справочнике физ.лиц. добавляем процедуру ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка), как в статье, но сначала проверяем условие Параметры.НовыйПоиск = Истина, а потом разбираем Параметры.СтрокаПоиска на ФИО. Например, пользователь ввел "Сидо Ст Пе", мы по пробелам разделяем строку. Начало фамилии "Сидо", начало имени "Ст" и начало отчества "Пе". Но здесь может быть проблема со всякими "Оглы", когда в ФИО 4 и более пробелов, или например, "Жанна Августина де Бартелеми". Здесь конечно можно поспорить, как лучше...
А дальше вызываем функцию из статьи РегистрыСведений.ФИОКонтрагентов.ПолучитьДанныеВыбораФИО(..), которую тоже не мешало бы переписать, там не учитывается отборы, которые находятся в Параметры.Отбор, и не зачем в запросе искать по отчеству, если оно не введено и прочее..
user1804494; trupo; luchik.lipetsk; +3 Ответить
23. Merkalov 11 15.10.21 10:45 Сейчас в теме
Спасибо! Сэкономил кучу времени.

Дополнительно с чем столкнулся:

АвтоПодбор - возникает в момент паузы при вводе.
ОкончаниеВводаТекста - Возникает после ввода текста и нажатия клавиши Enter.

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

Так же у своих полей ввода выключил свойство "ИсторияВвода", иначе весь смысл в ограничениях терялся, вместе с ограниченным поиском в поле ввода отображалась и "история" ввода за предыдущие сеансы. Возможно есть способы и её ограничить/очистить, но заморачиваться уже не стал.
user1804494; i.kovtun; user717534; +3 Ответить
24. Ranetka 23 20.09.23 15:31 Сейчас в теме
Уважаемый автор, спасибо за полезную статью, но стоило сделать более простой пример. Не нужны все эти ФИО из трех полей и регистры сведений с функциями для того, чтобы рассказать про переопределение ввода по строке. Это ваш рабочий пример, но в учебных целях он не нужен.
Есть поле на форме с типом справочник, задача при наборе текста в нем искать не по коду/наименованию, а по некоему алгоритму - всё.
user906828; user1804494; +2 Ответить
Оставьте свое сообщение