gifts2017

Ввод контрагента по номеру телефона

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

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

Для этого используем документ "Счет на оплату покупателю", как пример.

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

Процедура КонтрагентОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
	
	// ФантичПоискНомера / обработаем введенный телефон
	Цифры = "0123456789";
	СтрКоличество = СтрДлина(Текст);
	
	тел = "";
	Для Счетчик = 1 По СтрКоличество Цикл
		Если НЕ Найти(Цифры,Сред(Текст,Счетчик,1)) = 0 Тогда
			тел = тел + Сред(Текст,Счетчик,1);
		КонецЕсли;
	КонецЦикла;
	
	Если СтрДлина(тел) = 10 Тогда // это телефон
		КодСтраны = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ОсновнойКодСтраныТелефона");
		Если ПустаяСтрока(КодСтраны) Тогда
			Сообщить("Для текущего пользователя не указан код страны телефона! Поиск по номеру невозможен.");
		Иначе
			Текст = КодСтраны + " ("+Лев(тел,3)+") " + УправлениеКонтактнойИнформацией.ПривестиНомерТелефонаКШаблону(Прав(тел,7));
		КонецЕсли;
	КонецЕсли;
	// ФанКонец //
	
	РезультатЗапроса = ПроцедурыПоискаПоСтроке.ПолучитьРезультатЗапросаАвтоподбора(Текст, Новый Структура, Тип("СправочникСсылка.Контрагенты"), 1);
	
	Если НЕ РезультатЗапроса.Пустой() Тогда
		ПроцедурыПоискаПоСтроке.ОкончаниеВводаТекстаВЭлементеУправления(Элемент, Текст, Значение, СтандартнаяОбработка, Новый Структура, ЭтаФорма, Тип("СправочникСсылка.Контрагенты"), мОбработкаПоискаПоСтрокеКонтрагента, мТекстПоискаПоСтрокеКонтрагента, мПоследнееЗначениеЭлементаПоискаПоСтрокеКонтрагента, Ложь);
		Возврат;
	КонецЕсли; 
	
	УправлениеКонтактами.РегистрироватьНовогоКонтрагента(Элемент, Текст, Значение, СтандартнаяОбработка, мОбработкаПоискаПоСтрокеКонтрагента, мТекстПоискаПоСтрокеКонтрагента, мПоследнееЗначениеЭлементаПоискаПоСтрокеКонтрагента, ЭтаФорма, Контрагент, КонтактноеЛицоКонтрагента, Модифицированность, ДанныеНезарегистрированногоКонтрагента);

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

 
Теперь заменить функцию ПолучитьРезультатЗапросаАвтоподбора в общем модуле ПроцедурыПоискаПоСтроке:

