Пишем простенькие функции отбора (столько, сколько вариантов отбора мы хотим):
// На подобии этой, отбор списка владельцев подчиненного справочника, по полю // подчиненного справочника. Возвращает список значений владельцев подчиненного // справочника. // ---------------------------------------------------------------------- Функция гл7ПолучитьСписокСертификатовПоНомеруРамы(Знач НомерРамы) Экспорт Перем СпрРамыДвигатели, СпСертификатов; НомерРамы=СокрЛП(НомерРамы); СпСертификатов=СоздатьОбъект("СписокЗначений"); СпрРамыДвигатели=СоздатьОбъект("Справочник.СертификатыРамыДвигатели"); СпрРамыДвигатели.ВыбратьЭлементыПоРеквизиту("НомерРамы",НомерРамы,0,0); Пока СпрРамыДвигатели.ПолучитьЭлемент()=1 Цикл Если СпрРамыДвигатели.ПометкаУдаления()=1 Тогда Продолжить; КонецЕсли; ТекВлад=СпрРамыДвигатели.ТекущийЭлемент().Владелец; Если СпСертификатов.НайтиЗначение(ТекВлад)<1 Тогда СпСертификатов.ДобавитьЗначение(ТекВлад); КонецЕсли; КонецЦикла; Возврат СпСертификатов; КонецФункции // гл7ПолучитьСписокСертификатовПоНомеруРамы // ----------------------------------------------------------------------
После чего мы можем получить нужное количество списков элементов, удовлетворяющих нужному количеству условий. И теперь, чтобы объединить эти условия, используем следующие функции работы со списками значений:
// ---------------------------------------------------------------------- Функция гл8УдалитьДвойниковИзСписка(Знач Сп1) Экспорт Перем Сп, СпУдалПоз, СпУдалЗнач; Сп=СоздатьОбъект("СписокЗначений"); СпУдалПоз=СоздатьОбъект("СписокЗначений"); СпУдалЗнач=СоздатьОбъект("СписокЗначений"); Если ВРег(СокрЛП(ТипЗначенияСтр(Сп1))) <> ВРег("СписокЗначений") Тогда Возврат Сп; КонецЕсли; Если Сп1.РазмерСписка()<1 Тогда Возврат Сп; КонецЕсли; N=Сп1.РазмерСписка(); i=0; Пока i<N Цикл i=i+1; Sx=""; V=Сп1.ПолучитьЗначение(i,Sx); Если (СпУдалЗнач.НайтиЗначение(V)<1) Тогда j=0; Пока j<N Цикл j=j+1; Sx2=""; V2=Сп1.ПолучитьЗначение(j,Sx2); Попытка Если (V=V2) И (i<>j) И (СпУдалЗнач.НайтиЗначение(V2)>0) Тогда СпУдалПоз.ДобавитьЗначение(j); КонецЕсли; Если (V=V2) Тогда СпУдалЗнач.ДобавитьЗначение(V2,Sx2); КонецЕсли; Исключение КонецПопытки; КонецЦикла; КонецЕсли; КонецЦикла; i=0; Пока i<N Цикл i=i+1; Sx=""; V=Сп1.ПолучитьЗначение(i,Sx); Если СпУдалПоз.НайтиЗначение(i)<1 Тогда Сп.ДобавитьЗначение(V,Sx); КонецЕсли; КонецЦикла; Возврат Сп; КонецФункции // гл8УдалитьДвойниковИзСписка // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- Функция гл8ПолучитьПересечениеСписков(Знач Сп1, Знач Сп2) Экспорт Перем Сп; Сп=СоздатьОбъект("СписокЗначений"); Если ВРег(СокрЛП(ТипЗначенияСтр(Сп1))) <> ВРег("СписокЗначений") Тогда Возврат Сп; КонецЕсли; Если ВРег(СокрЛП(ТипЗначенияСтр(Сп2))) <> ВРег("СписокЗначений") Тогда Возврат Сп; КонецЕсли; Если Сп1.РазмерСписка()<1 Тогда Возврат Сп; КонецЕсли; Если Сп2.РазмерСписка()<1 Тогда Возврат Сп; КонецЕсли; Сп1=гл8УдалитьДвойниковИзСписка(Сп1); Сп2=гл8УдалитьДвойниковИзСписка(Сп2); N=Сп1.РазмерСписка(); i=0; Пока i<N Цикл i=i+1; Sx=""; V=Сп1.ПолучитьЗначение(i,Sx); Если Сп2.НайтиЗначение(V)>0 Тогда Сп.ДобавитьЗначение(V,Sx); КонецЕсли; КонецЦикла; Возврат Сп; КонецФункции // гл8ПолучитьПересечениеСписков // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- Функция гл8ПолучитьОбъединениеСписков(Знач Сп1, Знач Сп2) Экспорт Перем Сп; Сп=СоздатьОбъект("СписокЗначений"); Если ВРег(СокрЛП(ТипЗначенияСтр(Сп1))) <> ВРег("СписокЗначений") Тогда Сп1=СоздатьОбъект("СписокЗначений"); КонецЕсли; Если ВРег(СокрЛП(ТипЗначенияСтр(Сп2))) <> ВРег("СписокЗначений") Тогда Сп2=СоздатьОбъект("СписокЗначений"); КонецЕсли; Если Сп1.РазмерСписка()<1 Тогда Если Сп2.РазмерСписка()<1 Тогда Возврат Сп; Иначе Сп2.Выгрузить(Сп); Возврат Сп; КонецЕсли; КонецЕсли; Если Сп2.РазмерСписка()<1 Тогда Если Сп1.РазмерСписка()<1 Тогда Возврат Сп; Иначе Сп1.Выгрузить(Сп); Возврат Сп; КонецЕсли; КонецЕсли; Сп1=гл8УдалитьДвойниковИзСписка(Сп1); Сп2=гл8УдалитьДвойниковИзСписка(Сп2); N=Сп1.РазмерСписка(); i=0; Пока i<N Цикл i=i+1; Sx=""; V=Сп1.ПолучитьЗначение(i,Sx); Поз=Сп2.НайтиЗначение(V); Если Поз>0 Тогда Сп2.УдалитьЗначение(Поз); КонецЕсли; КонецЦикла; Сп=гл9ОбъединитьСпискиЗначений(Сп1,Сп2); Возврат Сп; КонецФункции // гл8ПолучитьОбъединениеСписков // ----------------------------------------------------------------------
Использовать можно следующим образом (упрощенно):
Перем СпСертификатов, СпСертификатов1, СпИтоговый; СпСертификатов=гл7ПолучитьСписокСертификатовПоНомеруРамы(ЗначениеВВидеСтроки); СпСертификатов1=гл7ПолучитьСписокСертификатовПоНомеруДвигателя(ЗначениеВВидеСтроки1); // И СпИтоговый=гл8ПолучитьПересечениеСписков(СпСертификатов,СпСертификатов1); ИспользоватьСписокЭлементов(СпИтоговый); // ИЛИ СпИтоговый=гл8ПолучитьОбъединениеСписков(СпСертификатов,СпСертификатов1); ИспользоватьСписокЭлементов(СпИтоговый);
Автор: Сергей Попов, Усинск, Коми
// ---------------------------------------------------------------------- //Объединяются списки значений //Функция возвращает суммарный список //При этом, Спис1 выгружается, а Спис2 построчно добавляется в конец списка Функция гл9ОбъединитьСпискиЗначений(Спис1,Спис2) Экспорт //_new_ 19.03.2003 сп_ Перем Res; Res=СоздатьОбъект("СписокЗначений"); Если ВРег(СокрЛП(ТипЗначенияСтр(Спис1)))= ВРег("СписокЗначений") Тогда Спис1.Выгрузить(Res); КонецЕсли; Если ВРег(СокрЛП(ТипЗначенияСтр(Спис2)))= ВРег("СписокЗначений") Тогда N=Спис2.РазмерСписка(); Если N>0 Тогда i=0; Пока i<N Цикл i=i+1; Sx=""; V=Спис2.ПолучитьЗначение(i,Sx); Res.ДобавитьЗначение(V,Sx); КонецЦикла; КонецЕсли; КонецЕсли; Возврат Res; КонецФункции //гл9ОбъединитьСпискиЗначений // ----------------------------------------------------------------------