Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Поиск в пустом подчиненном справочнике
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 7.7
Sede
Добрый день.
Создан подчиненный справочник (КодыКонтрагентов, реквизиты: КодТовара, Контрагент) подчинен справочнику (ТМЦ).
Пример - в справочнике ТМЦ товар Мыло, на етот товар в справочнике КодыКонтрагентов записи (фирма 1 - код 00001, фирма2 - код 22212, фирма3 - код 23232)
Необходимо - Найти код указаного контрагента и вернуть название Товара ТМЦ(владелец)
Листинг функции поиска в подчиненном справочнике.
Функция ПоискПоКоду(кодПоиска, Контрагент)               
нет=0;    
спрКодКонтр=СоздатьОбъект("Справочник.КодыКонтрагентов");
    спрКодКонтр.ВыбратьЭлементы(0);  
    Пока спрКодКонтр.ПолучитьЭлемент()=1 Цикл
        КодИзСпр=СокрЛП(Строка(СпрКодКонтр.КодТовара));
        КонтрИзСпр=спрКодКонтр.Контрагент;
        Пометка=спрКодКонтр.ПометкаУдаления();
          Если (КодИзСпр=кодПоиска) И (КонтрИзСпр=Контрагент) И (Пометка=0) Тогда
          Возврат спрКодКонтр.Владелец;  
    
         Прервать;
        Иначе
         нет=1;
         КонецЕсли;    
КонецЦикла;
Если нет=1 Тогда
      Возврат "";
КонецЕсли;
КонецФункции


Использование НайтиПоРеквизиту или НайтиПоНаименованию исключаю, так как в случае 2х одинаковых кодов поиск остановится на первом елементе (например у фирмы1 на код 00001 - мыло, у фирмы2 на коде 00001-рубашки)

Суть седующая: если в справочнике есть хотябы одна запись все работает отлично(записанные коды находит - если кодов нет сообщает).
Если справочник пуст результат -сообщает что все коды присутствуют.
Какбы вариант добавить 1 запись вроде (БлаБла, Абракадабра) и все работает никаких претензий, но все же для себя хотелось бы разобраться почему Фирма1="" и код 00001=""(Пустой справочник)

Как узнать что в справочнике (есть/нет) записи. Или может что-нибуть посоветуете.

Вот что получилось - Как один из вариантов - пересчет елементов при вызове запроса
Функция ПоискПоКоду(кодПоиска, Контрагент)               
//*************
Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса = "
    |ТекущийЭлемент  = Справочник.КодыКонтрагентов.ТекущийЭлемент;
    |Функция Счетчик = Счётчик();
    |"
  ;
    Запрос.Выполнить(ТекстЗапроса);
Если Запрос.Счетчик=0 Тогда
   Возврат "";
КонецЕсли;    
//*************
нет=0;    
спрКодКонтр=СоздатьОбъект("Справочник.КодыКонтрагентов");
    спрКодКонтр.ВыбратьЭлементы(0);  
    Пока спрКодКонтр.ПолучитьЭлемент()=1 Цикл
        КодИзСпр=СокрЛП(Строка(СпрКодКонтр.КодТовара));
        КонтрИзСпр=спрКодКонтр.Контрагент;
        Пометка=спрКодКонтр.ПометкаУдаления();
          Если (КодИзСпр=кодПоиска) И (КонтрИзСпр=выбКонтрагент) И (Пометка=0) Тогда
          Возврат спрКодКонтр.Владелец;  
         Прервать;
        Иначе
         нет=1;
         КонецЕсли;    
    КонецЦикла;
Если нет=1 Тогда
      Возврат "";
КонецЕсли;
КонецФункции

Может кому пригодится
vadim007
Цитата(Sede @ 03.06.15, 9:24) необходимо зарегистрироваться для просмотра ссылки
Может кому пригодится

Это было актуально лет десять назад...
Vofka
Цитата(vadim007 @ 03.06.15, 10:48) необходимо зарегистрироваться для просмотра ссылки
Это было актуально лет десять назад...

Что актуально сейчас?
TipsyKID
А чем не устроил метод

