Универсальная функция отбора в справочниках

25.05.09

Разработка - Инструментарий разработчика

Программисту на заметку:
Отбор элементов справочника по строковым реквизитам через прямой запрос. Универсально, для SQL и DBF. Работает очень быстро!

Для 7.7

Скачать файлы

Наименование Файл Версия Размер
Отбор по справочнику
.1243244290 40,00Kb
377
.1243244290 40,00Kb 377 Скачать

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

 

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

 

 


 

//Функция возвращает первые (все) элементы справочника, найденные по подстроке, в списоке значений

//Справочник = Идетинтификатор справочника (строка)

//ПолеПоиска = Реквизиты, по которым делать поиск (строка, разделенная запятыми)

//Метод = Метод поиска (1-поиск по вхождению, 2-поиск по первым символам, 3-поиск по последним символам)

//Искомая строка = Что ищем (строка)

//КвоЭлементов = кол-во, указывающий сколько элементов возвращать (10 - вернуть первые 10 элементов, удовлетворяющий условию, 0 - вернуть все элементы)

Функция глФильтрСправочника(Справочник,ПолеПоиска="",Метод=1,Знач ИскомаяСтрока="", КвоЭлементов=0,спРезультатов="") Экспорт

Если ТипЗначенияСтр(спРезультатов)<>"СписокЗначений" тогда спРезультатов=СоздатьОбъект("СписокЗначений");КонецЕсли;

Если ПустоеЗначение(ПолеПоиска)+ПустоеЗначение(ИскомаяСтрока)<>0 Тогда Возврат спРезультатов; КонецЕсли;

   спПолейПоиска=СоздатьОбъект("СписокЗначений");

   спПолейПоиска.ИзСтрокиСРазделителями(""""+СтрЗаменить(ПолеПоиска,",",""",""")+"""");

для х=1 по спПолейПоиска.РазмерСписка() Цикл

Если Врег(спПолейПоиска.ПолучитьЗначение(х))=Врег("Наименование") Тогда

спПолейПоиска.УстановитьЗначение(х,"спр.DESCR");

ИначеЕсли Врег(ПолеПоиска)=Врег("Код") Тогда

спПолейПоиска.УстановитьЗначение(х,"спр.Code");

Иначе

спПолейПоиска.УстановитьЗначение(х,"$Справочник."+Справочник+"."+спПолейПоиска.ПолучитьЗначение(х));

КонецЕсли;

КонецЦикла;

   МИК=СоздатьОбъект("MetaInfoClasses");

Если МИК.ЭтоSQL_Версия()=1 тогда

НоЛок=" (NOLOCK)";

Запрос = СоздатьОбъект("ODBCRecordset");

   Иначе

Если МонопольныйРежим()=1 Тогда

Возврат спРезультатов;

КонецЕсли;

НоЛок="";

База = СоздатьОбъект("OLEDBData");

Соединение ="

|Provider=VFPOLEDB.1;

|Data Source=" + КаталогИБ() + ";

|Mode=Read;

|";

Рез = База.Соединение(Соединение);

Запрос = База.СоздатьКоманду();

КонецЕсли;

   ИскомаяСтрока=Врег(СокрЛП(ИскомаяСтрока));

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

|SELECT"+?(КвоЭлементов=0,""," Top "+КвоЭлементов)+"

| спр.ID as [Элемент $Справочник."+Справочник+"]

|FROM

| $Справочник."+Справочник+" as спр"+НоЛок+"

|Where

|"+?(Метаданные.Справочник(Справочник).КоличествоУровней>1,"спр.ISFOLDER=2 AND","");

для х=1 по спПолейПоиска.РазмерСписка() Цикл

ТекПоле=спПолейПоиска.ПолучитьЗначение(х);

Если Метод=1 Тогда

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

|UPPER("+ТекПоле+") Like &apos;%&apos; + :Стр + &apos;%&apos;";

ИначеЕсли Метод=2 Тогда

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

|UPPER(Left(LTRIM("+ТекПоле+"),"+СтрДлина(ИскомаяСтрока)+"))=:Стр";

ИначеЕсли Метод=3 Тогда

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

|UPPER(RIGHT(RTRIM("+ТекПоле+"),"+СтрДлина(ИскомаяСтрока)+"))=:Стр";

КонецЕсли;

Если х<спПолейПоиска.РазмерСписка() тогда ТекстЗапроса=ТекстЗапроса+" OR"; КонецЕсли;

КонецЦикла;

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

|ORDER BY "+спПолейПоиска.ПолучитьЗначение(1);

   Запрос.УстановитьТекстовыйПараметр("Стр", ИскомаяСтрока);

Если МИК.ЭтоSQL_Версия()=1 тогда

Запрос.ВыполнитьИнструкцию(ТекстЗапроса,спРезультатов);

   Иначе

ТЗ=Запрос.ВыполнитьИнструкцию(ТекстЗапроса);

ТЗ.Выгрузить(спРезультатов,,,"Элемент");

КонецЕсли;

Возврат спРезультатов;

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

 

 

 

 


 

 

 

Требует 1С++ (http://www.1cpp.ru/index.php/Download) - обязательно.

И Microsoft OLE DB Provider для DBF баз (http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=e1a87d8f-2d58-491f-a0fa-95a3289c5fd4).

Как внедрить:

скачать 1С++, компоненту положить в каталог ИБ (или программы)

В процедуре ПриНачалеРаботыСистемы прописать

Попытка

        ЗагрузитьВнешнююКомпоненту(КаталогИБ()+"1CPP.dll");

Исключение
        Сообщить("Ошибка при загрузке ВК 1CPP.dll");
КонецПопытки;

 

 

Добавить в глобальный модуль указанную выше функцию.

А дальше можно использовать так:

Простейший пример: На форме списка справочника товаров/клиентов добавлем поле ввода "ФильтрСтр" - тип строка и две кнопки - "Фильтр()" и "ОтменаФильтра()"

В модуль формы добавлем процедуры:

Процедура Фильтр()

ИерархическийСписок(0);

ИспользоватьСписокЭлементов(глФильтрСправочника(Вид(),"Наименование,ПолнНаименование",1,ФильтрСтр));

Форма.Обновить();

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

Процедура ОтменаФильтра()

ИспользоватьСписокЭлементов();

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

 

Это простейший вариант использования данной функции.

Есть еще вариант - в отчеты по продажам/остаткам и тп - добавляем такое же поле ввода, а в запрос добавлем условие

что-то типа: Условие (Товар в спСтрФильтр)

где спСтрФильтр=глФильтрСправочника("Номенклатура","Наименование,ПолнНаименование",1,ФильтрСтр)

в итоге будем иметь возможность строить отчеты по всем товарам, где содержится например слово "шампунь"...

 

А если еще прикрутить формекс - то можно отлавливать нажатия клавиш прямо в форме списка справочника и фильтровать на лету.

Например у себя использую такой код в форме списка (Внимание, код не универсален - "причесывайте" под себя):

Перем ПоискПоШтрихКоду, ВернутьИерархию, РежимПодбора;

Процедура ПриНажатииКнопкиКлавиатуры(КодКлавиши,Alt,Shift,Ctrl,Символ,ФСО)
    Если (Shift=1) и (Alt+Ctrl=0) и (КодКлавиши=90) Тогда
        РежимПодбора=1;
        ФСО=0;
        Возврат;
    КонецЕсли;
    Если РежимПодбора=1 Тогда
        Если КодКлавиши=90 Тогда
            ФСО=0;
            Возврат;
        КонецЕсли;
        Если (КодКлавиши<58) и (КодКлавиши>47) тогда
            ФСО=0;
            ПоискПоШтрихКоду=ПоискПоШтрихКоду+Симв(КодКлавиши);
            Если ИерархическийСписок()=1 тогда
                ВернутьИерархию=1;
                ИерархическийСписок(0);
            КонецЕсли;
            ИспользоватьСписокЭлементов(глФильтрСправочника("ТМЦ","ШтрихКод,КодЯщика",3,ПоискПоШтрихКоду,50)); Форма.Обновить();
        ИначеЕсли (КодКлавиши<106) и (КодКлавиши>95) тогда
            ФСО=0;
            Если ИерархическийСписок()=1 тогда
                ВернутьИерархию=1;
                ИерархическийСписок(0);
            КонецЕсли;
            ПоискПоШтрихКоду=ПоискПоШтрихКоду+Симв(КодКлавиши-48);
            ИспользоватьСписокЭлементов(глФильтрСправочника("ТМЦ","ШтрихКод,КодЯщика",3,ПоискПоШтрихКоду,100)); Форма.Обновить();
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Процедура ПриОтжатииКнопкиКлавиатуры(КодКлавиши,Alt,Shift,Ctrl,Символ,ФСО)
    Если (КодКлавиши=90) и (РежимПодбора=1) Тогда
        РежимПодбора=0;
        ТекЭлемент=ТекущийЭлемент();
        ПоискПоШтрихКоду="";
        ИспользоватьСписокЭлементов();
        Если ВернутьИерархию=1 тогда ИерархическийСписок(1); КонецЕсли;
        АктивизироватьОбъект(ТекЭлемент);
    КонецЕсли;   
КонецПроцедуры

В моем случае пользователь Нажимает Shift - затем клавишу "Я" и при зажатой клавишу "Я" набирает последние цифры штрихкода  - справочник мгновенно фильтруется. При отжатии клавиши "Я" фильтр сбрасывается, а курсор активизируется на элемент, который был активен при фильтре - мои юзеры просто в восторге... :)

 

В качестве демонстрации прикладываю обработку, демонстрирующую работу функции.

 

Статья расчитана в первую очередь на тех, кто хочет быстро попробовать - что же это за зверь - "прямой запрос".

 

 

См. также

Консоль запросов

Инструментарий разработчика Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Консоль запросов к базе SQL, не требующая внешних компонент

10 стартмани

29.04.2015    21559    54    Gvozdod    8    

14

StartManager 1.4 - Развитие альтернативного стартера

Инструментарий разработчика Платформа 1С v7.7 Платформа 1С v8.3 Абонемент ($m)

Очередная редакция альтернативного стартера, являющегося продолжением StartManager 1.3. Спасибо всем, кто присылал свои замечания и пожелания, и тем, кто перечислял финансы на поддержку проекта. С учетом накопленного опыта, стартер был достаточно сильно переработан в плане архитектуры. В основном сделан упор на масштабируемость, для способности программы быстро адаптироваться к расширению предъявляемых требований (т.к. довольно часто просят добавить ту или иную хотелку). Было пересмотрено внешнее оформление, переработан существующий и добавлен новый функционал. В общем можно сказать, что стартер эволюционировал, по сравнению с предыдущей редакцией. Однако пока не всё реализовано, что планировалось, поэтому еще есть куда развиваться в плане функциональности.

1 стартмани

23.04.2014    165696    1864    Alexoniq    1596    

496

Tray Informer

Инструментарий разработчика Платформа 1С v7.7 Платформа 1С v8.3 Россия Абонемент ($m)

Согласитесь, что окно стандартное сообщений в 1С иногда приносит больше неудобств, чем пользы. И тем более разные "Предупредить"... Что с этим окном только не делают! Его отцепают от формы, делают маленьким, умудряются спрятать за границы экрана. А потом звонят программистам с претензией, что документ почему-то не проводится, отя ничего и не пишет. У вас такого не было? А вот у нас было и не раз )))

