Имя: Пароль:
1C
1С v8
Иерархия данных в запросе OLE
0 Romich1981
 
14.02.14
09:37
Коллеги, всем доброго дня.

Задача: вытянуть из удаленной базы иеррахический справочник, не потеряв при этом иерархию.
В голову приходит только рекурсия выборки по родителю.
Может быть, есть варианты проще, а я их не знаю?
1 Romich1981
 
14.02.14
11:09
=) ну и хрен с ним... рекурсия так рекурсия
2 fisher
 
14.02.14
11:11
Для того, чтобы не потерять иерархию, достаточно вытянуть родителя.
3 fisher
 
14.02.14
11:12
Или ты хочешь по ссылкам вытаскивать только используемые элементы и их родителей, а не весь справочник?
4 fisher
 
14.02.14
11:14
Если так - то я в подобных случаях просто делал несколько запросов (по количеству используемых уровней иерархии).
Сначала элементы. Потом запрос на их родителей. И так далее.
5 fisher
 
14.02.14
11:16
Можно одним пакетом с временными таблицами и объединением.
6 dk
 
14.02.14
11:19
а тупо в выборке указать по иерархии?
7 fisher
 
14.02.14
11:20
Хм... Я почему-то сразу решил, что речь не об 1С.
8 wowik
 
14.02.14
11:29
(6) +1
9 Romich1981
 
14.02.14
11:32
(6) запрос выполняется в OLE, возвращается таблица с данными простых типов. Выгружаются только наименования элементов. Как тут указать "по иерархии" ?
10 Romich1981
 
14.02.14
11:34
(0)...забыл сказать, что данные собираются из нескольких баз, выгрузки осуществляются в таблицу, чтобы потом ее засунуть в запрос и произвести над очередные манипуляции.
11 hhhh
 
14.02.14
11:39
(9) ну, поле наименование родителя?
12 Romich1981
 
14.02.14
11:50
(11) ну да, его тоже выгружаю.
Потом возникает небольшая,но решаемая техническая проблема - выстроить иерархию родителей =)
13 dk
 
14.02.14
11:57

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка = &Ссылка
ИТОГИ ПО Номенклатура.Ссылка ИЕРАРХИЯ
14 m-serg74
 
14.02.14
12:31
(13) может так?

ВЫБРАТЬ
    Номенклатура.Родитель.Код,
    Номенклатура.Родитель.Наименование,
    Номенклатура.Код,
    Номенклатура.Наименование,
    Номенклатура.ЭтоГруппа
ИЗ
    Справочник.Номенклатура КАК Номенклатура

УПОРЯДОЧИТЬ ПО
    Номенклатура.Ссылка ИЕРАРХИЯ
15 dk
 
14.02.14
12:34
(14) с фильтром по товару не взлетит
16 m-serg74
 
14.02.14
12:35
(15) с чего бы?
17 m-serg74
 
14.02.14
12:36
(15) и где у ТСа про фильтр?
18 dk
 
14.02.14
12:37
(16) проверь
(17) см (10)
19 m-serg74
 
14.02.14
12:41
(18) про несколько баз вижу, про то что из этих баз выбирается что то хоть убей не вижу
20 Romich1981
 
14.02.14
13:07
(13) еще раз, выгружаю через ОЛЕ, ссылка не канает, выборка не канает. Только выгрузка в таблицу значений. Если запрос с итогами, то выгрузятся дополнительно строки с итогами. Потом эту таблицу в сводном запросе как обрабатывать?

Может быть, есть смысл в постообработке запроса в удаленной базе, чтобы засунуть в итоговую таблицу уровень элемента...
21 dk
 
14.02.14
13:14
(20) не впиливаешь
как ты "рекурсию по родителю" (0) будешь делать без ссылки? ))
22 m-serg74
 
14.02.14
13:16
(20)

ТаблДанных = Новый ТаблицаЗначений();
ТаблДанных.Колонки.Добавить("НоменклатураРодительКод", Новый ОписаниеТипов("Строка"));
ТаблДанных.Колонки.Добавить("НоменклатураРодительНаименование", Новый ОписаниеТипов("Строка"));
    ТаблДанных.Колонки.Добавить("НоменклатураКод", Новый ОписаниеТипов("Строка"));
ТаблДанных.Колонки.Добавить("НоменклатураНаименование", Новый ОписаниеТипов("Строка"));
ТаблДанных.Колонки.Добавить("НоменклатураЭтоГруппа", Новый ОписаниеТипов("Строка"));
Запрос = ВнСоед.NewObject("Запрос");
Запрос.Текст =
"ВЫБРАТЬ
|    Номенклатура.Родитель.Код КАК НоменклатураРодительКод,
|    Номенклатура.Родитель.Наименование КАК НоменклатураРодительНаименование,
|    Номенклатура.Код КАК НоменклатураКод,
|    Номенклатура.Наименование КАК НоменклатураНаименование,
|    Номенклатура.ЭтоГруппа КАК НоменклатураЭтоГруппа
|ИЗ
|    Справочник.Номенклатура КАК Номенклатура
|УПОРЯДОЧИТЬ ПО// или как предложили ИТОГИ
|    Номенклатура.Ссылка ИЕРАРХИЯ
";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    НовСтр = ТаблДанных.Добавить();
    НовСтр.НоменклатураРодительКод = Выборка.НоменклатураРодительКод;
    НовСтр.НоменклатураРодительНаименование = Выборка.НоменклатураРодительНаименование;
    НовСтр.НоменклатураКод = Выборка.НоменклатураКод;
    НовСтр.НоменклатураНаименование = Выборка.НоменклатураНаименование;
    НовСтр.НоменклатураЭтоГруппа = Выборка.НоменклатураЭтоГруппа;
КонецЦикла;
23 m-serg74
 
14.02.14
13:19
(21) ссылка которая будет везде COMObject? Много она ему поможет
24 dk
 
14.02.14
13:19
(23) еще 1 не впиливает
25 m-serg74
 
14.02.14
13:20
(24) поясни с учетом (23)
26 dk
 
14.02.14
13:22
ссылка она и есть ссылка хоть ком, хоть обычная - получай реквизиты, используй в фильтрах, ...
27 Вах 1-й
 
14.02.14
13:24
метаданные в цикле получи куда-нить в ТЗ, потом будет понятно что используется чего вообще в другой базе нет
28 m-serg74
 
14.02.14
13:25
(26) а вон ты про что, что тянуть все через ссылку? нах тогда Запрос?

Тогда
Выборка = Справочники.Номенклатура.ВыбратьИерархически... и епись с ними...
29 MaxxiMiliSanM
 
14.02.14
13:27
выгружать все сразу
родитель - это ссылка по гуиду
потом родитель когда загрузится он проставится
30 m-serg74
 
14.02.14
13:29
(29) /родитель - это ссылка по гуиду /

что есть гуид, в запросе?
31 Romich1981
 
14.02.14
14:07
(26) Возможно, при выборке из одной базы такой вариант прокатит...
32 Romich1981
 
14.02.14
14:09
(26) Если собрать ТЗ из нескольких баз, потом засунуть ее в обобщающий запрос, то таблица с колонкой типа "COMОбъект" просто туда не полезет...
33 Romich1981
 
14.02.14
14:11
(21) Если получу Уровень элемента, то построить иерархическое дерево не такая уж большая проблема.
34 dk
 
14.02.14
14:12
(32) а какую ты хочешь построить иерархию, если
товар1 есть в базе А, но его нет в базе Б
товар2 есть в базе Б, но его нет в базе А
35 Romich1981
 
14.02.14
14:15
В моем случае иерархия по справочнику будет после группировки по организациям - это раз. Справочники идентичны - это два.
36 Serginio1
 
14.02.14
14:15
(32) Выгрузи ТЗ в строку и загрузи на стороне COM

СериализаторXDTO.ЗаписатьXML(

ВнСоед.СериализаторXDTO.ПрочитатьXML
37 Serginio1
 
14.02.14
14:16
38 dk
 
14.02.14
14:16
"Справочники идентичны" = совпадают УИДы?
39 Romich1981
 
14.02.14
14:19
(34) И какая тут связь с иерархией? пока не понял...
(38) нет, УИДы разные. Давай забудем про идентичность справочников, а то предложишь иерерхию построить по справочнику из основной базы, а из удаленных через соединение выстроить =)
40 Romich1981
 