ВыбратьЭлементыПоРеквизиту(<ИмяРеквизита>, <Значение>, <РежимИерархии>, <РежимГрупп>)
Метод ВыбратьЭлементыПоРеквизиту() предоставляет возможность выбирать элементы (открывает выборку) при помощи метода ПолучитьЭлемент().

Дальнейшая выборка при помощи метода ПолучитьЭлемент() будет происходить среди элементов текущего справочника, имеющих значение реквизита <ИмяРеквизита> равным <Значение>, в порядке, установленном параметрами <РежимИерархии> и <РежимГрупп>, а также согласно установкам, сделанным заранее при помощи методов:

ПорядокНаименований(),

ПорядокКодов(),

ВключатьПодчиненные(),

ИспользоватьРодителя(),

ИспользоватьВладельца(),

ИспользоватьДату().

?
Sede
Цитата(TipsyKID @ 03.06.15, 11:50) необходимо зарегистрироваться для просмотра ссылки
А чем не устроил метод

ВыбратьЭлементыПоРеквизиту(<ИмяРеквизита>, <Значение>, <РежимИерархии>, <РежимГрупп>)
Метод ВыбратьЭлементыПоРеквизиту() предоставляет возможность выбирать элементы (открывает выборку) при помощи метода ПолучитьЭлемент().

Дальнейшая выборка при помощи метода ПолучитьЭлемент() будет происходить среди элементов текущего справочника, имеющих значение реквизита <ИмяРеквизита> равным <Значение>, в порядке, установленном параметрами <РежимИерархии> и <РежимГрупп>, а также согласно установкам, сделанным заранее при помощи методов:

ПорядокНаименований(),

ПорядокКодов(),

ВключатьПодчиненные(),

ИспользоватьРодителя(),

ИспользоватьВладельца(),

ИспользоватьДату().



?


Извините Но даный метод не работает по причине описаной выше. Если по результатам ВыбратьЭлементыПоРеквизиту количество елементов - 0, то результат поиска возвращет положительноесть результат (все найдено, но название представляется отсутствующим,- именно отсутсвующим, поскольку при значении ""(пусто) результат отрицательный- товар не найден,см. листинг выше).
Чтобы он работал необходимо снова делать проверку на количество уже отобраных елементов. Или может ктонибуть подскажет где "Собака зарыта". Почему при отсутствии записей (количество которых =0) результат положительный.

хм.. TipsyKID спасибо! Подтолкнул на еще одно решение:
Функция ПоискПоКоду(кодПоиска, Контрагент)               
нет=0;    
спрКодКонтр=СоздатьОбъект("Справочник.КодыКонтрагентов");
//    спрКодКонтр.ВыбратьЭлементы(0); //1

    количество = спрКодКонтр.ВыбратьЭлементыПоРеквизиту("КодТовара", кодПоиска, 0,0);
    Если количество=0 Тогда
        Возврат "";
    КонецЕсли;    


    Пока спрКодКонтр.ПолучитьЭлемент()=1 Цикл
        КодИзСпр=СокрЛП(Строка(СпрКодКонтр.КодТовара));
        КонтрИзСпр=спрКодКонтр.Контрагент;
        Пометка=спрКодКонтр.ПометкаУдаления();
          Если (КодИзСпр=кодПоиска) И (КонтрИзСпр=выбКонтрагент) И (Пометка=0) Тогда
          Возврат спрКодКонтр.Владелец;  
         Прервать;
        Иначе
         нет=1;
         КонецЕсли;    
    КонецЦикла;
Если нет=1 Тогда
      Возврат "";
КонецЕсли;
КонецФункции


