- ベストアンサー
エクセル2003で上位10箇所を抽出してデータベースを構築する方法
- エクセル2003を使ってデータベースを構築する方法について説明します。具体的には、R列にある事象が発生した箇所を抽出し、違うシートにそれぞれの発生件数と共に貼り付ける方法を紹介します。
- 同順位の事象が複数ある場合でも、上位10箇所を抽出する方法について説明します。例えば、1位の事象が100件、2位の事象が90件、3位の事象が80件とAAも80件ある場合でも、上記のように抽出することができます。
- この処理はVBAを使って実現することができます。VBAを用いることで、簡単に上位10箇所を抽出し、データベースを構築することができます。VBAのコードを使用することで、同順位の事象も正しく抽出することができます。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> 構文の説明を頂けないでしょうか? 基本はDictionaryオブジェクトです。 Dictionaryオブジェクトについては http://officetanaka.net/excel/vba/tips/tips80.htm などを参照してください。 要は、データの羅列から重複しないリストを作成し、個々の重複しない各データ(Key)に関連付けられるItemに出現数をカウントしているだけです。 KeyもItemも配列となるので、それぞれTransposeで縦に変換してB、C列に貼り付けます。 そしてそれを降順に並べ替え、空いているA列にRankを入れ、さらに上位10に入る数値のところまでを残してそれ以下を削除しました。 各コードにコメントをつけました。 Sub test01() Dim myDic As Object '変数宣言 Dim ms As Worksheet, ns As Worksheet Dim c As Range, r As Range, dta As String, b As Long Set myDic = CreateObject("Scripting.Dictionary") 'Dictionaryオブジェクトを準備しmyDicとする Set ms = Sheets("Sheet1") 'Sheets("Sheet1")をmsとする Set ns = Sheets("Sheet2") 'Sheets("Sheet2")をnsとする For Each c In ms.Range(ms.Cells(2, "R"), ms.Cells(Rows.Count, "R").End(xlUp)) 'msのR列の各セルについて dta = c.Value 'セルのデータをdtaに代入 If Not myDic.exists(dta) Then 'myDicにdtaが存在しなければ myDic.Add dta, 1 'myDicにKeyとして加え、そのItemを1とする Else '重複すれば myDic(dta) = myDic(dta) + 1 'そのKeyのItemに1を加える End If Next c '繰り返し ns.Range("B1").Resize(myDic.Count, 1).Value = Application.Transpose(myDic.Keys) 'nsのB1以下にKeyの配列を転記 ns.Range("C1").Resize(myDic.Count, 1).Value = Application.Transpose(myDic.Items) 'nsのC1以下にItemの配列を転記 Set myRng = ns.Range("C1:C" & myDic.Count) 'ns.C列データ範囲をmyRngとする myRng.Offset(0, -1).Resize(, 2).Sort Key1:=ns.Range("C1"), Order1:=xlDescending, Header:=xlNo 'A~C列を並べ替え b = Application.Large(myRng, 10) 'myRngの10位の値をbに代入 myRng.Offset(0, -2).NumberFormatLocal = "#""位""" 'A列の書式設定(位) For Each r In myRng 'myRng各セルについて r.Offset(0, -2).Value = Application.Rank(r.Value, myRng) '左2つ隣(A列)にRank表示 If r.Value < b Then 'b以下なら ns.Range(r, myRng.Cells(myRng.Count)).EntireRow.Delete 'それ以下の行を削除 Exit For '繰り返しを抜ける End If Next r '繰り返し Set myDic = Nothing '後処理 Set ms = Nothing Set ns = Nothing Set myRng = Nothing End Sub
その他の回答 (2)
- merlionXX
- ベストアンサー率48% (1930/4007)
merlionXXです。 ごめんなさい、ミスってました。 修正します。 Sub test01() Dim myDic As Object Dim ms As Worksheet, ns As Worksheet Dim c As Range, r As Range, dta As String, b As Long Set myDic = CreateObject("Scripting.Dictionary") Set ms = Sheets("Sheet1") Set ns = Sheets("Sheet2") For Each c In ms.Range(ms.Cells(2, "R"), ms.Cells(Rows.Count, "R").End(xlUp)) dta = c.Value If Not myDic.exists(dta) Then myDic.Add dta, 1 Else myDic(dta) = myDic(dta) + 1 End If Next c ns.Range("B1").Resize(myDic.Count, 1).Value = Application.Transpose(myDic.Keys) ns.Range("C1").Resize(myDic.Count, 1).Value = Application.Transpose(myDic.Items) Set myRng = ns.Range("C1:C" & myDic.Count) myRng.Offset(0, -1).Resize(, 2).Sort Key1:=ns.Range("C1"), Order1:=xlDescending, Header:=xlNo b = Application.Large(myRng, 10) myRng.Offset(0, -2).NumberFormatLocal = "#""位""" For Each r In myRng r.Offset(0, -2).Value = Application.Rank(r.Value, myRng) If r.Value < b Then ns.Range(r, myRng.Cells(myRng.Count)).EntireRow.Delete Exit For End If Next r Set myDic = Nothing Set ms = Nothing Set ns = Nothing Set myRng = Nothing End Sub
お礼
前回に引き続き、ご回答頂きありがとうございます。 お陰さまで、今回も解決できそうです。 お手数でなければ、この構文の説明を頂けないでしょうか? 後程、抽出するデータの追加等が発生する可能性がありますので・・・ よろしくお願い致します。
- merlionXX
- ベストアンサー率48% (1930/4007)
R2以降に「事象発生箇所」名があるシートをSheet1 ベスト10を抽出するシートをSheet2とします。 Sheet2のA列にRANK、B列に「事象発生箇所」、C列に発生数(出現数)を表示します。 Sub test01() Dim myDic As Object Dim ms As Worksheet, ns As Worksheet Dim c As Range, r As Range, dta As String, b As Long Set myDic = CreateObject("Scripting.Dictionary") Set ms = Sheets("Sheet1") Set ns = Sheets("Sheet2") For Each c In ms.Range(ms.Cells(2, "R"), ms.Cells(Rows.Count, "R").End(xlUp)) dta = c.Value If Not myDic.exists(dta) Then myDic.Add dta, 1 Else myDic(dta) = myDic(dta) + 1 End If Next c ns.Range("B1").Resize(myDic.Count, 1).Value = Application.Transpose(myDic.Keys) ns.Range("C1").Resize(myDic.Count, 1).Value = Application.Transpose(myDic.Items) Set myRng = ns.Range("C1:C" & myDic.Count) myRng.Sort Key1:=ns.Range("C1"), Order1:=xlDescending, Header:=xlNo b = Application.Large(myRng, 10) myRng.Offset(0, -2).NumberFormatLocal = "#""位""" For Each r In myRng r.Offset(0, -2).Value = Application.Rank(r.Value, myRng) If r.Value < b Then ns.Range(r, myRng.Cells(myRng.Count)).EntireRow.Delete Exit For End If Next r Set myDic = Nothing Set ms = Nothing Set ns = Nothing Set myRng = Nothing End Sub
お礼
お礼が大変遅くなり申し訳ございませんでした。 また、ご丁寧な回答ありがとうございました。