14.02.14
14:19
(34) = (36)
41 Romich1981
 
14.02.14
14:21
В общем, попробую как-нибудь ссылку выгрузить, посмотрю, что там за иерархия получится...
42 Serginio1
 
14.02.14
14:25
(40) Так собери данные в ТЗ и использую ее в Запросе. Для того, что бы передать эту ТЗ в COM передавай её как строку
43 Romich1981
 
14.02.14
14:38
(42) Ничего не понял, пошел курить XDTO...
44 Serginio1
 
14.02.14
14:43
(42) Либо как тут многие используют ЗначениеВСтрокуВнутр
ЗначениеИзСтрокиВнутр

Но XDTO знать надо т.к. внутри 1С используют XML сериализацию и например для ТЗ написано

Сериализуется. Данный объект может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту, определяется в пространстве имен {http://v8.1c.ru/8.1/data/core}. Имя типа XDTO: ValueTable.
45 m-serg74
 
14.02.14
14:57
(43) чем (22) не подходит?
46 Romich1981
 
14.02.14
15:04
(45) при таком подходе, как я понимаю, надо строго следить за сортировкой результата. Если, не дай бог, пересортировал, то метод не работает, а значит он ненадежный. Конечно, информация о родителе останется, но, чтобы построить иерархию придется проанализировать, всю таблицу - кто там кому родитель и на каком уровне...
47 Romich1981
 
14.02.14
15:07
(45) таблицу можно и без XDTO получить. Не понял, как при такой передаче можно сохранить иерархию. Как уже посмеялись в (21) иерархию без ссылки штатно не восстановить.
48 Serginio1
 
14.02.14
15:12
(47) У тебя должно же быть ключевое поле
49 Romich1981
 
14.02.14
15:19
(48) что ты имеешь ввиду под ключевым полем и как оно поможет?
50 m-serg74
 
14.02.14
15:20
(46) почему это? сортируй как хочешь, но вот загружать начинай с тех где родитель код/наимменование пустые, потом тех, для кого они являются родителями и т.д.
51 Serginio1
 
14.02.14
15:24
(49) Код, Ссылка, уникальный реквизит.
Делаешь соединение по справочнику
52 m-serg74
 
14.02.14
15:27
(51) какая Ссылка через КОМ?
53 dk
 
14.02.14
15:29
(49) как ты понимаешь что товар1 в Базе1 это товар2 в Базе2?
как сопоставляешь? по наименованию / коду / ...?
54 Serginio1
 
14.02.14
15:32
(52) Легко, если базы синхронизируются по ссылке и имеют одинаковое наименование справочников можно обмениваться ТЗ через строку где полем будет являться "СправочникСсылка.ХХХ
55 m-serg74
 
14.02.14
15:34
(54) откуда в запросе через КОМ получишь "СправочникСсылка.ХХХ"???
56 Serginio1
 
14.02.14
15:37
(55) Если выгружу запрос в ТЗ а тз сериализую в строку и обратно  из строки десериализую.
57 m-serg74
 
14.02.14
15:46
(49) так на "коленке":


Процедура ЗагрузитьИерархию(ТЗ, ТекущийУровень, Родитель)
    Для Каждого ТекСтр Из ТекущийУровень Цикл
        Если ТекСтр.ЭтоГруппа = "Да" Тогда
            НовРодитель = Справочники.Номенклатура.СоздатьГруппу();
            НовРодитель.Код = ТекСтр.Код;
            НовРодитель.Наименование = ТекСтр.Наименование;
            НовРодитель.Записать();
            Отбор = Новый Структура("РодительКод, РодительНаименование", ТекСтр.Код, ТекСтр.Наименование);
            ВерхнийУровень = ТЗ.НайтиСтроки(Отбор);
            ЗагрузитьИерархию(ТЗ, ВерхнийУровень, НовРодитель.Ссылка);
        Иначе
            НовЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
            НовЭлемент.Код = ТекСтр.Код;
            НовЭлемент.Наименование = ТекСтр.Наименование;
            НовЭлемент.Записать();
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Процедура КнопкаВыполнитьНажатие(Кнопка)
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Номенклатура.Родитель.Код КАК РодительКод,
    |    Номенклатура.Родитель.Наименование КАК РодительНаименование,
    |    Номенклатура.Код КАК НоменклатураКод,
    |    Номенклатура.Наименование КАК НоменклатураНаименование,
    |    Номенклатура.ЭтоГруппа КАК НоменклатураЭтоГруппа
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура";
    Выборка = Запрос.Выполнить().Выбрать();
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("РодительКод", Новый ОписаниеТипов("Строка"));
    ТЗ.Колонки.Добавить("РодительНаименование", Новый ОписаниеТипов("Строка"));
    ТЗ.Колонки.Добавить("НоменклатураКод", Новый ОписаниеТипов("Строка"));
    ТЗ.Колонки.Добавить("НоменклатураНаименование", Новый ОписаниеТипов("Строка"));
    ТЗ.Колонки.Добавить("НоменклатураЭтоГруппа", Новый ОписаниеТипов("Строка"));
    Пока Выборка.Следующий() Цикл
        ЗаполнитьЗначенияСвойств(ТЗ.Добавить(), Выборка);
    КонецЦикла;
    //выгрузили из базу КОМ
    
    //создаем в текущей базе
    Отбор = Новый Структура("РодительКод, РодительНаименование", "", "");
    ВерхнийУровень = ТЗ.НайтиСтроки(Отбор);
    ЗагрузитьИерархию(ТЗ, ВерхнийУровень, Справочники.Номенклатура.ПустаяСсылка());
КонецПроцедуры
58 m-serg74
 
14.02.14
15:47
(57) поиск существующих, сам добавить думаю сможешь, если нужно
59 m-serg74
 
14.02.14
15:53
(57) про...еп:

        Если ТекСтр.ЭтоГруппа = "Да" Тогда
            НовРодитель = Справочники.Номенклатура.СоздатьГруппу();
            НовРодитель.Код = ТекСтр.Код;
            НовРодитель.Наименование = ТекСтр.Наименование;
            НовРодитель.Родитель = Родитель;
            НовРодитель.Записать();
            Отбор = Новый Структура("РодительКод, РодительНаименование", ТекСтр.Код, ТекСтр.Наименование);
            ВерхнийУровень = ТЗ.НайтиСтроки(Отбор);
            ЗагрузитьИерархию(ТЗ, ВерхнийУровень, НовРодитель.Ссылка);
        Иначе
            НовЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
            НовЭлемент.Код = ТекСтр.Код;
            НовЭлемент.Наименование = ТекСтр.Наименование;
            НовЭлемент.Родитель = Родитель;
            НовЭлемент.Записать();
        КонецЕсли;
60 Romich1981
 
14.02.14
16:20
(53) допустим по коду
(54) базы не синхронизируются по ссылке
(58) это я понял, примерно такое решение изначально и пришло в голову. Только пустых родителей нет, т.к. я не выгребаю весь справочник, а лишь небольшую часть. Но в целом работает.
61 m-serg74
 
14.02.14
16:22
(60) как это пустых нет, если иерархия вплоть до корня справочника то все равно самый верхний уровень будет иметь пустого родителя
62 Romich1981
 
14.02.14
16:23
Коллеги, я предлагаю тему зарыть. Решение в принципе есть, похоже на (57).
Насчет ссылок, XDTO и прочего - я как-нибудь обязательно попробую!
Спасибо участвующим!
63 m-serg74
 
14.02.14
16:23
(60) или если только определенную ветку выгружаешь, то в запросе для нее делай что родитель якобы пустой
64 Serginio1
 
14.02.14
16:43
(62) Попробуй. Соединиться со справочником с тз по Коду и
УПОРЯДОЧИТЬ ПО Номенклатура.Ссылка ИЕРАРХИЯ самый простой способ
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс