Вход | Регистрация


1С:Предприятие :: 1С:Предприятие 8 общая

Получить параметры из регистра сведений

Получить параметры из регистра сведений
Я
   vikpart
 
09.10.18 - 12:56
Добрый день! Направьте на путь истинный!

Исходные Данные 8-ка, обычные формы 
Есть Регистр Сведений с измерением "Номенклатура" (может принимать значение группы и элемента) и ресурсом "Ограничение скидки" тип число; 

Нужно получить данные "Ограничение скидки" из этого регистра по элементу "Номенклатура" 
если запись имеет соответствие Элементу то по элементу иначе значение самого близкого родителя.

Можно ли получить запросом? чтоб в условие передать массив элементов для которых необходимо получить данные
 
 
   1Сергей
 
1 - 09.10.18 - 13:03
(0) можно, но муторно
   Жан Пердежон
 
2 - 09.10.18 - 13:05
(0) можно, но буднично
   vikpart
 
3 - 09.10.18 - 13:05
Готов рассмотреть любой вариант, даже муторный, только бы быстро отрабатывало
   1Сергей
 
4 - 09.10.18 - 13:06
(3) иерархия неограничена?
   vikpart
 
5 - 09.10.18 - 13:07
Да не ограничена
   hhhh
 
6 - 09.10.18 - 13:12
(3) так как-то
ВЫБРАТЬ ПЕРВЫЕ 1
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура = &Ном

ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура.Родитель = &Ном 
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура.Родитель.Родитель = &Ном
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура.Родитель.Родитель.Родитель = &Ном
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура.Родитель.Родитель.Родитель.Родитель = &Ном
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура.Родитель.Родитель.Родитель.Родитель.Родитель = &Ном
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = &Ном
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = &Ном
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = &Ном
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = &Ном
   vikpart
 
7 - 09.10.18 - 13:15
А если вложенность будет 20-50... родителей, громоздкая конструкция запроса будет
   1Сергей
 
8 - 09.10.18 - 13:16
(7) именно. Потому и мутарно
   palsergeich
 
9 - 09.10.18 - 13:19
(7) Если вложенность будет 20-50 родителей и элементов будет много - далеко не самая страшная проблема в базе будет
   Йохохо
 
10 - 09.10.18 - 13:21
так то самый близкий родитель всегда на расстоянии 1 и даже записан в номенклатуре
 
 Рекламное место пустует
   Йохохо
 
11 - 09.10.18 - 13:22
а, ну в коде сформировать массив ссылок полной иерархии и передать в запрос, ппц
   vikpart
 
12 - 09.10.18 - 13:26
(10) самый близки да ) но регистре может быть запись не самая близкая к родителю номенклатуры
   vikpart
 
13 - 09.10.18 - 13:28
(11) плюс на входе не одна номенклатура а массив и он может содержать 20-30к элементов
   1Сергей
 
14 - 09.10.18 - 13:36
Ещё варик

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ПОМЕСТИТЬ Номенклатура
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка В(&СписокНоменклатуры)
;

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ
    Группы.Ссылка КАК Родитель,
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Группы
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Номенклатура КАК Номенклатура
        ПО (Группы.Ссылка = Номенклатура.Ссылка.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Ссылка.Родитель.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Ссылка.Родитель.Родитель.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Ссылка.Родитель.Родитель.Родитель.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Ссылка.Родитель.Родитель.Родитель.Родитель.Родитель)
ГДЕ
    Группы.ЭтоГруппа

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Номенклатура.Ссылка,
    NULL
ИЗ
    Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
   palsergeich
 
15 - 09.10.18 - 13:40
(14) Удали это.
ИЛИ Группы.Ссылка = Номенклатура.Ссылка.Родитель.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Ссылка.Родитель.Родитель.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Ссылка.Родитель.Родитель.Родитель.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Ссылка.Родитель.Родитель.Родитель.Родитель.Родитель
Ты этим положишь базу уже на 100 000 элементах
   palsergeich
 
16 - 09.10.18 - 13:40
А то и раньше
   1Сергей
 
