Динамическая фильтрация в справочнике при вводе наименования

04.07.12

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

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

Предлагаю способ, наверное уже избитый, но в поиске не нашел.

Смысл решения, практически тоже самое что предложено Ёпрст. На практике это использую почти год.

Фильтрация происходит по набранным символам разделенных пробелами. Сортировка происходит по первому набору символов (до пробела)
Требования: 1С++
Версия: SQL (с DBF сто лет не работал, наверное что-то нужно поменять :) )
Ограничения. Если установлен отбор из диалога 1С, фильтрация не работает (скорее всего я не разобрался как программно снимать отбор, надеюсь в комментах подскажут)

Код приведенный ниже, добавить в нужную форму.

У меня в ГМ при начале работы системы присвоена глРС = СоздатьОбъект("ODBCRecord");
и глСтрокаРазрешенныхСимволов = " .,-+*/\_0123456789абвгдеёжзийклмнопрстуфхцчшщъыьэюяabcdefghijklmnopqrstuvwxyz";
Их необходимо создать и объявить для работы данного алгоритма. 

 

Перем СтрокаСимволов;

Перем ТекФлагИерархическогоСписка;
Перем СпЗн;
Перем ОтборУстановлен;

Процедура ПриУстановкеОтбора(ТипОтбора,ЗначениеОтбора)
   
ОтборУстановлен = ТипОтбора;
КонецПроцедуры

Функция
ПолучитьСписокЭлементов(ВидСправочника, СтрокаСимволов)
   
СтрДляПозиции = СтрокаСимволов;
   
Пробел = Найти(СтрДляПозиции," ");
    Если
Пробел>0 Тогда
       
СтрДляПозиции = Лев(СтрДляПозиции,Пробел-1);
    КонецЕсли;
   
