Contagem hierárquica ou recursiva no Excel (preferencialmente dentro de uma tabela dinâmica)?

4

Eu estou tentando encontrar uma maneira de agregar dados em um conjunto de dados hierárquico, de preferência dentro de uma tabela dinâmica, mas outros métodos podem estar bem também. Considere um conjunto de dados (bastante simplificado para o exemplo) que se parece com o abaixo. A partir desses dados, estou tentando criar um conjunto de funções que responderão a perguntas como:

"Quanto estoque total eu tenho para Fruit?"

"Quantos tipos diferentes de comida eu vendo?"

Item     Category
=======  ========
Apples   Fruit
Bacon    Meat
Chicken  Meat
Corn     Veg
Food     
Fruit    Food
Grapes   Fruit
Meat     Food
Squash   Veg
Steak    Meat
Veg      Food

Cada Item tem (entre muitas outras informações) um Categoria , o que podemos realmente pensar como um "pai". Mas observe também que, no conjunto de dados, todos os "pais" também têm suas próprias categorias pai. Neste conjunto de dados, uma amostra 'ramificação' da hierarquia seria Comida - & gt; Carne & gt; Frango.

Para responder à pergunta como "quantos tipos diferentes de frutas eu vendo" não é difícil, porque esta é a categoria de primeiro nível. Eu posso apenas usar a função COUNTIF e dizer "Quantos itens pertencem à categoria" Fruit "?" - e eu recebo uma tabela assim:

Item    Category    COUNTIF(categories,me)
Apples  Fruit       0
Bacon   Meat        0
Chicken Meat        0
Corn    Veg         0
Food    Food        3
Fruit   Food        2
Grapes  Fruit       0
Meat    Food        3
Squash  Veg         0
Steak   Meat        0
Veg     Food        2

Fácil - para a primeira linha, você verá quantas vezes "Maçãs" aparecem como a categoria de outra pessoa. (Desde que é zero, eu sei que as maçãs não são um pai ... isso deve ajudar, mas não sei como ...) Agora linha cinco, "Fruit", aparece como a categoria de outra pessoa duas vezes - desde o número não é zero, eu sei que é uma categoria em vez de apenas um item. Tudo bem para o primeiro nível de matemática, mas ...

Isso me leva à parte que não consegui resolver ... Como faço para descobrir quantos tipos TOTAL de "comida" eu tenho? E, dado que meus dados reais têm muito mais níveis hierárquicos, preciso subir e descer a árvore para descobrir quantas crianças totais existem em cada uma delas. A função COUNTIF do primeiro nível me diz que existem três subcategorias de Food (Fruit, Veg, & Meat) - mas o que eu realmente quero é de alguma forma determinar de forma recursiva que Fruit, Veg e Meat também pode ser Categorias e some os números correspondentes para essas crianças. Em termos de excel, o que eu realmente quero é poder construir uma outra coluna que conte recursivamente / iterativamente o número TOTAL de itens em toda a subárvore ... neste caso, existem sete itens únicos que pertencem ao Food: 3 carnes, 2 veg e 2 frutas.

Alguns fatores complicadores:

  • Não há explícito identificador nos dados para nos dizer se esse item específico também é uma categoria, ou se é um nível inferior item.

  • Cada item só sabe o que é categoria / pai - não há dados explícitos para dizer se tem filhos ou não. Dito de outra forma: todos os itens pertencem a uma categoria, mas apenas alguns itens também são categorias.

  • Nos dados reais, o relacionamento pai pode chegar a 10 níveis profundos, MAS não há garantias de que a profundidade de cada ramificação na hierarquia é consistente: alguns itens podem ter 3 níveis profundo, enquanto o próximo pode ser 8.

  • A raiz ou pai final não vem com uma categoria, mas isso é um caso único que posso manipular facilmente manualmente.

  • Eu estou plenamente ciente de que este seria um exercício trivial em qualquer linguagem de programação 'real' (Perl, Python, etc) ... mas no final eu tenho que passar isso para alguém que não tem experiência em programação, então estou tentando muito difícil fazer isso se encaixar em uma pasta de trabalho do Excel "padrão".

ljwobker
fonte
Você já olhou (você tem acesso a) Power Pivot? Eu não tenho isso em 365/2016, mas era um suplemento gratuito incluído em algumas versões do Excel e tem a capacidade de criar hierarquias. Eu não sei se vai preencher seus requisitos, mas pode valer a pena um tiro.
Ron Rosenfeld
1
Não me parece que o Excel é a ferramenta certa para este trabalho.
Raystafarian
RonRosenfeld- Eu tenho isso, mas não parece fazer o que eu preciso para ... @Raystafarian: Eu concordo absolutamente (como eu mencionei, isso é trivial para codificar como uma caminhada recursiva em qualquer outra coisa) e eu Já o codifiquei em Python, mas no final não estou mantendo isso e a esmagadora maioria das outras coisas que eu preciso desse app / pasta de trabalho / o que quer que seja fazer são ideais no Excel. Esta foi a "última coisa" que eu estava tentando trabalhar nativamente no Excel ...
ljwobker
1
O acesso do MS é uma possibilidade? Quer dizer, com a estrutura dos seus dados, isso seria uma tarefa difícil com o VBA no Excel. Existe uma maneira de alterar a estrutura de dados? Ou para saber quais categorias sempre existem, como um relatório bastante estático?
Raystafarian
@Raystafarian Há um bom número de "outras" maneiras de resolvê-lo - mas eu estou meio que nesse estranho canto onde eu posso resolver isso 100% em "padrão, portátil, não-VBA" excel ... ou Eu tenho que ter ALGUM outro tipo de aplicativo externo ou helper ... E se eu tiver que ir desse jeito, será Python (já que eu já escrevi). Infelizmente, neste caso específico, o único valor incremental real é se eu posso fazê-lo nativamente dentro de uma pasta de trabalho 'normal' do excel ...
ljwobker

Respostas:

2

No começo, eu concordo plenamente com o @Raystafarian, o Excel não é a ferramenta certa para isso.

No entanto, se você realmente quiser fazer isso aqui, aqui está uma solução com algumas colunas auxiliares:

  • nível: nível de item real na hierarquia (itens raiz tem nível 1, o nível das crianças é aumentado)
    =IFERROR(INDEX([level],MATCH([@Category],[Item],0))+1,1)
  • código de nível: código em execução para cada item, único em NÍVEIS
    =CHAR(CODE("a")+COUNTIF($C$2:C2,[@level])-1)
  • código longo: código concatenado de pai & amp; item
    =IF([@level]>1,INDEX([long code],MATCH([@Category],[Item],0)),"")&[@[level code]]
  • tem filho: booleano dizendo se o item tem filho
    =COUNTIF([Category],[@Item])>0

Com este modelo, uma categoria contém todos os itens e subcategorias dos quais o código começa com a mesma sequência que o código dos pais (por exemplo, se fruit O código é aa, então todos (grand ...) filhos dele têm um código começando com aa )

enter image description here

Respostas para suas perguntas:

"Quanto estoque total eu tenho para Fruit?"

=COUNTIFS(Table1[long code],VLOOKUP(I3,Table1,5,FALSE)&"*",Table1[has child],FALSE)
apenas de acordo com o modelo, todos os itens com a mesma sequência inicial. Eu não vejo aqui apenas itens e não categorias (você vende dois tipos de frutas apples e grapes, você não tem um produto chamado fruit vender). Se você quiser contar também as categorias, basta excluir a segunda parte da fórmula.

"Quantos tipos diferentes de comida eu vendo?"

=SUMIF(Table1[long code],VLOOKUP(I10,Table1,5,FALSE)&"*",Table1[inventory])
Muito semelhante com SUMIF

Aviso

Esta solução tem duas limitações:

  • número de caracteres: atualmente inicia a partir de a, que tem um código de 97 e último caractere suportado em CHAR a função é 255, então ter mais de 158 categorias diferentes em qualquer nível lhe dará um erro (você pode expandir um pouco usando um caractere com código menor para o primeiro)
  • À medida que seu banco de dados aumenta, ele provavelmente terá um desempenho reduzido (cálculos complexos), você pode definir o método de cálculo como "automático, exceto para tabelas de dados" e calculá-lo manualmente apenas quando precisar.
Máté Juhász
fonte
0

Eu acho que Máté tem uma boa resposta. A maneira que eu faria seria com listas:

enter image description here

(Todas as fórmulas de array, então Ctrl + Shft + Entrar )

Então, as fórmulas (arrastar para baixo)

D2 =INDEX($A$2:$A$12,MATCH(0,IF(ISBLANK($B$2:$B$12),COUNTIF($D$1:$D1,$A$2:$A$12),""),0))    
E2 =INDEX($A$2:$A$12,MATCH(0,IF($B$2:$B$12=$D$2,COUNTIF($E$1:$E1,$A$2:$A$12),""),0))
F2 =INDEX($A$2:$A$12,MATCH(0,IF($B$2:$B$12=$E$2,COUNTIF($F$1:$F1,$A$2:$A$12),""),0))
G2 =INDEX($A$2:$A$12,MATCH(0,IF($B$2:$B$12=$E$3,COUNTIF($G$1:$G1,$A$2:$A$12),""),0))
H2 =INDEX($A$2:$A$12,MATCH(0,IF($B$2:$B$12=$E$4,COUNTIF($H$1:$H1,$A$2:$A$12),""),0))

Agora, dependendo de como você decide classificá-los, você pode definitivamente criar uma hierarquia ou usar uma tabela dinâmica.

Eu provavelmente daria nomes de colunas A e B para que você possa trabalhar com intervalos nomeados.

Raystafarian
fonte