17 - 09.10.18 - 13:42
(15) а так?

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Родитель КАК Родитель
ПОМЕСТИТЬ Номенклатура
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка В(&СписокНоменклатуры)
;

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ
    Группы.Ссылка КАК Родитель,
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Группы
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Номенклатура КАК Номенклатура
        ПО (Группы.Ссылка = Номенклатура.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Родитель.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Родитель.Родитель.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Родитель.Родитель.Родитель.Родитель
                ИЛИ Группы.Ссылка = Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    NULL,
    Номенклатура.Ссылка
ИЗ
    Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
   palsergeich
 
18 - 09.10.18 - 13:45
(6) Тоже не вариант.
Я бы решил эту задачу через служебный регист сведений где было бы 2 колонки: ГруппаНоменклатуры Номенклатура
Суть Фоновым заданием для каждой группы пишем всю номенклатуру которая есть в этой группе и не является группой
ТЕ
гр1 ном1
гр1 ном2
+ подпписка на событие которая будет пересчитывать при изменении.
Но это будет работать быстро
   1Сергей
 
19 - 09.10.18 - 13:45
(17) + попробовал на 211 элементах:
0,276 сек.
   palsergeich
 
20 - 09.10.18 - 13:46
(19) Жалкие 211 элементов четветь секунды
   palsergeich
 
21 - 09.10.18 - 13:46
А теперь хотя бы тысячи 3
   palsergeich
 
22 - 09.10.18 - 13:46
И зависимость там будет не линейная
   hhhh
 
23 - 09.10.18 - 13:47
(19) "ИЛИ" по-любому ложит базу
   palsergeich
 
24 - 09.10.18 - 13:48
(18) Так как номенклатура как правило справочник со строгим учетом и изменения в существующие элементы заносятся редко, а новые создаются не очень часто - оптимальное решение этой задачи
   palsergeich
 
25 - 09.10.18 - 13:49
(23) Дело даже не в или, а в количестве полей через точку. Каждая лишняя точка это еще одно левое соединение. Там план запроса будет такой елкой
   1Сергей
 
26 - 09.10.18 - 13:50
(21) гражданин, на предыдущем допросе Вы говорили о ста элементах

Попробовал на 1000 элементах, прироста по длительности выполнения нет

:)
   palsergeich
 
27 - 09.10.18 - 13:52
(26) я говорил о 100 000 (Сто Тысяч)
   azernot
 
28 - 09.10.18 - 13:52
(15) Лично видел как подобные конструкции работают на более 100 тыс элементов. База не умирает. Запрос, конечно, не быстрый, но это минуты/десятки минут.
   1Сергей
 
29 - 09.10.18 - 13:53
(27) у мну столько нету
   1Сергей
 
30 - 09.10.18 - 13:54
Жалко, конечно, что нельзя В ИЕРАРХИИ тут присобачить
   palsergeich
 
31 - 09.10.18 - 13:54
(28) И комфортно в базе работать когда такие запросы выполняются? (18) Таким способом - время будет секунды
   Borteg
 
32 - 09.10.18 - 13:54
(0)
Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ
    |    ПодразделенияОрганизаций.Родитель КАК Родитель,
    |    ПодразделенияОрганизаций.Родитель.Родитель КАК РодительРодитель,
    |    ПодразделенияОрганизаций.Родитель.Родитель.Родитель КАК РодительРодительРодитель,
    |    ПодразделенияОрганизаций.Родитель.Родитель.Родитель.Родитель КАК РодительРодительРодительРодитель,
    |    ПодразделенияОрганизаций.Родитель.Родитель.Родитель.Родитель.Родитель КАК РодительРодительРодительРодительРодитель
    |ИЗ
    |    Справочник.ПодразделенияОрганизаций КАК ПодразделенияОрганизаций
    |ГДЕ
    |    ПодразделенияОрганизаций.Ссылка = &Подразделение";
    Запрос.УстановитьПараметр("Подразделение",Подразделение);
    
    Пока Истина Цикл
        
        Запрос.УстановитьПараметр("Подразделение",Подразделение);
        
        РезультатЗапроса = Запрос.Выполнить();
        
        Если РезультатЗапроса.Пустой() Тогда
            Прервать;
        КонецЕсли;
        
        Выборка = РезультатЗапроса.Выбрать();
        Выборка.Следующий();
        
        Для НомерКолонки = 0 По РезультатЗапроса.Колонки.Количество() - 1 Цикл
            
            Подразделение = Выборка[НомерКолонки];
            
            Если Подразделение = Справочники.ПодразделенияОрганизаций.ПустаяСсылка() Тогда
                Прервать;
            Иначе
                МассивПодразделений.Добавить(Подразделение);
            КонецЕсли;
    
        КонецЦикла;
        
        Если Подразделение = Справочники.ПодразделенияОрганизаций.ПустаяСсылка() Тогда
            Прервать;
        КонецЕсли;    
        
    КонецЦикла;    
    
    Возврат МассивПодразделений;
   palsergeich
 