ТекстЗапроса = "
    |SELECT ID [Ссылка $Справочник."
+ВидСправочника+"]
    |   , case when CHARINDEX ('"
+СтрДляПозиции+"', "+ВидСправочника+".DESCR)=0 then 999 else CHARINDEX ('"+СтрДляПозиции+"', "+ВидСправочника+".DESCR) end ПозицияВСтроке
    |FROM $Справочник."
+ВидСправочника+" AS "+ВидСправочника+" With (NOLOCK)
    |WHERE ("
+ВидСправочника+".ISFOLDER >= 0)
    |"
;
    Если
ПустаяСтрока(СтрокаСимволов)=0 Тогда
       
СтрДляЗапроса = "
        |AND ("
+ВидСправочника+".DESCR LIKE '%"+СтрЗаменить(СтрокаСимволов," ","%') AND ("+ВидСправочника+".DESCR LIKE '%");
       
СтрДляЗапроса = СтрДляЗапроса + "%')
        |"
;
       
ТекстЗапроса=ТекстЗапроса+СтрДляЗапроса;
    КонецЕсли;
   
ТекстЗапроса = ТекстЗапроса + "
    |ORDER BY ПозицияВСтроке, "
+ВидСправочника+".DESCR
    |"
;
   
глРС.ВыполнитьИнструкцию(ТекстЗапроса, СпЗн);
    Возврат
СпЗн;
КонецФункции

Процедура
ПриНажатииКнопкиКлавиатуры(_код, , , , _симв, ФСО)
    Если
Лев(Форма.ТекущаяКолонка(),12)="Наименование" Тогда
        Если
ПустоеЗначение(ОтборУстановлен)=0 Тогда
           
УстановитьОтбор("","");
            Возврат;
        КонецЕсли;
        Если (
=1) или (=1) или (=1) Тогда
           
ФСО=1;
            Возврат;
        КонецЕсли;
        Если
_код = 27 Тогда
            Если СтрокаСимволов="" Тогда 
                Фсо = 1
                Возврат;
            КонецЕсли;

            КурсорНаЭлементе = ТекущийЭлемент();
           
СтрокаСимволов = "";
           
Форма.Наименование.Заголовок("Наименование");
            
СпЗн.УдалитьВсе();
            ИспользоватьСписокЭлементов();
            
ИерархическийСписок(ТекФлагИерархическогоСписка,1);
            Попытка
               
АктивизироватьОбъект(КурсорНаЭлементе);
            Исключение
            КонецПопытки;
           
ФСО = 1;
            Возврат;
        ИначеЕсли
_код = 8 Тогда
           
СтрокаСимволов = Лев(СтрокаСимволов, СтрДлина(СтрокаСимволов)-1);
        ИначеЕсли
_симв="" Тогда
           
ФСО = 1;
            Возврат;
        ИначеЕсли
Найти(глСтрокаРазрешенныхСимволов, Нрег(_симв))>0 Тогда
           
СтрокаСимволов = СтрокаСимволов + _симв;
        Иначе
           
ФСО = 1;
            Возврат;
        КонецЕсли;
       
Форма.Наименование.Заголовок("Наименование ("+СтрокаСимволов+")");
       
СпЗн = ПолучитьСписокЭлементов("Номенклатура", СтрокаСимволов);
       
ИспользоватьСписокЭлементов(СпЗн);
       
ИерархическийСписок(0,0);
       
ФСО = 0;
    КонецЕсли;
КонецПроцедуры

Процедура
ПриОткрытии()
    ТекФлагИерархическогоСписка = ВосстановитьЗначение("ТекФлагИерархическогоСпискаНоменклатура");
    СтрокаСимволов = "";
    СпЗн = СоздатьОбъект("СписокЗначений");
КонецПроцедуры

Процедура ПриСменеИерархии(Способ)
    ТекФлагИерархическогоСписка = Способ;
КонецПроцедуры

Процедура ПриЗакрытии()
    СохранитьЗначение("ТекФлагИерархическогоСпискаНоменклатура",ТекФлагИерархическогоСписка);
КонецПроцедуры

См. также

"Виртуальный" работник на платформе 1C v7.7

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

В статье расписаны примеры из жизни использования "Виртуального" работника. Разобраны вопросы, возникающие при работе с ним.

28.11.2021    1544    user707242_Gold_karas    18    

5

Асинхронное программирование в 1с77 без внешних компонент. Обратные вызовы.

Механизмы платформы 1С Платформа 1С v7.7 Абонемент ($m)

Пример построения программного кода для достижения функционала обратных вызовов (call back) во внешних обработках исключительно штатными средствами. Тестировалось на платформе 1с77 релиз 027. Конфигурация значения не имеет.

1 стартмани

06.10.2018    7443    Vortigaunt    5    

11

Особенности разделения объектной модели документа и базы данных в 1С 7.7. Забавный глюк

Механизмы платформы 1С Оперативный учет 7.7 Абонемент ($m)

Когда занимаешься разработкой в среде 1С, редко задумываешься о том, что программным кодом ты работаешь с объектной моделью базы данных, а не с самой базой данных. И что это вообще разные вещи. Ты создаешь объекты: документы и справочники, записываешь их - и в базе данных появляются соответствующие записи. Это настолько привычно, что когда сталкиваешься с нетипичным поведением платформы, первым делом думаешь: надо протестировать базу, она битая. В этой статье я хочу разобрать одну интересную ситуацию, которая как раз демонстрирует такое поведение. Описанная ниже ситуация воспроизводится как в файловом, так и в клиент-серверном (SQL) варианте. Тестировалось на версии платформы 1с77 релиз 027.

1 стартмани

16.05.2018    10124    Vortigaunt    26    

5

Использование классов .Net в 1С для новичков

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

Руководство для новичков. Написав статью http://infostart.ru/public/238584/, я понял, что многие не понимают того, что написано. Поэтому в этой статье постараюсь более подробно остановиться на азах и без кода на вражеском языке (C#)

27.01.2016    93944    Serginio    116    

188

Все про картинки в 1С 7.7, ну или почти все...

Механизмы платформы 1С Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

В 1С 8 наличие картинок товаров предусмотрено изначально, а в 7.7 такого нет. Проблема существует и ее исправляют, но это, как правило, частные случаи, касающиеся, например, печати прайса http://infostart.ru/public/289876/ , показу картинок в справочнике номенклатура http://infostart.ru/public/17125/, файловый менеджер картинок товара http://infostart.ru/public/15239/ или просто конфигурации работы с картинками http://infostart.ru/public/21142/ (не стремился дать полный обзор, поэтому не попавшие не обижайтесь :). Что не устроило – информация разбросана по статьям, необходимость дополнительно напрягаться, чтобы это заработало. Здесь я попытался собрать все «до кучи», а так же дать необходимые ссылки для желающих «копнуть вглубь».

1 стартмани

18.11.2014    43975    95    kitminsk    18    

20

ЗаполнитьЗначенияСвойств - заставляем работать в 7.7

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

Если вы используете в работе 1С:Предприятие 8.х, то наверняка знакомы и с замечательной системной процедурой, как ЗаполнитьЗначенияСвойств(). Ее использование помогает значительно упростить написание программного кода в ряде случае, делает его (код) более наглядным и простым. Но что же делать тем, кто до сих пор использует (постоянно или иногда) 1С:Предприятие 7.7?

24.07.2014    23720    tomvlad    5    

14

Работа с бинарными файлами в 1С 7.7

Механизмы платформы 1С Платформа 1С v7.7 Конфигурации 1cv7 Россия Абонемент ($m)

Описание принципов и набор инструментов для работы с двоичными данными в 1С 7.7. Примеры во вложениях.

1 стартмани

16.05.2012    31754    100    dusha0020    8    

22
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Модератор раздела 03.07.12 16:59 Сейчас в теме
Плюсанул.
Тема интересна, хоть я от 77 и 1С++ отошел.

Не описан глРС, будет ошибка.
Дбф? скуль?
2. maxpiter 147 04.07.12 00:35 Сейчас в теме
(1)Поправил замечания в описании.
Работаю с SQL, но для DBF алгоритм такой же, возможно код запросов чуток другой.

p.s. Спасибо за +, от artbear плюс вообще приятно :)
3. gutentag 253 04.07.12 10:18 Сейчас в теме
4. Ёпрст 1063 04.07.12 10:56 Сейчас в теме
Только вот по первым символам и так есть поиск в форме списка справочника..
6. maxpiter 147 04.07.12 10:59 Сейчас в теме
(4) вот вредный, видно же что ищет не по первым символам, а сортирует по первым
7. Ёпрст 1063 04.07.12 11:03 Сейчас в теме
(6)
1.глСтрокаРазрешенныхСимволов - это что за зверь такой ?
2. не видно вводимых символов на форме (лучше уж тогда через ДобавитьАтрибут добавлять поле, как у A'Dirks-а)
3. запрос, на сколько я понял выполняется при каждом нажатии на кнопку клавиатуры, если это не эескейп, бекспейс ?
це-же медленно на большом спраочнике, лучше или начиная с 3-4 символа, или задержку втыкаить, как в софтпоинте сделали
9. maxpiter 147 04.07.12 11:19 Сейчас в теме
(7)
1. упустил
глСтрокаРазрешенныхСимволов = " .,-+*/\_0123456789абвгдеёжзийклмнопрстуфхцчшщъыьэюяabcdefghijklmn­opqrstuvwxyz";
набор символов по которым можно выполнять отбор.
2. видно, они набираются в поле "Наименование"
3. на справочнике более чем 5к элементов, примлемо. Действительно думал, чтобы начать фильтрацию с 3 символа, но пришел к выводу, что лучше с первого.
Разве что, при наборе первого символа искать не все вхождения а именно только те у которыех он первый, но тут будут не очень нормальные варианты с ё, й, ы, ь, ъ.

(8)
спасибо, так пробовал, вываливалось с ошибкой, а вот УстановитьОтбор("",""); только сейчас предположил и получилось, хотя второй параметр и написано что необязательный.

изменил в коде и описание.
10. Ёпрст 1063 04.07.12 11:47 Сейчас в теме
(9) ааа...
т.е "МАМА Мыла РАМУ" уже не канает для поиска ?
жаль..
11. maxpiter 147 04.07.12 12:57 Сейчас в теме
(10) почему не канает-то???? где сказано что не канает?
уже столько написал, давно бы попробовал :)
5. Ёпрст 1063 04.07.12 10:57 Сейчас в теме
8. Ёпрст 1063 04.07.12 11:05 Сейчас в теме
>>>как программно снять отбор ?

УстановитьОтбор("");
12. maxpiter 147 04.07.12 13:00 Сейчас в теме
+11 SQL ищет без учета регистра, если ему конкретно не скажут что нужно учитывать регистр.
13. Ёпрст 1063 04.07.12 13:04 Сейчас в теме
(12) при чем тут то, что ищет скуль ?

Ты сам ограничил набор вводимых символов - у тебя заглавные символы ввести нельзя.

:))))
16. maxpiter 147 04.07.12 13:08 Сейчас в теме
(13) а заглавные ввести нельзя, потому что shift, alt и ctrl вообще из поиска исключаю
14. Ёпрст 1063 04.07.12 13:06 Сейчас в теме
А ёпт.. Нрег не заметил в Найти..
Забираю слова обратно
15. maxpiter 147 04.07.12 13:07 Сейчас в теме
(14) попробуй уже а? и напиши че нить хорошее :)
17. Ёпрст 1063 04.07.12 13:08 Сейчас в теме
И это, ставить не буду - тёткам удобно видеть весь справочник, им и штатный поиск по первым символам в форме списка устраивает, причем, он штатно "множественный", т.е нашли первое совпадение, потом можно "бегать" по форме списка вверх вниз по этим совпадениям - привыкли так ужо.
19. maxpiter 147 04.07.12 13:11 Сейчас в теме
(17) мои тоже привыкли, но когда в списке ароматизаторов около 200 штук и все начинаются Ароматизатор и только потом различие, то проще набрать аром лимон :) и уже бегать глазками по оставшемуся десятку.
>> привыкли так ужо. - привычка дело может быть навязанной, причем в данном случае 1С :)
18. Ёпрст 1063 04.07.12 13:10 Сейчас в теме
Хотя..ща прикручу, "послушаю" народное мнение..
:)
maxpiter; +1 Ответить
60. maxpiter 147 26.07.12 10:22 Сейчас в теме
(18)(59) какой результат тестов, пользуются юзвери? :)
61. Dolly_EV 269 31.07.12 03:51 Сейчас в теме
(60) из отпуска только сегодня, но судя по тому, что вопросов нет - пользуются, и видимо понравилось))
20. Ёпрст 1063 04.07.12 13:13 Сейчас в теме
Это ..еще недочет:

в ПриОткрытии, нужно проверить, что флагиерархического просмотра восстановлен..иначе болт
21. maxpiter 147 04.07.12 13:14 Сейчас в теме
23. Ёпрст 1063 04.07.12 13:20 Сейчас в теме
(21) этого нету

Процедура ПриОткрытии()
ТекФлагИерархическогоСписка = ВосстановитьЗначение("ТекФлагИерархическогоСпискаНоменклатура");

вот тут болт, ибо нет еще сохраненного "ТекФлагИерархическогоСпискаНоменклатура" при открытии при первом открытии, да и при закрытии сохранять нечего, если иерархию не меняли.
22. Ёпрст 1063 04.07.12 13:18 Сейчас в теме
СпЗн = ПолучитьСписокЭлементов("Номенклатура"<<?>>);
{Справочник.Номенклатура.ФормаСписка.ФормаСписка.Модуль(100)}: Недостаточно фактических параметров
При проверке модуля обнаружены синтаксические ошибки!
24. maxpiter 147 04.07.12 13:28 Сейчас в теме
(22) СпЗн = ПолучитьСписокЭлементов("Номенклатура",СтрокаСимволов);
(23) согласен, если пустое значение после ВосстановитьЗначение, то нужно получить текущее
25. Ёпрст 1063 04.07.12 13:33 Сейчас в теме
(24) :)

Это.. при нажатии Эскейп, нужно проверить, если строка символов не пустая (или было уже нажатия и потом удалили символы, короче, что уже есть использоватьсписокэлементов), то ФСО нужно делать = 0, а не 1, иначе справочник закроется.
26. Ёпрст 1063 04.07.12 13:38 Сейчас в теме
ну и это, чариндекс выкинуть из селекта и запихать в ордербай
27. maxpiter 147 04.07.12 13:46 Сейчас в теме
28. Ёпрст 1063 04.07.12 13:46 Сейчас в теме
(27) дело в быстродействии
29. maxpiter 147 04.07.12 13:54 Сейчас в теме
(28) ммм, вот это аргумент, в данном случае каждая миллисекунда дорога :)
30. Ёпрст 1063 04.07.12 14:00 Сейчас в теме
И это.. фсо всё же поправь для Esc
32. maxpiter 147 04.07.12 14:02 Сейчас в теме
(30) код который я представил у меня в форме списка, в форме выбора дейстивтельно есть небольшая добавочка
Если _код = 27 Тогда
Если СтрокаСимволов="" Тогда
Фсо = 1;
Возврат;
КонецЕсли;
....
31. maxpiter 147 04.07.12 14:00 Сейчас в теме
+29 хотя у меня case в select работает все таки чуток быстрее, может быть кеш.
Отличие ооочень мизерное. Оставлю как есть :)
33. maxpiter 147 04.07.12 14:22 Сейчас в теме
Вообще то. зная имя отбора и значение отбора, можно сгенерить условие фильтрации с учетом отбора :) и будет вообще хорошо
34. Dolly_EV 269 05.07.12 15:38 Сейчас в теме
(0) CHARINDEX для 1SQLite (dbf) чем заменить? :-((
35. Dolly_EV 269 05.07.12 16:37 Сейчас в теме
+(34) Мдаа... без CHARINDEX на DBF нелогично сортировка получается, юзер не поймет :-(
37. maxpiter 147 05.07.12 17:09 Сейчас в теме
36. maxpiter 147 05.07.12 17:06 Сейчас в теме
41. Dolly_EV 269 06.07.12 05:48 Сейчас в теме
(36) 1.0.2.4 (уже 1.0.2.6)
Вместо чариндекс можно конечно огород нагородить с тз и Найти(СтрДляПозиции,Наименование), но скорость потеряется :-(
42. Ёпрст 1063 06.07.12 09:11 Сейчас в теме
(41) юзай запрос на фоксе - он быстрее и там есть аналог чариндекса - AT()
43. Dolly_EV 269 06.07.12 09:49 Сейчас в теме
(42) а с монопольностью там нормально? и пример бы в студию
44. Ёпрст 1063 06.07.12 10:11 Сейчас в теме
(43) нормально.
Ставишь решение от hogik и привет
48. Dolly_EV 269 06.07.12 10:58 Сейчас в теме
(44) ADS муторно :-(... хотя в 2009-м он меня реально спас. Сейчас решил по периферийкам - по дорастанию до критической массы - переводить на SQL
50. Ёпрст 1063 06.07.12 11:09 Сейчас в теме
38. dumal 05.07.12 23:55 Сейчас в теме
Хорошая вещь. Можно внедрить в тех местах, где народ пользуется 7.7 и даже не планирует переходить на 8ку. Жаль только, sql...
39. maxpiter 147 05.07.12 23:59 Сейчас в теме
(38) в DBF пока уперлось в CHARINDEX, но может это все таки решаемо?
40. dumal 06.07.12 00:13 Сейчас в теме
Да, я прочитал в комментариях. Решения у меня нет :(
45. Ёпрст 1063 06.07.12 10:31 Сейчас в теме
+44
|select id as [Элем $Справочник.Номенклатура]
|,iif(at('туф',lower(descr))=0,999,at('туф',lower(descr))) as вася
|from $Справочник.Номенклатура спр
|where 
|(lower(descr) like '%туф%') 
|and 
|(lower(descr) like '%жен%')
|order by вася
Показать
46. maxpiter 147 06.07.12 10:38 Сейчас в теме
47. Ёпрст 1063 06.07.12 10:45 Сейчас в теме
(46) я твой код переделал..
мне лень даже 1cqa открыть
49. Dolly_EV 269 06.07.12 11:00 Сейчас в теме
(45) дрова для Фокса - достаточно библиотек вот отсюда http://www.1cpp.ru/forum/YaBB.pl?num=1210677779/30 ?
53. Dolly_EV 269 06.07.12 13:05 Сейчас в теме
(45) В ПриОткрытии():
		СтрСоединение = "Provider=VFPOLEDB.1;Data Source=" + КаталогИБ() + ";Exclusive=Yes;Mode=ReadWrite;Collating Sequence=MACHINE";
		ДБ = СоздатьОбъект("OLEDBData");
		Рез = ДБ.Соединение(СтрСоединение);
		лЗапросФокс = ДБ.СоздатьКоманду();
		лЗапросФокс.Выполнить("EXECSCRIPT('SET ANSI OFF')");  
		лЗапросФокс.Выполнить("EXECSCRIPT('SET REFRESH TO 0,-1')");
		лЗапросФокс.Выполнить("Exec('SET TABLEVALIDATE TO 0')");
		лЗапросФокс.Отладка(1);

ТекстЗапроса:
SELECT
	ID [Ссылка $Справочник.Номенклатура],
	iif(at('в',lower(Номенклатура.DESCR))=0,999,at('в',lower(Номенклатура.DESCR))) AS ПозицияВСтроке
FROM
	Справочник.Номенклатура AS Номенклатура
WHERE
	(Номенклатура.ISFOLDER >= 0)

AND (lower(Номенклатура.DESCR) LIKE '%в%')

ORDER BY ПозицияВСтроке,Номенклатура.DESCR
Показать


лТЗ=лЗапросФокс.ВыполнитьИнструкцию(ТекстЗапроса);
{Справочник.Номенклатура.ФормаСписка.Основная.Модуль(101)}: FAILED! ICommandText::Execute(): Too many arguments.

Где засада?
54. Dolly_EV 269 06.07.12 13:14 Сейчас в теме
(53) все, разобрался.. ВЗЛЕТЕЛО! УРА! осталось только hogika прикрутить, чтобы в монопольном взлетело
P.S. Теперь и монопольно - спасибо hogik'у
55. maxpiter 147 06.07.12 13:16 Сейчас в теме
(54) при наборе текста, скорость фильтрации приемлемая?
56. Dolly_EV 269 06.07.12 13:30 Сейчас в теме
(55) Приемлемо (Номенклатура 25K), причем на dbf через фокса - заметно бастрее получилось, чем через SQLite. На SQL - медленнее, но там у меня еще заморочка с получением остатков.

Только стоит все-таки наверно с третьего символа начинать фильтровать ?
и еще: для Esc при НЕпустой СтрокаСимволов надо ФСО=0 - а то форма выбора закрывается (30)
57. maxpiter 147 06.07.12 14:17 Сейчас в теме
(56) >> Только стоит все-таки наверно с третьего символа начинать фильтровать ?
Тоже не совсем логично может получиться.
В качестве идеи для обсуждения. Сделать как в поисковиках.
При открытии выдавать пустой справочник, при наборе выводить то что нашлось скажем TOP 20 пока не наберет больше 3х символов. Как больше трех набрал выводит все.
59. Dolly_EV 269 06.07.12 15:06 Сейчас в теме
(56) Пока как есть оставил, пусть юзеры потестят, потом расспросим
52. Dolly_EV 269 06.07.12 11:50 Сейчас в теме
(51) ааа, я это как-то упустил :-(( думал, ты имеешь ввиду вот эту: http://infostart.ru/public/15211/
58. maxpiter 147 06.07.12 14:18 Сейчас в теме
+57 ну понятно, что эта опция для каждого может индивидуально настраиваться в настройках пользователя.
62. Иваныч 23 17.01.23 12:44 Сейчас в теме
Плюс поставил, сколько раз так бывает в прайсах, да и наименования чаще всего скопировал/вставил при создании номенклатуры. "Фильтр масляный", а кто-то напишет "Масляный фильтр"
maxpiter; +1 Ответить
Оставьте свое сообщение