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