7.7 Цикл по отфильтрованном справочнику 7.7?

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 7.7"", создана пользователем umbra777, 14 мар 2018.

  1. TopicStarter Overlay
    umbra777
    Offline

    umbra777

    Регистрация:
    10 май 2010
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    Задача такая: есть справочник Серии (см. скриншот), очень большой. Мне надо расставить в каждой серии значение нового реквизита (Поставщик). Поставщики эти указаны в доках "приходная накладная". Вот я и прохожусь по всем этим докам, чтобы выцепить оттуда поставщиков и расставить для каждой серии по ее имени и по цене поставщика как однозначному ключу.
    Сейчас проблема в следующем - если запросом действовать, то я потом буду работать с результатом запроса, а не непосредственно со справочником Серии? Тогда возникает вопрос: как мне получить РЕАЛЬНЫЙ код элемента справочника, чтобы однозначно его идентифицировать и изменить у него реквизит?
    Сейчас в поле Код коды все повторяются (см. скриншот)
    Может есть какой-то внутренний код уникальный? Как его получить?
    Либо второй вариант: непосредственно делать цикл по справочнику и перебирать элементы с нужным именем (первый параметр) пока не совпадет и второй параметр - Цена поставщика.
    Это можно как-нибудь сделать? Причем не тупо перебором, потому что справочник Серии гигантский и получается, что чтобы расставить каждому его элементу реквизит мне надо будет его перебрать примерно n * n раз где - n - его размерность в десятки тысяч элементов! А сначала скажем так сделать фильтрацию элементов справочника по наименованию, чтобы искать только среди них и потом уже искать элемент с нужной ценой поставщика. Накидайте кто может пожалуйста пример как это сделать примерно!
    Не нашел вообще ничего похожего в сети в качестве примера.
    Я думаю второй вариант более доступный. К тому же сомневаюсь по первому варианту, что есть уникальный код элемента справочника, по которому его можно однозначно идентифицировать. Поэтому что мне сейчас нужно:
    1. У меня есть Имя серии (на скриншоте это столбец "Наименование"), Цена поставщика и Название поставщика (из строки документа).
    2. Мне нужно как то включить фильтрацию в справочнике Серии (именно в нем самом, а не на копии), чтобы в нем остались только серии с искомым именем.
    3. Нужно организовать цикл по всем отфильтрованным элементам, пока не найду элемент с искомой ценой поставщика.
    Дальше дело техники. Скажите пожалуйста, реализуемо ли это и есть да, то дайте пожалуйста пример кода!

    Вложения:

  2. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    22.628
    Симпатии:
    542
    Баллы:
    204
    У вас этот справочник как-то фигурирует в документе поступления? Если да, то получать через метод НайтиЭлемент.
    Слишком мало информации.. Можете выложить МДшник.
  3. TopicStarter Overlay
    umbra777
    Offline

    umbra777

    Регистрация:
    10 май 2010
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    Не фигурирует, если я вас правильно понимаю. В документе "Приходная Накладная" указывается не ссылка на элемент справочника Серии, а ее строковое представление (т.е. имя Серии = столбец Наименование на скриншоте выше)
    Ссылка на Мдшник http://cloud.mail.ru/public/Hki2/etFqKtXZA
  4. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    22.628
    Симпатии:
    542
    Баллы:
    204
    Не вижу... "приходная накладная" в первом посте, как в метаданных документ называется? Тут такая каша....
  5. TopicStarter Overlay
    umbra777
    Offline

    umbra777

    Регистрация:
    10 май 2010
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    В конфиге так и называется - ПриходнаяНакладная, в базе - Поступление товаров
  6. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    22.628
    Симпатии:
    542
    Баллы:
    204
    ПриходнаяНакладная в метаданных у вас это Отгрузка товаров. Определитесь уж
  7. TopicStarter Overlay
    umbra777
    Offline

    umbra777

    Регистрация:
    10 май 2010
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    Вы про сам объект конфигурации речь ведете? Сам объект называется таки ПриходнаяНакладная (см. скрин)

    Вложения:

  8. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    22.628
    Симпатии:
    542
    Баллы:
    204
    Ну более менее понятно. Нашел.
    "В лоб" не получится. Только перебором документов "ПриходнаяНакладная"
    Алгоритм я вижу так
    1) В цикле выбираем документы от Рождества Христова (или откуда вам нужно)
    2) Поиск нужного элемента справочника "серия" (модуль проведения документа, строка 93)
    3) Установка и запись реквизита (для ускорения проверка перед записью на уже заполненный реквизит). Т.е. если заполнен - повторять не надо. При массовой обработке дает заметный прирост в скорости.
  9. TopicStarter Overlay
    umbra777
    Offline

    umbra777

    Регистрация:
    10 май 2010
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    Ну да, я так и планировал. Перебор документов уже готов, остался только сам алгоритм непосредственного изменения серий в справочнике! Проблема в том что не могу сообразить как сделать цикл ТОЛЬКО по нужным мне элементам справочника Серии. Или сделать фильтрацию по имени серии.
    У меня уже было некоторое решение но в силу того, что оказывается в 1С нельзя двигаться по результатам поиска, оно не подходит, так как работает только для первого найденного элемента.
    А серий с одинаковым именем (но при этом с разным поставщиком, что определяется разной ценой поставщика!) могут быть десятки!
    Код:
    Сер = СоздатьОбъект("Справочник.Серии");
    ...
    Пока Сер.НайтиПоНаименованию(Докум.Серия, 0) = 1 Цикл
          Цен = Сер.ЦенаПоставщика.Получить(Докум.ДатаДок);
          Если Цен = Докум.ЦенаПост Тогда
                  Сер.Поставщик.Установить(Докум.ДатаДок,Докум.Контрагент);
                  Сер.Записать();
                  Прервать;
          Иначе
                  Продолжить;
           КонецЕсли;
    КонецЦикла; 
    --- Объединение сообщений, 14 мар 2018 ---
    В это то вся и загвоздка! Из строки документа я беру 2 параметра:
    1. Наименование, то есть имя серии
    2. ЦенаПоставщика
    Ну и соответственно название этого поставщика из шапки документа
    Так вот, я никак не могу понять, как имея эти два параметра (которые вместе однозначно определяют поставщика для каждой серии!), организовать цикл по справочнику Серии так, чтобы
    когда мы находим первую серию с заданным именем, цикл не заканчивался, так как Цена поставщика может быть другая, значит надо двигаться дальше -
    искать следующую серию с таким же именем и проверять у нее Цену поставщика и так, пока не найдется нужный элемент!
    Вот в этом вся загвоздка! Не могу понять как делать следующую итерацию цикла, если имя серии совпадает, а цена поставщика - не совпадает!
    Поэтому и предположил, что может как-то можно сначала отфильтровать справочник Серии по нужному имени серии и потом уже в отфильтрованном справочнике искать серию с нужной ценой поставщика?
    Или еще как-то по другому можно сделать? Уже голову сломал за 2 дня, помогите пожалуйста!
    Последнее редактирование: 14 мар 2018
  10. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    22.628
    Симпатии:
    542
    Баллы:
    204
    Тут без ТЗ не обойтись...

    А)Грузим Справочник Серий в ТаблицуЗначений
    Структура ТЗ
    1) Наименование
    2) Цена
    3) Ссылка на элемент (текущийЭлемент)

    Б) Сортируем ТЗ по Наименованию (серия)

    В) Цикл По ТЗ

    поз=0;
    ТЗ.НайтиЗначение(ТекЗначение,Поз,"Наименование");
    Для ПозТЗ=Поз По ТЗ.КоличествоСтрок() Цикл
    ТЗ.ПолучитьСтрокуПоНомру(ПозТЗ);
    Если СоркЛП(ТЗ.Наименование)<>СокрЛП(ТекЗначение) Тогда
    прервать;
    КонецЕсли;
    //тут сравниваем цены. Если совпало - тоже прервать чтобы ограничить цикл
    КонецЦикла;

    ТекЗначение - название серии из документа (ваш цикл)
  11. TopicStarter Overlay
    umbra777
    Offline

    umbra777

    Регистрация:
    10 май 2010
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    Ок, огромное спасибо за помощь! Сейчас буду пробовать!
  12. TopicStarter Overlay
    umbra777
    Offline

    umbra777

    Регистрация:
    10 май 2010
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    Споткнулся о ссылки. Подскажите пожалуйста, правильно ли я записываю в ТЗ ссылки на элементы справочника Серии и самое главное как мне потом в конце, когда найдена нужная серия, перейти к ней по сохраненной ссылке из ТЗ?

    Код:
    Процедура ПриОткрытии()
        Дата1 = НачалоПериодаБИ();
        Дата2 = КонецПериодаБИ();
    КонецПроцедуры
    
    
    //*******************************************
    
    Процедура ФайлЗакупок()
        ТЗ = СоздатьОбъект("ТаблицаЗначений");
        ТЗ.НоваяКолонка("Наименование");
        ТЗ.НоваяКолонка("ЦенаПост");
        ТЗ.НоваяКолонка("Ссылка");
    
        Сер = СоздатьОбъект("Справочник.Серии");
        Сер.ВыбратьЭлементы(0);
        Пока Сер.ПолучитьЭлемент() = 1 Цикл
                ТЗ.НоваяСтрока();          
                ТЗ.Наименование = Сер.Наименование;                         
                ТЗ.ЦенаПост = Сер.ЦенаПоставщика.Получить(ТекущаяДата());
                ТЗ.Ссылка = Сер.ТекущийЭлемент();  //Вот тут правильно ли я сохраняю ссылку? 
          КонецЦикла;
    
        ТЗ.Сортировать("Наименование");                                       
    
        Докум = СоздатьОбъект( "Документ" );
    
        Докум.ВыбратьДокументы( Дата1, Дата2 );
    
        Пока Докум.ПолучитьДокумент() = 1 Цикл
              Если (Докум.Вид() = "ПриходнаяНакладная") Тогда             
                    Докум.ВыбратьСтроки();
                    Пока Докум.ПолучитьСтроку()=1 Цикл
                  
                        ТекЗначение = Докум.Серия;
                        Поз=1;
                        ТЗ.НайтиЗначение(ТекЗначение,Поз,"Наименование");             
                           Для ПозТЗ=Поз По (ТЗ.КоличествоСтрок()) Цикл
                               ТЗ.ПолучитьСтрокуПоНомеру(ПозТЗ);
                               Если СокрЛП(ТЗ.Наименование)<>СокрЛП(ТекЗначение) Тогда
                                          прервать;
                                   КонецЕсли;
                        //тут сравниваем цены. Если совпало - тоже прервать чтобы ограничить цикл
                           Если ТЗ.ЦенаПост = Докум.ЦенаПост Тогда
                                   Сер.ТекущееЗначение() = ТЗ.Ссылка;  // Вот тут как мне перейти к элементу по ссылке?
                                   Сер.Поставщик.Установить(Докум.ДатаДок,Докум.Контрагент);
                                   Сер.Записать();
                                   Прервать;
                           КонецЕсли;
                           КонецЦикла;                                
                    КонецЦикла;
               КонецЕсли;
        КонецЦикла;
    КонецПроцедуры
    
    Последнее редактирование: 15 мар 2018
  13. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    22.628
    Симпатии:
    542
    Баллы:
    204
    Да. Все правильно (заполняете ТЗ). А вот присваиваете не верно.
    Тмп= СоздатьОбъект("Справочник.Серии");
    Тмп.НайтиЭлемент(ТЗ.ССылка);
    Тмп.Поставщик.Установить(Докум.ДатаДок,Докум.Контрагент);
    Тмп.Записать();

    Еще момент... Поскольку у вас Цена - периодическое значение... Нужно В ТЗ еще дату установки цены добавлять.
  14. TopicStarter Overlay
    umbra777
    Offline

    umbra777

    Регистрация:
    10 май 2010
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    Огромное спасибо за помощь!
  15. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    22.628
    Симпатии:
    542
    Баллы:
    204
    Не вопрос... Обращайтесь! Всегда можно помочь направить на путь истинный.
    З/Ы.. Не забываем внимание на коммент.. Периодика вещи коварная...