Имя: Пароль:
1C
1С v8
Получить параметры из регистра сведений
0 vikpart
 
09.10.18
12:56
Добрый день! Направьте на путь истинный!

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

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

Можно ли получить запросом? чтоб в условие передать массив элементов для которых необходимо получить данные
1 1Сергей
 
09.10.18
13:03
(0) можно, но муторно
2 Жан Пердежон
 
09.10.18
13:05
(0) можно, но буднично
3 vikpart
 
09.10.18
13:05
Готов рассмотреть любой вариант, даже муторный, только бы быстро отрабатывало
4 1Сергей
 
09.10.18
13:06
(3) иерархия неограничена?
5 vikpart
 
09.10.18
13:07
Да не ограничена
6 hhhh
 
09.10.18
13:12
(3) так как-то

ВЫБРАТЬ ПЕРВЫЕ 1
     ОграничениеСкидки
ИЗ
    РегистрСведений.Рег КАК Рег
ГДЕ
    Рег.НОменклатура = &Ном

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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