Находясь под впечатлением обработки по фильтрации справочников средствами SQL (см. статью), решил написать свою версию обработки с использованием только стандартных средств 1С для работы с любыми базами.
Для простоты решил отказаться от диапазонов. Осталось только два шаблона * и ?, так что реализовать оказалось несложно. Зато добавилась опция поиска с учетом либо без учета регистра символов.
Сначала я пошел более сложным путем, но затем хорошую идею подсказал Uno , за что ему спасибо. Что из всего этого получилось, смотрите ниже:
Вот как выглядит форма обработки:
А вот вторая закладка (результат):
Вот код модуля:
Перем ТекСправочник ,ТЗ ; Перем Последний ; Процедура ОбрТабл () Если Список .КоличествоСтрок ()>0 Тогда Предупреждение(Список .Реквизит ); КонецЕсли; КонецПроцедуры
//________________________________________________________ Функция ПроверкаСтроки (ПармСтрока ) Перем ВремСтрока , Результат ; ВремСтрока =ПармСтрока ; ТЗ .ВыбратьСтроки (); Результат =1 ; Пока ТЗ .ПолучитьСтроку ()=1 Цикл Если СтрДлина(ВремСтрока )=0 Тогда Результат =0 ; КонецЕсли; ТекПропуск =ТЗ .Пропуск ; ТекТекст =ТЗ .Текст ; ТекДлина =ТЗ .Длина ; Если ТекПропуск >0 Тогда //обрезаем ВремСтрока =Сред(ВремСтрока ,1 +ТекПропуск ); КонецЕсли; Если ТекПропуск <0 Тогда ТекПозиция =Найти(ВремСтрока ,ТекТекст ); Если ТекПозиция >0 Тогда ВремСтрока =Сред(ВремСтрока ,ТекПозиция +ТекДлина ); Иначе Результат =0 ; Прервать; КонецЕсли; Иначе //=0 Если Лев(ВремСтрока ,ТекДлина )=ТекТекст Тогда ВремСтрока =Сред(ВремСтрока ,1 +ТекДлина ); Иначе Результат =0 ; Прервать; КонецЕсли; КонецЕсли; КонецЦикла; Если (Последний =1 ) И (СтрДлина(ВремСтрока )>0 ) Тогда Результат =0 ; КонецЕсли; Возврат Результат ; КонецФункции
//________________________________________________________ Процедура ШаблонистыйШаблон () Состояние("Создание правил" ); ТекШаблон =СокрП(Стр ); Если РегистрСимволов =0 Тогда ТекШаблон =Врег(ТекШаблон ); КонецЕсли; ТекПропуск =0 ; Накопитель ="" ; Если ТипЗначениястр(ТЗ )="ТаблицаЗначений" Тогда ТЗ .УдалитьСтроки (); Иначе ТЗ =СоздатьОбъект("ТаблицаЗначений" ); ТЗ .НоваяКолонка ("Пропуск" ,"Число" ); ТЗ .НоваяКолонка ("Текст" ,"Строка" ); ТЗ .НоваяКолонка ("Длина" ,"Число" ,); КонецЕсли; Последний =0 ; Для к =1 по СтрДлина(ТекШаблон ) Цикл Символ =Лев(ТекШаблон ,1 ); ТекШаблон =Сред(ТекШаблон ,2 ); Если Символ ="*" Тогда Если СтрДлина(Накопитель )>0 Тогда ТЗ .НоваяСтрока (); ТЗ .Пропуск =ТекПропуск ; ТЗ .Текст =Накопитель ; ТЗ .Длина =СтрДлина(Накопитель ); ТекПропуск =0 ; Накопитель ="" ; КонецЕсли; ТекПропуск =?(ТекПропуск >0 ,ТекПропуск ,-1 ); ИначеЕсли Символ ="?" Тогда Если СтрДлина(Накопитель )>0 Тогда ТЗ .НоваяСтрока (); ТЗ .Пропуск =ТекПропуск ; ТЗ .Текст =Накопитель ; ТЗ .Длина =СтрДлина(Накопитель ); ТекПропуск =0 ; Накопитель ="" ; КонецЕсли; ТекПропуск =?(ТекПропуск >0 ,ТекПропуск +1 ,1 ); Иначе Накопитель =Накопитель +Символ ; КонецЕсли; КонецЦикла; Если СтрДлина(Накопитель )>0 Тогда ТЗ .НоваяСтрока (); ТЗ .Пропуск =ТекПропуск ; ТЗ .Текст =Накопитель ; ТЗ .Длина =СтрДлина(Накопитель ); Последний =1 ; КонецЕсли; КонецПроцедуры
//________________________________________________________ Процедура Сформировать () Перем Спр , ТекАтрибут ; Перем ТекРезультатПроверки ; Список .УдалитьСтроки (); ШаблонистыйШаблон (); ТекЭлемент =Справочники .ПолучитьЗначение (Справочники .ТекущаяСтрока ()); ТекРеквизит =Реквизиты .ПолучитьЗначение (Реквизиты .ТекущаяСтрока ()); Запрос =СоздатьОбъект("Запрос" ); ТекстЗапроса ="ЗапЭлемент = Справочник." +ТекЭлемент +".ТекущийЭлемент; |ЗапРеквизит = Справочник." +ТекЭлемент +"." +ТекРеквизит +" ; |Группировка ЗапЭлемент без упорядочивания;" ; Если Запрос .Выполнить (ТекстЗапроса )=0 Тогда Сообщить("Не выполнился запрос!" ); Возврат; КонецЕсли; Состояние("Проверка соответствия" ); Пока Запрос .Группировка (1 )=1 Цикл ТекЗначение =СокрП(Запрос .ЗапРеквизит ); Если РегистрСимволов =1 Тогда //1-учитывать регистр ТекРезультатПроверки =ПроверкаСтроки (ТекЗначение ); Иначе //0- не учитывать регистр ТекРезультатПроверки =ПроверкаСтроки (Врег(ТекЗначение )); КонецЕсли; Если ТекРезультатПроверки = 1 Тогда Список .НоваяСтрока (); Список .Элемент =Запрос .ЗапЭлемент ; Список .Реквизит =ТекЗначение ; КонецЕсли; КонецЦикла; Запрос =0 ; КонецПроцедуры
//________________________________________________________ Процедура приОткрытии () // Пример строки для фильтрации Для х =1 По Метаданные.Справочник () Цикл // перебор справочников Справочники .ДобавитьЗначение (МетаДанные.Справочник (х ).Идентификатор ); Если х =1 тогда // Для первого справочника. Остальные при навигации Реквизиты .ДобавитьЗначение ("Код" ); Реквизиты .ДобавитьЗначение ("Наименование" ); Для хх =1 По Метаданные.Справочник (х ).Реквизит () Цикл Если Метаданные.Справочник (х ).Реквизит (хх ).Тип ="Строка" тогда Если Метаданные.Справочник (х ).Реквизит (хх ).Длина =0 тогда Продолжить; КонецЕсли; Если Метаданные.Справочник (х ).Реквизит (хх ).Периодический =1 тогда Продолжить; КонецЕсли; Реквизиты .ДобавитьЗначение (МетаДанные.Справочник (х ).Реквизит (хх ).Идентификатор ); КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; ТекСправочник =Справочники .ПолучитьЗначение (1 ); Форма .ИспользоватьСлой ("Источник,Общий" ); КонецПроцедуры
//________________________________________________________ Функция Пересчет () Если НЕ(ТекСправочник =Справочники .ПолучитьЗначение (Справочники .ТекущаяСтрока ())) Тогда ТекСправочник =Справочники .ПолучитьЗначение (Справочники .ТекущаяСтрока ()); Реквизиты .УдалитьВсе (); Если Метаданные.Справочник (ТекСправочник ).ДлинаКода >0 Тогда Реквизиты .ДобавитьЗначение ("Код" ); КонецЕсли; Если Метаданные.Справочник (ТекСправочник ).ДлинаНаименования >0 Тогда Реквизиты .ДобавитьЗначение ("Наименование" ); КонецЕсли; Для хх =1 По Метаданные.Справочник (ТекСправочник ).Реквизит () Цикл ТекТип =Метаданные.Справочник (ТекСправочник ).Реквизит (хх ).Тип ; Если (ТекТип ="Строка" ) Или (ТекТип ="Число" ) тогда Если Метаданные.Справочник (ТекСправочник ).Реквизит (хх ).Длина =0 тогда Продолжить; КонецЕсли; Если Метаданные.Справочник (ТекСправочник ).Реквизит (хх ).Периодический =1 тогда Продолжить; КонецЕсли; Реквизиты .ДобавитьЗначение (МетаДанные.Справочник (ТекСправочник ).Реквизит (хх ).Идентификатор ); КонецЕсли; КонецЦикла; ТекСправочник =Справочники .ПолучитьЗначение (Справочники .ТекущаяСтрока ()); Реквизиты .Текущаястрока (2 ); КонецЕсли; КонецФункции
//________________________________________________________ Процедура ПриВыбореЗакладки (ТекНомер ) Если ТекНомер =1 Тогда Форма .ИспользоватьСлой ("Источник,Общий" ); Иначе Форма .ИспользоватьСлой ("Основной,Общий" ); КонецЕсли; КонецПроцедуры
//________________________________________________________
Форма .ИспользоватьЗакладки (1 );
Форма .Закладки .ДобавитьЗначение (1 ,"Данные" );
Форма .Закладки .ДобавитьЗначение (2 ,"Результат" );
Список .НоваяКолонка ("Элемент" );
Список .НоваяКолонка ("Реквизит" );
Эту обработку можно загрузить в разделе "Скачать".
Перепечатка, воспроизведение в любой форме, распространение, в том числе в переводе, любых материалов с сайта www.softpoint.ru возможны только с письменного разрешения компании "СофтПоинт". Это правило действует для всех без исключения случаев, кроме тех, когда в материале прямо указано разрешение на копирование (основание: Закон Российской Федерации "Об авторском праве и смежных правах").
|