Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.08.2010, 18:35   #1
motorway
Участник клуба
 
Регистрация: 28.06.2009
Сообщений: 1,950
Счастье Получение дочерних элементов в PivotTable

Привет, кто может помочь с таким вопросом:
есть PivotTable (сводная таблица), в которую данные загружаются из PowerPivot (OLAP-источник). Как для выделенной ячейки можно получить список всех дочерних элементов (уровня leaf) в иерархии, которые соответствуют определенному полю?
Вот пример (на рисунке):
Ячейки, для которых нужно получить все непустые дочерние элементы, помечены красным, голубым и серым. Дочерние элементы, представляющие собой значения поля "код", выделены оранжевым. Их и нужно получать.
Для "Бразилия" и столбца "1" будет список 1,10,19,28, для столбца "2" - 2,11,20,29 и т.п. Для ячейки на пересечении "23.08.10" и столбца "1" дочерними будут только 1 и 10. Для общего итога - все: 1,2,3,10,11,12,19,20,21,28,29,30.
При этом, так как элементов может быть много, а получать их надо быстро, лучше не обращаться к самим ячейкам таблицы, так как обычно это медленно, а обращаться к объекту типа PivotCell. Похоже, надо копать в сторону PivotItems или подобной коллекции элементов, но как сделать точно - в этом и вопрос.
Изображения
Тип файла: jpg pivot.jpg (132.5 Кб, 136 просмотров)
motorway вне форума Ответить с цитированием
Старый 27.08.2010, 20:10   #2
KL (XL)
Форумчанин
 
Аватар для KL (XL)
 
Регистрация: 04.08.2009
Сообщений: 112
По умолчанию

Как-то так, но без самой таблицы как-то непривычно:

Код:
Sub Test()
    Dim pt As PivotTable
    Dim pf As PivotField
    Dim pi As PivotItem
    
    Set pt = ActiveSheet.PivotTables(1)
    Set pf = pt.PivotFields(4)
    Set pi = pf.PivotItems(1)
    
    MsgBox pi.LabelRange(1).Value
End Sub
Если не дотянули, то еще есть объект pi.ChildItems(n)
KL [MVP - Microsoft Office Excel]
CPU: Intel Core 2, 2.17GHz | RAM: 3.25GB (4GB) | GPU: nVidia Quadro FX 2500M
OS: Windows 7 Ultimate x64 EN | MSO: 2010 Professional Plus x86 EN

Последний раз редактировалось KL (XL); 27.08.2010 в 20:13.
KL (XL) вне форума Ответить с цитированием
Старый 27.08.2010, 20:53   #3
motorway
Участник клуба
 
Регистрация: 28.06.2009
Сообщений: 1,950
По умолчанию

Если везде поставить 1-й индекс, появляется ошибка 1004: невозможно получить свойство PivotItems класса PivotFields.
Также если менять индексы у PivotField, иногда появляется ошибка такого же рода о LabelRange у класса PivotItems
А свойство ChildItems для OLAP не работает! (http://msdn.microsoft.com/en-us/libr...hilditems.aspx)

Последний раз редактировалось motorway; 27.08.2010 в 21:59.
motorway вне форума Ответить с цитированием
Старый 27.08.2010, 22:16   #4
KL (XL)
Форумчанин
 
Аватар для KL (XL)
 
Регистрация: 04.08.2009
Сообщений: 112
По умолчанию

Цитата:
Сообщение от motorway Посмотреть сообщение
Если везде поставить 1-й индекс, появляется ошибка 1004: невозможно получить свойство PivotItems класса PivotFields.
Также если менять индексы у PivotField, иногда появляется ошибка такого же рода о LabelRange у класса PivotItems
А свойство ChildItems для OLAP не работает! (http://msdn.microsoft.com/en-us/libr...hilditems.aspx)
Индексы я ставил на глаз, вы же таблицу не выложили. Так что доводить вам ;-)

Кстати с первыми индексами - логично. У вас PivotField(1) - Акции даже не включен в таблицу, так откуда у него будут PivotItems?
KL [MVP - Microsoft Office Excel]
CPU: Intel Core 2, 2.17GHz | RAM: 3.25GB (4GB) | GPU: nVidia Quadro FX 2500M
OS: Windows 7 Ultimate x64 EN | MSO: 2010 Professional Plus x86 EN

Последний раз редактировалось KL (XL); 27.08.2010 в 22:21.
KL (XL) вне форума Ответить с цитированием
Старый 27.08.2010, 22:20   #5
motorway
Участник клуба
 
Регистрация: 28.06.2009
Сообщений: 1,950
По умолчанию

Пока что получается, что вообще нерешаемая проблема - ChildItems-то не работает
И эту проблему я видел в Интернете - у многих она есть. Но решения пока не нашел
Кроме этого, у вас не используется текущая ячейка

Последний раз редактировалось motorway; 27.08.2010 в 22:23.
motorway вне форума Ответить с цитированием
Старый 27.08.2010, 22:23   #6
KL (XL)
Форумчанин
 
Аватар для KL (XL)
 
Регистрация: 04.08.2009
Сообщений: 112
По умолчанию

Цитата:
Сообщение от motorway Посмотреть сообщение
Пока что получается, что вообще нерешаемая проблема - ChildItems-то не работает
И эту проблему я видел в Интернете - у многих она есть. Но решения пока не нашел
Вы таблицу не хотите выложить? Думаю, искать недолго и обратите внимание на второй абзац, который я только что добавил к моему предыдущему посту.
Насчет текущей ячейки, я думал, вы сами разберетесь, там совсем легко, если найдем уровень объекта, на котором у вас эти значения
И нерешаемых задач не бывает, бывает недостачно информации или мотивации :-)
KL [MVP - Microsoft Office Excel]
CPU: Intel Core 2, 2.17GHz | RAM: 3.25GB (4GB) | GPU: nVidia Quadro FX 2500M
OS: Windows 7 Ultimate x64 EN | MSO: 2010 Professional Plus x86 EN

Последний раз редактировалось KL (XL); 27.08.2010 в 22:30.
KL (XL) вне форума Ответить с цитированием
Старый 27.08.2010, 22:26   #7
motorway
Участник клуба
 
Регистрация: 28.06.2009
Сообщений: 1,950
По умолчанию

А будет ли она работать у вас без подключения к источнику?
OK, посмотрите, может, что получится
Понятно, что каким-то способом можно перебрать эти элементы, но хотелось бы это сделать максимально эффективно.
А мотивация большая
Вложения
Тип файла: rar PowerPivot_TEST2.rar (89.9 Кб, 14 просмотров)

Последний раз редактировалось motorway; 27.08.2010 в 22:31.
motorway вне форума Ответить с цитированием
Старый 27.08.2010, 23:19   #8
KL (XL)
Форумчанин
 
Аватар для KL (XL)
 
Регистрация: 04.08.2009
Сообщений: 112
По умолчанию

Как-то так, хотя Union достаточно медленная функция. Но если значений не тысячи, то должно бегать быстро:

Option Explicit

Код:
Sub Test()
    Dim pt As PivotTable
    Dim pf As PivotField
    Dim pi As PivotItems
    Dim r As Range, a As Range
    Dim i As Long
    Dim arr
    
    Set pt = ActiveSheet.PivotTables(1)
    Set pf = pt.PivotFields(6)
    Set pi = pf.PivotItems
    
    For i = 1 To pi.Count
        If r Is Nothing Then Set r = pi(i).LabelRange Else Set r = Union(r, pi(i).LabelRange)
    Next i
    For Each a In r.Areas
        If Not Intersect(a, ActiveCell) Is Nothing Then
            arr = a.Value
            Exit For
        End If
    Next a
End Sub
KL [MVP - Microsoft Office Excel]
CPU: Intel Core 2, 2.17GHz | RAM: 3.25GB (4GB) | GPU: nVidia Quadro FX 2500M
OS: Windows 7 Ultimate x64 EN | MSO: 2010 Professional Plus x86 EN
KL (XL) вне форума Ответить с цитированием
Старый 27.08.2010, 23:32   #9
motorway
Участник клуба
 
Регистрация: 28.06.2009
Сообщений: 1,950
По умолчанию

Что-то пока не работает, пробую вывести значения, ничего не показывает, даже Msgbox не появляется. Как проверить полученные результаты?
Значений как раз может быть много в случае, если элемент достаточно высоко. При этом OLAP начинает тормозить, то же может быть и с макросом... Если >10000 ячеек, то в сводной таблице это уже не показывается
Еще есть один способ - получать текущий уровень вложенности элемента и идти вниз по элементам, пока их уровень вложенности будет больше значения для текущей ячейки.
Но надо еще определить их общее кол-во.

Последний раз редактировалось motorway; 27.08.2010 в 23:41.
motorway вне форума Ответить с цитированием
Старый 27.08.2010, 23:46   #10
KL (XL)
Форумчанин
 
Аватар для KL (XL)
 
Регистрация: 04.08.2009
Сообщений: 112
По умолчанию

Цитата:
Сообщение от motorway Посмотреть сообщение
Что-то пока не работает, пробую вывести значения, ничего не показывает, даже Msgbox не появляется. Как проверить полученные результаты?
Значений как раз может быть много в случае, если элемент достаточно высоко. При этом OLAP начинает тормозить, то же может быть и с макросом... Если >10000 ячеек, то в сводной таблице это уже не показывается
Все работает А вы разве не массив просили? Как же я вам его покажу?
- Кликните мышью перед E в строке End Sub
- Меню Debug > Run to cursor
- В окне Locals найдите + arr
- Кликните на плюс и изучайте значения массива

В каком виде вам нужен список?
KL [MVP - Microsoft Office Excel]
CPU: Intel Core 2, 2.17GHz | RAM: 3.25GB (4GB) | GPU: nVidia Quadro FX 2500M
OS: Windows 7 Ultimate x64 EN | MSO: 2010 Professional Plus x86 EN
KL (XL) вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Много дочерних форм... L.A.M.E.R. Общие вопросы Delphi 4 03.08.2010 08:13
запретить переопределение в дочерних классах MAcK Общие вопросы Delphi 2 20.05.2010 09:29
массив в PivotTable jungo Microsoft Office Excel 1 21.01.2010 09:33
Расположение дочерних MDI окон слева-направо и сверху-вниз Umdis Общие вопросы Delphi 2 30.11.2009 07:05
AlphaSkins. Как убрать скин с дочерних MDI Форм? chandrasecar Компоненты Delphi 4 11.02.2009 20:06