階層データセット内、できればピボットテーブル内でデータを集計する方法を見つけようとしていますが、他の方法でも問題ない場合があります。以下のようなデータセット(例では大幅に簡略化されています)について考えてみます。このデータから、次のような質問に答える一連の関数を作成しようとしています。
「フルーツの総在庫はどれくらいありますか?」
「何種類の食べ物を売っていますか?」
Item Category
======= ========
Apples Fruit
Bacon Meat
Chicken Meat
Corn Veg
Food
Fruit Food
Grapes Fruit
Meat Food
Squash Veg
Steak Meat
Veg Food
各Itemには(他の多くの情報の中で)カテゴリがあります、これは本当に「親」と考えることができます。ただし、データセット内では、すべての「親」にも独自の親カテゴリがあることに注意してください。このデータセットでは、階層の1つのサンプル「ブランチ」はFood-> Meat-> Chicken。になります。
「何種類の果物を売っていますか」などの質問に答えるのは難しいことではありません。これは第1レベルのカテゴリだからです。 COUNTIF関数を使用して、「カテゴリ「フルーツ」に属するアイテムはいくつですか?」と言うだけです。 -そして私は次のようなテーブルを取得します:
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
簡単-最初の行では、「リンゴ」が他の人のカテゴリとして表示される回数が表示されます。 (ゼロなので、Appleが親ではないことはわかっています...これは役立つはずですが、方法はわかりません...)5行目の「Fruit」が他の人のカテゴリとして2回表示されます。はゼロではありません。単なるアイテムではなくカテゴリであることを私は知っています。すべてうまく、最初のレベルの数学には良いですが...
これは私が解決できなかった部分に私を導きます...私が持っている「食べ物」の合計の種類をどのように把握するのですか?そして、私の実際のデータにはさらに多くの階層レベルがあることを考えると、ツリーを上下に歩いて、それぞれに何人の子供がいるかを把握する必要があります。第1レベルのCOUNTIF関数は、食品には3つのサブカテゴリ(果物、野菜、肉)があることを示していますが、私が本当に望んでいるのは、果物、野菜、肉を再帰的に決定することですもカテゴリである可能性があり、それらの子に対応する数を合計します。 Excelの用語で言えば、私が本当に望んでいるのは、サブツリー全体のアイテムの総数を再帰的/反復的にカウントする別の列を作成できることです...この場合、Foodに属する7つの固有のアイテムがあります:3つの肉、野菜2個と果物2個。
いくつかの複雑な要因:
その特定のアイテムがカテゴリでもあるかどうか、またはそれが最下位のアイテムであるかどうかを示すデータには、明示的識別子はありません。
各アイテムは、そのカテゴリ/親が何であるかを知っているだけです。子があるかどうかを示す明示的なデータはありません。別の言い方をすれば、すべてのアイテムはカテゴリに属しますが、一部のアイテムのみがカテゴリでもあります。
実際のデータでは、親関係は最大10レベルの深さになる可能性がありますが、階層内の各ブランチの深さが一貫しているという保証はありません。一部のアイテムは3レベルの深さで、次のアイテムは8レベルの深さである可能性があります。
ルートまたは最終的な親にはカテゴリが付属していませんが、これは1回限りのケースであり、手動で簡単に処理できます。
これは「実際の」プログラミング言語(Perl、Pythonなど)では簡単な演習になることを十分に承知しています...しかし、最終的にはプログラミングの経験がない人にこれを渡さなければならないので、私はこれを「標準的な」Excelワークブックに適合させるために非常に懸命に努力しています。
最初は、@ Raystafarianに完全に同意しますが、Excelはそのための適切なツールではありません。
ただし、本当にここで実行したい場合は、いくつかのヘルパー列を使用したソリューションを次に示します。
=IFERROR(INDEX([level],MATCH([@Category],[Item],0))+1,1)
=CHAR(CODE("a")+COUNTIF($C$2:C2,[@level])-1)
=IF([@level]>1,INDEX([long code],MATCH([@Category],[Item],0)),"")&[@[level code]]
=COUNTIF([Category],[@Item])>0
このモデルでは、カテゴリにはすべてのアイテムとサブカテゴリが含まれ、そのコードは親コードと同じシーケンスで始まります(たとえば、fruit
のコードがaa
の場合、すべての(孫...)子そのうちのaa
で始まるコードがあります)
あなたの質問への回答:
「フルーツの総在庫はどれくらいありますか?」
=COUNTIFS(Table1[long code],VLOOKUP(I3,Table1,5,FALSE)&"*",Table1[has child],FALSE)
モデルによると、すべてのアイテムの開始シーケンスは同じです。ここでは、カテゴリではなくアイテムのみを扱っています(2種類の果物apples
とgrapes
を販売していますが、fruit
という商品を販売していません)。カテゴリもカウントする場合は、数式の2番目の部分を除外します。
「何種類の食べ物を売っていますか?」
=SUMIF(Table1[long code],VLOOKUP(I10,Table1,5,FALSE)&"*",Table1[inventory])
SUMIF
と非常によく似ています
このソリューションには2つの制限があります。
a
から始まり、CHAR
関数で最後にサポートされる文字は255であるため、どのレベルでも158を超える異なるカテゴリがあります。エラー(最初のコードに小さいコードの文字を使用して少し拡張できます)マテには良い答えがあると思います。私がそれをする方法はリストであるでしょう:
(すべての配列数式なので、 Ctrl+Shft+Enter)
だから、数式(下にドラッグ)
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))
これで、それらを並べ替える方法に応じて、確実に階層を作成したり、ピボットテーブルを使用したりできます。
名前付き範囲で作業できるように、おそらくA列とB列に名前を付けます。