И судя по всему ето и есть одно из верных решений, если не единственное .
TipsyKID
Так красивее будет ( а то 100500+ прерываний функции возвратом - изврат ) :
Функция ПолучитьВладельцаПоКоду(кодПоиска, Контрагент)               
       Результат = ПолучитьПустоеЗначение();
       
    спрКодыКонтрагентов=СоздатьОбъект("Справочник.КодыКонтрагентов");
    спрКодыКонтрагентов.ВыбратьЭлементыПоРеквизиту("КодТовара", кодПоиска, 0,0);

    Пока спрКодыКонтрагентов.ПолучитьЭлемент()=1 Цикл
        КодИзСпр = СокрЛП(спрКодыКонтрагентов.КодТовара);
        КонтрИзСпр = спрКодКонтр.Контрагент;
        Пометка = спрКодКонтр.ПометкаУдаления();
        
        Если (Пометка = 0) И (КонтрИзСпр = Контрагент) И (КодИзСпр = КодПоиска) Тогда
            Результат = спрКодКонтр.Владелец;
            Прервать;
        КонецЕсли;    
    КонецЦикла;
    
    Возврат Результат;
КонецФункции
twilight_dream
Да, семерка она коварная. Выбирать надо без групп. То же касается и запроса. В зависимости от того, как его построишь, может вернуть либо одну пустую строку, естественно,с ненулевым счетчиком, либо ничего, либо одну строку с нулевым счетчиком. smile.gif
Sede
В справочнике 1 уровень так что с группами заморачиваться не пришлось...и слаба Богу, хватит с одного головной болью разобрался rulez.gif
Sharzem
Цитата(Sede @ 08.06.15, 10:42) необходимо зарегистрироваться для просмотра ссылки
В справочнике 1 уровень так что с группами заморачиваться не пришлось...и слаба Богу, хватит с одного головной болью разобрался rulez.gif


А я так не думаю, что разобрались уж-таки до конца ))).
Для отбора единичного количества элементов, варриант предложенный TipsyKID вполне решает задачу.

Смотря что Вы собираетесь делать. Решение в нужном направлении, но: в функции используются такие операторы как СоздатьОбъект, ВыбратьЭлементыПоРеквизиту, Пока ... Цикл.
В зависимости от количества обращений к функции у Вас очень уж сильно возрастет время выполнения задачи. Например, нужно загрузить прайс-лист, с немеряным количеством Элементов, в следствии будете смотреть в экран минутами.

Вопрос: Почему Вы не можете даже тем самым запросом отобрать подчиненый справочник по условию Контрагент = Контрагент, выгрузить запрос в Таблицу значений и по мере необходимости доставать оттуда методом НайтиЗначение в колонке "код" подчиненный справочник ? В результате Вы получите возрастание производительности (на большом количестве обращений) раз в 10-15 (в зависимости от формата базы)! Подумайте, возможно еще не поздно изменить подход и на этапе разработки переделать.
Sede
Цитата(Sharzem @ 08.06.15, 12:49) необходимо зарегистрироваться для просмотра ссылки
А я так не думаю, что разобрались уж-таки до конца ))).
Для отбора единичного количества элементов, варриант предложенный TipsyKID вполне решает задачу.

Смотря что Вы собираетесь делать. Решение в нужном направлении, но: в функции используются такие операторы как СоздатьОбъект, ВыбратьЭлементыПоРеквизиту, Пока ... Цикл.
В зависимости от количества обращений к функции у Вас очень уж сильно возрастет время выполнения задачи. Например, нужно загрузить прайс-лист, с немеряным количеством Элементов, в следствии будете смотреть в экран минутами.

Вопрос: Почему Вы не можете даже тем самым запросом отобрать подчиненый справочник по условию Контрагент = Контрагент, выгрузить запрос в Таблицу значений и по мере необходимости доставать оттуда методом НайтиЗначение в колонке "код" подчиненный справочник ? В результате Вы получите возрастание производительности (на большом количестве обращений) раз в 10-15 (в зависимости от формата базы)! Подумайте, возможно еще не поздно изменить подход и на этапе разработки переделать.


Спасибо 12201689.gif . На работу с запросами еще руки не очень заточены, не знаю как реализовать. Но Ваш вариант мне нравится буду разбираться.
Касательно количества обращений тут пока либо поштучно, либо пачками по 10-15 штук. В тестовом варианте обработал 20 штук грузится за секунду(может просто справочник еще не достаточно большой), так что пусть пока работает, НО в перспективу придется обязательно переделать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.