Функция ПолучитьРезультатЗапросаАвтоподбора(Знач Текст, СтруктураПараметров, ТипСправочника, КоличествоЭлементов) Экспорт
		
	ВеткаМетаданных = ПолучитьВеткуМетаданныхПоТипу(ТипСправочника);
	Если ВеткаМетаданных = "" Тогда
		Возврат Неопределено;
	КонецЕсли;
	ПустаяСсылкаТипа = Новый(ТипСправочника);
	
	МетаданныеОбъекта = ПустаяСсылкаТипа.Метаданные();
	
	КоллекцияПоискаПоПодстроке = МетаданныеОбъекта.ВводПоСтроке;
	
	Если КоллекцияПоискаПоПодстроке.Количество() = 0 Тогда
		Возврат Неопределено;
	КонецЕсли; 
	
	ИмяТаблицыСправочника = МетаданныеОбъекта.Имя;
	ИмяТаблицыОграничений = ?(КоллекцияПоискаПоПодстроке.Количество() = 1, "ТаблицаВложенногоЗапроса", "ТаблицаСправочника");
	
	СтрокаОтборовПоСтруктуре = "";
	
	Запрос = СоздатьЗапросДляСпискаАвтоподбора(Текст, СтрокаОтборовПоСтруктуре, СтруктураПараметров, ИмяТаблицыОграничений);
	
	СтрокаПолей = "
	|ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ ПЕРВЫЕ " + Строка(КоличествоЭлементов) + "
	|	ТаблицаВложенногоЗапроса.Ссылка КАК Ссылка,
	|";
	
	Если МетаданныеОбъекта.ДлинаНаименования > 0 Тогда
		СтрокаПолей = СтрокаПолей + "
		|	ТаблицаВложенногоЗапроса.Ссылка.Наименование КАК Наименование,";
	КонецЕсли;
	
	Если МетаданныеОбъекта.ДлинаКода > 0 Тогда
		СтрокаПолей = СтрокаПолей + "
		|	ТаблицаВложенногоЗапроса.Ссылка.Код КАК Код,";
	КонецЕсли; 
	
	Если КоллекцияПоискаПоПодстроке.Количество() = 1 Тогда
		
		ЭлементКоллекции = КоллекцияПоискаПоПодстроке[0];
		ТипЗначенияПоиска = ОпределитьТипОграниченийПоПолю(ЭлементКоллекции.Имя, МетаданныеОбъекта);
		
		Если ЭлементКоллекции.Имя <> "Наименование" И ЭлементКоллекции.Имя <> "Код" Тогда
			СтрокаПолей = СтрокаПолей + "
			|	ТаблицаВложенногоЗапроса.Ссылка." + ЭлементКоллекции.Имя + " КАК " + ЭлементКоллекции.Имя;
		КонецЕсли;
		
		Запрос.Текст = Лев(СтрокаПолей, (СтрДлина(СтрокаПолей) - 1)) + "
		|ИЗ
		|	" + ВеткаМетаданных + "." + ИмяТаблицыСправочника + " КАК ТаблицаВложенногоЗапроса
		|ГДЕ ";
		
		ОграничениеПоПолю = СформироватьОграничениеПоПолюВхождениеВНачало("ТаблицаВложенногоЗапроса." + ЭлементКоллекции.Имя, ТипЗначенияПоиска);
		
		ОграничениеПоПолю = ОграничениеПоПолю + "
		|	И НЕ ТаблицаВложенногоЗапроса.ПометкаУдаления ";
		
		Запрос.Текст = Запрос.Текст +"
		|	" + ОграничениеПоПолю + СтрокаОтборовПоСтруктуре;
	
	Иначе
		
		ПервыйЭлемент = Истина;
		СтрокаТаблиц = "";
		Для каждого ЭлементКоллекции Из КоллекцияПоискаПоПодстроке Цикл
			
			ТипЗначенияПоиска = ОпределитьТипОграниченийПоПолю(ЭлементКоллекции.Имя, МетаданныеОбъекта);
			
			Если ЭлементКоллекции.Имя <> "Наименование" И ЭлементКоллекции.Имя <> "Код" Тогда
				СтрокаПолей = СтрокаПолей + "
				|	ТаблицаВложенногоЗапроса.Ссылка." + ЭлементКоллекции.Имя + " КАК " + ЭлементКоллекции.Имя + ",";
			КонецЕсли;
			
			Если НЕ ПервыйЭлемент Тогда
				СтрокаТаблиц = СтрокаТаблиц + "
				|
				|	ОБЪЕДИНИТЬ ВСЕ
				|";
			КонецЕсли; 
			ПервыйЭлемент = Ложь;
			
			СтрокаТаблиц = СтрокаТаблиц + "
			|	ВЫБРАТЬ  ПЕРВЫЕ " + Строка(КоличествоЭлементов) + "
			|		ТаблицаСправочника.Ссылка КАК Ссылка" + 
			 ?(ТипСправочника = Тип("СправочникСсылка.Контрагенты"),",
			|       NULL КАК Представление // Фантич Добавим для сходства количества полей","
			|") + " 
			|	ИЗ
			|		" + ВеткаМетаданных + "." + ИмяТаблицыСправочника + " КАК ТаблицаСправочника
			|	ГДЕ ";
			
			
			ОграничениеПоПолю = СформироватьОграничениеПоПолюВхождениеВНачало("ТаблицаСправочника." + ЭлементКоллекции.Имя, ТипЗначенияПоиска);
			
			ОграничениеПоПолю = ОграничениеПоПолю + "
			|	И НЕ ТаблицаСправочника.ПометкаУдаления ";
		
			СтрокаТаблиц = СтрокаТаблиц +"
			|	" + ОграничениеПоПолю + СтрокаОтборовПоСтруктуре;		
		КонецЦикла;
		
		// ФАНТИЧ добавим номер телефона в запрос
		Если ТипСправочника = Тип("СправочникСсылка.Контрагенты") Тогда
			СтрокаТаблиц = СтрокаТаблиц + "
			|
			|	ОБЪЕДИНИТЬ ВСЕ
			|
			|	ВЫБРАТЬ  ПЕРВЫЕ " + Строка(КоличествоЭлементов) + "
			|
			|	КИ.Объект.Ссылка КАК Ссылка,
			|   ВЫРАЗИТЬ(КИ.Представление КАК СТРОКА(100))
			| ИЗ
			|	РегистрСведений.КонтактнаяИнформация КАК КИ
			| ГДЕ ";
			
			ОграничениеПоПолю = СформироватьОграничениеПоПолюВхождениеВНачало("КИ.Представление", ТипЗначенияПоиска);
			
			ОграничениеПоПолю = ОграничениеПоПолю + "
			|	И КИ.Объект ССЫЛКА Справочник.Контрагенты
			|	И КИ.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Телефон)";
			
			СтрокаТаблиц = СтрокаТаблиц +"
			|	" + ОграничениеПоПолю + СтрокаОтборовПоСтруктуре;
			
			СтрокаПолей = СтрокаПолей + "
			|	ТаблицаВложенногоЗапроса.Представление,";
		КонецЕсли;
		//  ФанКонец
		
		Запрос.Текст = Лев(СтрокаПолей, (СтрДлина(СтрокаПолей) - 1)) + "
		|ИЗ
		|
		|	(
		|" + СтрокаТаблиц + "
		|	) КАК ТаблицаВложенногоЗапроса";
	
	КонецЕсли; 
	
	Возврат Запрос.Выполнить();

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

 
Если у вас все номера записаны в правильно формате, то можно тестировать!

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Тактик 1С (Taktic) 14.09.15 09:03
Однако изящное начало:


Цифры = "0123456789";
СтрКоличество = СтрДлина(Текст);

тел = "";
Для Счетчик = 1 По СтрКоличество Цикл
Если НЕ Найти(Цифры,Сред(Текст,Счетчик,1)) = 0 Тогда
тел = тел + Сред(Текст,Счетчик,1);
КонецЕсли;
КонецЦикла;


Есть предложение - нужно создать таблицу значений, поместить в каждую строку "цифру", потом поместить ТЗ во временную таблицу и запросом в цикле определить есть ли текущий символ в этой ТЗ.