gifts2017

Универсальная обработка события "ОкончаниеВводаТекста"

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

При вводе по строке выводит в список значения произвольных реквизитов. Функция универсальна для любой конфигурации. Для использования необходимо предлагаемую функцию вставить в общий модуль. Функция вызывается из обработчика элемента формы "ОкончаниеВводаТекста".
Текст функции с примером ее вызова представлен ниже.

Недавно поставила мне бух задачу: Хочу, чтобы когда я вводила расчетный счет контрагента в платежное поручение, отображался в списке для выбора расчетный счет и МФО в скобочках. Другая бухгалтерша захотела, чтобы при вводе статьи затрат та отображалась с хитрой кодировкой в списке значений. И у меня родилась идея написать универсальный обработчик события "ОкончаниеВводаТекста" элемента формы, который бы позволил при вводе по строке выводить в список значения произвольных реквизитов.

Функция универсальна для любой конфигурации.

Для использования необходимо предлагаемую функцию вставить в общий модуль.

Функция вызывается из обработчика элемента формы "ОкончаниеВводаТекста".

 

Пример вызова функции:

 

Процедура СчетКонтрагентаОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)

           
СтандартнаяОбработка = Ложь;

           
Значение = РаботаСДиалогами.ПолучитьСписокОкончаниеВводаТекста("БанковскиеСчета",Текст,"НомерСчета","Банк.Код",,"МФО",Контрагент);

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

 

//==================================

//ПолучитьСписокОкончаниеВводаТекста(_НазваниеСправочника,_Текст,_НазваниеРекв1,_НазваниеРекв2 = "",_Рекв2ВСкобки = Истина,_ТекстРекв2 = "",_ВладелецСправочника = "") Экспорт

// _НазваниеСправочника - Строка с названием справочника

// _Текст - Подстрока набираемого текста

// _НазваниеРекв1 - Строка с названием реквизита, который будем показывать в списке значений

// _НазваниеРекв2 - Строка с названием реквизита, который будем показывать в списке значений в скобочках

// _Рекв2ВСкобки - Признак вывода второго реквизита в скобках, булево

//_ТекстРекв2 - В случае необходимости добавляем к значению реквизита в скобочках его имя

// _ ВладелецСправочника – Фильтр по владельцу

// Возвращает список значений; Вызывается из обработчика события "ОкончаниеВводаТекста" элемента формы

Функция ПолучитьСписокОкончаниеВводаТекста(_НазваниеСправочника,_Текст,_НазваниеРекв1,_НазваниеРекв2 = "",_Рекв2ВСкобки = Истина,_ТекстРекв2 = "",_ВладелецСправочника = "") Экспорт

           
Метадан = Метаданные.Справочники[_НазваниеСправочника];

           
ПоляВводПоСтроке = Метадан.ВводПоСтроке;

           
КвоСимволов = СтрДлина(СокрЛП(_Текст));

           
СписокЗн = Новый СписокЗначений;

            Если
ПоляВводПоСтроке.Количество() = 0 ИЛИ КвоСимволов = 0 Тогда

                        Возврат
СписокЗн;

            КонецЕсли;



                       
Запрос = Новый Запрос;

                       
Запрос.УстановитьПараметр("КвоСимволов",КвоСимволов);

                       
Запрос.УстановитьПараметр("Текст",_Текст);

                       
Запрос.Текст "ВЫБРАТЬ

                        |           Спр.Ссылка,

                |       Спр."
+_НазваниеРекв1+"";



                        Если
_НазваниеРекв2 <> "" Тогда



                                  
Запрос.Текст = Запрос.Текст + ",

                                   |           Спр."
+_НазваниеРекв2+"";

                        КонецЕсли;



                       
Запрос.Текст = Запрос.Текст + "



                        |ИЗ

                        |           Справочник."
+_НазваниеСправочника+" КАК Спр

                        |ГДЕ"
;



                        Для каждого
ТекСтр Из ПоляВводПоСтроке Цикл



                                   Если (
ТекСтр.Имя = "Наименование")

                                               ИЛИ (
ТекСтр.Имя = "Код" И Строка(Метадан.ТипКода) = "Строка")

                                               ИЛИ (
ТекСтр.Имя <> "Код" И ТипЗнч(Метадан.Реквизиты[ТекСтр.Имя].Имя) = Тип("Строка")) Тогда



                                              
Запрос.Текст = Запрос.Текст + "

                                               |  "
+ ?(ПоляВводПоСтроке.Индекс(ТекСтр) > 0," ИЛИ ","(")+            "ПОДСТРОКА(Спр." + ТекСтр.Имя + ", 1, &КвоСимволов) = &Текст"

                                              
+  ?(ПоляВводПоСтроке.Индекс(ТекСтр) = (ПоляВводПоСтроке.Количество() - 1),")","");



                                   Иначе

                                              
Запрос.Текст = Запрос.Текст + "

                                               |  "
+ ?(ПоляВводПоСтроке.Индекс(ТекСтр) > 0," ИЛИ ","(")+     "Спр." + ТекСтр.Имя + " = &Текст"

                                              
+  ?(ПоляВводПоСтроке.Индекс(ТекСтр) = (ПоляВводПоСтроке.Количество() - 1),")","");

                                   КонецЕсли;

                        КонецЦикла;



                        Если
Метадан.Иерархический Тогда

                                  
Запрос.Текст = Запрос.Текст + "

                                   |           И (НЕ Спр.ЭтоГруппа)"
;

                        КонецЕсли;



                        Если
_ВладелецСправочника <> "" Тогда

                                  
Запрос.УстановитьПараметр("ВладелецСправочника",_ВладелецСправочника);

                                  
Запрос.Текст = Запрос.Текст + "

                                   |           И Спр.Владелец = &ВладелецСправочника"
;

                        КонецЕсли;



                       
Запрос.Текст = Запрос.Текст + "

                        |

                        |УПОРЯДОЧИТЬ ПО

                        |           "
+_НазваниеРекв1+"";



                        Если
_НазваниеРекв2 <> "" Тогда



                                  
Запрос.Текст = Запрос.Текст + ",

                                   |           "
+_НазваниеРекв2+"";

                        КонецЕсли;



                       
ЗначениеРекв2 = "";

                       
Выборка = Запрос.Выполнить().Выбрать();

                        Пока
Выборка.Следующий() Цикл

                                  
ЗначениеСсылка = Выборка.Ссылка;

                                  
ЗначениеРекв1  = СокрЛП(Выборка[_НазваниеРекв1]);

                                   Если
_НазваниеРекв2 <> "" Тогда

                                              
_НазваниеРекв2 = СтрЗаменить(_НазваниеРекв2,".","");

                                              
ЗначениеРекв2 = ?(_Рекв2ВСкобки," (",?(_ТекстРекв2 <> ""," ","")) + _ТекстРекв2 + " " + СокрЛП(Выборка[_НазваниеРекв2]) + ?(_Рекв2ВСкобки,")","");



                                   КонецЕсли;



                                  
СписокЗн.Добавить(ЗначениеСсылка,ЗначениеРекв1 + ЗначениеРекв2);



                        КонецЦикла;

            Возврат
СписокЗн;

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

См. также

Подписаться Добавить вознаграждение
Комментарии
2. Андрей Осин (anosin) 28.10.11 10:33
Иногда не удобно что скобки в конце при длинном наименовании (например код артикул выводить)

добавил параметр.

Функция ПолучитьСписокОкончаниеВводаТекста(_НазваниеСправочника,_Текст,_СначалаСкобки,_НазваниеРекв1,_НазваниеРекв2 = "",_ТекстРекв2 = "",_ВладелецСправочника = "") Экспорт

....

		СписокЗн.Добавить(ЗначениеСсылка, ?(_СначалаСкобки, ЗначениеРекв2 + " " + ЗначениеРекв1, ЗначениеРекв1 + " " + ЗначениеРекв2));     
		
	КонецЦикла;
	Возврат СписокЗн;
КонецФункции //
...Показать Скрыть
3. Дмитрий (mdmytro) 28.10.11 10:48
только параметру _СначалаСкобки лучше присвоить значение по умолчанию, и отодвинуть в конец параметров, чтобы при вызове функции каждый раз не указывать.
Функция ПолучитьСписокОкончаниеВводаТекста(_НазваниеСправочника,_Текст,_СначалаСкобки,_НазваниеРекв1,_НазваниеРекв2 = "",_ТекстРекв2 = "",_ВладелецСправочника = "")

Заменить на

Функция ПолучитьСписокОкончаниеВводаТекста(_НазваниеСправочника,_Текст,_НазваниеРекв1,_НазваниеРекв2 = "",_СначалаСкобки = Истина,_ТекстРекв2 = "",_ВладелецСправочника = "")
4. Дмитрий (mdmytro) 28.10.11 12:08
(2) anosin, Пожелание учел в публикации
5. Алексей Константинов (alexk-is) 28.10.11 13:44
6. Петр Чечин (stoptime) 30.10.11 09:55
Может вместо НазваниеРекв2 использоват список желаемых реквизитов, как то боле универсально должно получится.
7. Дмитрий (mdmytro) 30.10.11 10:33
(6) stoptime, Я над этим думал, но при выводе списка остальные реквизиты останутся не видны.
8. Дмитрий (mdmytro) 30.10.11 10:52
9. Марк (marku) 30.10.11 21:12
Спасибо за функцию
немного подправил, чтобы поиск по наименованию проходил, где встречается строка поиска
буду у себя использовать
//******
Для каждого ТекСтр Из ПоляВводПоСтроке Цикл
                                   Если (ТекСтр.Имя = "Наименование") Тогда
											   СтрокаПараметра = """%"""+"+&Текст+"+"""%""";
                                               Запрос.Текст = Запрос.Текст + "
                                               |  " + ?(ПоляВводПоСтроке.Индекс(ТекСтр) > 0," ИЛИ ","(")+   "Спр."+ ТекСтр.Имя +" ПОДОБНО "+СтрокаПараметра    //  "ПОДСТРОКА(Спр." + ТекСтр.Имя + ", 1, &КвоСимволов) = &Текст"
                                               +  ?(ПоляВводПоСтроке.Индекс(ТекСтр) = (ПоляВводПоСтроке.Количество() - 1),")","");

                                    ИначеЕсли  (ТекСтр.Имя = "Код" И Строка(Метадан.ТипКода) = "Строка")

                                               ИЛИ (ТекСтр.Имя <> "Код" И ТипЗнч(Метадан.Реквизиты[ТекСтр.Имя].Имя) = Тип("Строка")) Тогда
//********

...Показать Скрыть
Novoross11; +1 Ответить
10. Michael Smith (opiumdx) 31.10.11 07:17
11. Alex Misanets (Misanets) 31.10.11 10:29
а я бы просто буху сказал НЕТ.
12. Дмитрий (mdmytro) 31.10.11 10:57
(11) Misanets, У нас в одном справочнике часто встречается одна и та же статья по наименованию, но с разным значением определенного реквизита. И поэтому стандартный ввод по строке дает 5-6 одинаковых наименований в списке. Поэтому для того чтобы узнать какое именно это наименование необходимо было только открывать форму. А если учесть, что этот реквизит участвует практически в половине документов... Моя функция значительно увеличила скорость набора. А почему сразу НЕТ? Частный случай я нарисовал быстро, с универсальным пришлось повозиться. НЕТ можно аргументировать если либо такой возможности нет у программы,либо время на разработку не сопоставимо с эффектом, либо нет времени у программиста, либо программист не компетентен.