1 стартмани

04.09.2013    32877    61    O-Planet    78    

49

Изменение структуры баз 1С 7.7 без долгой реструктуризации. Часть 1. Справочники

Инструментарий разработчика Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

На днях встретил вопрос на форуме про возможность внесения изменений в конфигурацию без долгого сохранения в рабочей базе большого объема. Вот решил поделиться опытом, как это делал я. База у нас была объемом порядка 120 Гб. К базе обращался сайт в режиме 24/7, поэтому важно было быстро сохранять изменения и желательно без последующего монопольного запуска для восстановления индексов и процедур и без отключения пользователей от базы. Это первая часть статьи и посвящена она справочникам. С одной стороны - это самый простой объект, с другой стороны, именно про справочник спрашивалось на форуме. Если статья будет востребована, то я напишу аналогичные про документы, регистры и может еще что.

1 стартмани

13.08.2013    21197    Reptile    5    

35

v7.7 1CDialogControls: Инструмент в помощь разработчику на 7.7.

Инструментарий разработчика Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Давным давно, когда я еще плотно писал на 7.7 работа с формами была мучительной и неудобной. Приходилось каждый элемент выкладывать, выравнивать на форме ручками, прописывать код в модуле. Иногда при разработке очередной формы приходила в голову мысль: "а где-то я уже похожее делал..." и начинался мучительный поиск подходящего кода в своих запасах........

1 стартмани

21.02.2013    18029    35    MarSeN    14    

16

[Разработчику] Любая таблица значений в OLAP

Инструментарий разработчика Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Анализируем различные данные в 1С, используя OLAP-технологии со всеми прелестями. Т.е. наглядное отображение данных, быстрые расчеты, горизонтальные и вертикальные группировки любой вложенности, удобная фильтрация, Drag'n'Drop и ещё много приятных вещей от MS. Обработка на входе принимает практически любую таблицу значений (ТЗ в которой колонкам указаны типы значений, строка, число и т.п.), на выходе имеем на форме 1С сводную таблицу и график по этой ТЗ, с которой работаем, как и в Excel со сводной таблицей и диаграммой. Взял за основу разработку «OLAP Анализ счёта» ( http://infostart.ru/public/14964/ ) от JohnyDeath и переделал под любую ТЗ. Опционально используется «Прогресс бар для 1С 77» (http://infostart.ru/public/14061/ ) от Gmix.

1 стартмани

21.12.2012    36103    51    venger    7    

23

Библиотека кода 1С 7.7 (накопленная за 8 лет)

Инструментарий разработчика Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Весь код на 1С 7.7, собранный для повторного использования за 8 лет работы.

10 стартмани

25.11.2012    34957    248    adhocprog    51    

70
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Noy 1076 25.05.09 14:03 Сейчас в теме
P.S. В базах DBF будет работать только в разделенном режиме.
2. Ёпрст 1063 25.05.09 15:00 Сейчас в теме
(1) при помощи правки dbeng32 от hogik работает в любом...
3. Ёпрст 1063 25.05.09 15:02 Сейчас в теме
+2 всё это конечно хорошо, но вот решение, имхо , получшее:
http://www.1cpp.ru/forum/YaBB.pl?num=1211491690
4. Noy 1076 25.05.09 15:07 Сейчас в теме
(3) Не получшее, а лучше просто в разы!
Ясень пень, что моя маленькая заготовка с ней не сравниться, но как обучающий материал пойдет.
5. Ёпрст 1063 25.05.09 15:14 Сейчас в теме
(4) ну ясно...и это , к (2) тоже приглядись, если что на будующее...

6. Ёпрст 1063 25.05.09 15:14 Сейчас в теме
7. Noy 1076 25.05.09 15:20 Сейчас в теме
8. rasswet 82 27.05.09 08:54 Сейчас в теме
плюсанул за идею, сам видимо пользоваться не буду
9. Anics 27.05.09 10:21 Сейчас в теме
Что с этим делать?

МИК=СоздатьОбъект("MetaInfoClasses");
{C:\DOCUMENTS AND SETTINGS\АДМИНИСТРАТОР\РАБОЧИЙ СТОЛ\FN_FINDSPR.ERT(23)}: Неудачная попытка создания объекта (MetaInfoClasses)
10. Ёпрст 1063 27.05.09 10:25 Сейчас в теме
(9) загрузить ВК 1cpp.dll, для начала.
11. Anics 27.05.09 10:32 Сейчас в теме
1cpp.dll загружается, ошибка остается
12. Ёпрст 1063 27.05.09 10:33 Сейчас в теме
13. Anics 27.05.09 10:34 Сейчас в теме
14. Anics 27.05.09 10:47 Сейчас в теме
15. Ёпрст 1063 27.05.09 10:59 Сейчас в теме
16. Anics 27.05.09 11:07 Сейчас в теме
и с 3.0.1.22 не работает. Вк загружается, в примере же прописывется ее вызов.
17. Ёпрст 1063 27.05.09 11:12 Сейчас в теме
18. Ёпрст 1063 27.05.09 11:14 Сейчас в теме
(16) На закладке в 1с-предприятие, в Помощь о программе, появилась вкладка с ВК ?
19. Anics 27.05.09 11:21 Сейчас в теме
Заработала. Надо было Вк вызывать не в процедуре ПриОткрытии() обработки,
а в процедуре ПриНачалеРаботыСистемы().
20. Ёпрст 1063 27.05.09 11:24 Сейчас в теме
(19) это без разницы... можно хоть в Табло в самом предприятии написать строчку ЗагрузитьВнешнююКомпоненту("1cpp.dll") ...
21. anton.fly7 173 04.10.09 13:56 Сейчас в теме
Привет!
только начинаю упражняться с прямыми запросами...
скажите, в этой строке

|UPPER("+ТекПоле+") Like '%' + :Стр + '%'";

что должно быть написано? я так понел что косяк какой то...
22. anton.fly7 173 04.10.09 14:03 Сейчас в теме
23. anton.fly7 173 06.10.09 14:37 Сейчас в теме
почему то не ищет по наименованию по русским буквам... :?:
24. Noy 1076 06.10.09 15:10 Сейчас в теме
(23) у меня ищет...
база скульная? функцию покажи...
25. Noy 1076 06.10.09 15:15 Сейчас в теме
(23) Вижу на мисте уже ответили ;)
26. anton.fly7 173 06.10.09 15:17 Сейчас в теме
опять разобрался...
передавал на поиск маленькими буквами, а в запросе приводися к большим буквам
27. anton.fly7 173 06.10.09 15:18 Сейчас в теме
"UPPER(" + ТекПоле + ") Like '%' + :Стр" + Строка(i) + " + '%'"
28. Noy 1076 06.10.09 15:25 Сейчас в теме
"UPPER(" + ТекПоле + ") Like '%'" + ВРЕГ(Строка(i)) + "'%'"
29. selesta 17 18.06.12 01:47 Сейчас в теме
вещь супер, на 600 тыс. справочнике результат на 2 секунде
спасибо за простоту и универсальность!
30. selesta 17 03.07.12 14:04 Сейчас в теме
добавлю еще - не работает поиск с апострофом (одинарной кавычкой)
нужно заменить ее на 2
ИскомаяСтрока = СтрЗаменить(ИскомаяСтрока,"'","''");
31. Noy 1076 03.07.12 14:30 Сейчас в теме
(30) никто не совершенен. Баги в ПО будут всегда :)
32. LeshaUMC 25.07.21 20:52 Сейчас в теме
при выполнении выдает ошибку:
спрЗ = глФильтрСправочника(Вид(),"Диагноз",1,"К");
ТЗ=Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
{Глобальный модуль(3876)}: FAILED! ICommandText::Execute(): SQL: Column 'SP3578' is not found.
Но когда ищу в поле с названием по английски, например Diagnoz, то все работает.
Что может быть?
33. Noy 1076 02.09.21 11:44 Сейчас в теме
(32) Ошибка в функции. Похоже что неправильно разбирается второй параметр (имя поля). Если искать по двум и более полям - то должно работать.
Например:
спрЗ = глФильтрСправочника(Вид(),"Диагноз,Наименование",1,"К");
Оставьте свое сообщение