33 - 09.10.18 - 13:55
(28) Просто я тоже видел. У нас в 14 часов такой отчет запускали - час никто работать толком не мог, пока не переписали.
Там еще  и сервер у нас был совсем не рядовой и то иногда падал, но не часто.
 
 
   Borteg
 
34 - 09.10.18 - 13:57
(32) лучший вариант-переделай просто под свою задачу, в этом запросе получается все вложенность для элемента подразделения.
   vikpart
 
35 - 09.10.18 - 13:57
(18) В этот регистр надо записать все уровни иерархии для каждого элемента справочника чтоб получить потом соответствие
   azernot
 
36 - 09.10.18 - 13:58
(31) Приемлемо.
Сразу оговорюсь, что не вникал в суть сабжа, я имел в виду конструкцию типа

Спр.Родитель.Родитель.Родитель......
т.е. многократное неявное левое соединение.

Разумеется, если есть способ решить задачу по-другому - лучше её решить по-другому.

(33) Проблема в файловой системе сервера БД. Её нужно прокачивать.
   vikpart
 
37 - 09.10.18 - 14:01
(32) Уровень иерархии не ограничен
   palsergeich
 
38 - 09.10.18 - 14:02
(36) Там все было как надо, просто вылетал rphost и все (35) А что Вас смущает? Место? Не страшно. Да первое заполнение будет долгое, зато потом профит.
   Borteg
 
39 - 09.10.18 - 14:03
(37) там для любого урвоня иерархии работает
   Borteg
 
40 - 09.10.18 - 14:03
(37) внимательно посмотри что там написано, запрос будет выполняться пока не найдет всю вложенность - родитель пустая ссылка
   Borteg
 
41 - 09.10.18 - 14:06
(37) у нас финансисты использут очень глубокую вложенность(10-15) для разных статей, схожий запрос работает идеально, ни тормозов никаких проблем.
   palsergeich
 
42 - 09.10.18 - 14:07
(32) Вполне себе тру вариант кстати. Но я бы уменьшил количество полей запроса до 3х
   vikpart
 
43 - 09.10.18 - 14:08
(41) Это хорошо когда надо найти вложенность по одному элементу, а у мне надо передать на вход  20-30к элементов
   Borteg
 
44 - 09.10.18 - 14:09
(43) тоесть тебе надо передать 20к элементов номенклатуры и на выходе получить таблицу значений номенклатура - ближайший родитель?
   Borteg
 
45 - 09.10.18 - 14:11
(43) Тогда добавь в запрос еще поле номенклатуры и итоги по, и два обхода делай, всеравно это будет в разы быстрее чем крутить запросом все это дело.
   1Сергей
 
46 - 09.10.18 - 14:24
(43) а теперь представь 30к элементов с 50-тью уровнями иерархии. Это полтора миллионов
   azernot
 
47 - 09.10.18 - 14:46
Думается проблему надо решать с другой стороны.
При запросе искать только параметры для номенклатуры и непосредственного родителя.
А вот при изменении параметров группы - изменять параметры у всех групп, первого уровня вложенности для которых параметры не заданы (разумеется рекурсивно).
   Eiffil123
 
48 - 09.10.18 - 15:10
Такую задачу проще кодом реализовывать:
1. Запросом 1 выбрать иерархию и элементы
2. Запросом 2 выбрать значения из регистра по номенклатуре из запроса 1
3. В коде обработать все строки из (1), искать значение в выборке (2).

В случае необходимости готовую ТЗ запихнуть в запрос и дальше работать в запросе.
   FIXXXL
 
49 - 10.10.18 - 08:13
Проще писать номенклатуру в РС, ПриЗаписи вычисляя значение
И быстрее гораздо
 
 Рекламное место пустует


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует