|
Находясь под впечатлением обработки по фильтрации справочников средствами 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 возможны только с письменного разрешения компании "СофтПоинт". Это правило действует для всех без исключения случаев, кроме тех, когда в материале прямо указано разрешение на копирование (основание: Закон Российской Федерации "Об авторском праве и смежных правах").
|