[[20140520170430]] 『出現頻度の抽出(文字列)』(MECO) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『出現頻度の抽出(文字列)』(MECO)

お世話になります。 
少々わかりにくいかと思いますが、助言願います。
問)
D列にデータ(=名前;文字列、重複あり))があり、最も出現頻度が高いものから
上位3位までを順番に下記に示す要領でA,B列に「名前」と頻度(重複数)を表示させる。

 例)
 A         B
 名前    頻度
 ○○○   6
 △△      4
 (多数)

要領)
1.同頻度数は同順位、以降の順位は繰下げない(1,1,1,2,2,3,4..)
2.重複が1個もないか最大2個以内の場合は、A列先頭行に「(なし)」と表示
3.名前の該当数が7個以上ある場合は以下による
 -1.1位のみで7個以上:A列先頭行に「(多数)」と表示
 -2.1位と2位で7個以上:1位の直後の行に「(多数)」と表示
 -3.1位〜3位で7個以上:2位の直後の行に「(多数)」と表示

説明)
・表示の対象は、重複3個以上です
・表示する名前の数は最大で6個となります
・データ数は200行程度まで

データにより表示する名前の数が都度変わるため、関数式ではムズかと
感じてますが、VBAは「超」初心者です。
VBA案であれば、実際のデータ列は数パターンあるので、どこの部分を
変更すればいいか、提示いただきたいです。

よろしくお願いします。

< 使用 Excel:Excel2010、使用 OS:Windows7 >


 1位〜4位(5位、6位・・・)の7個以上はどうすんの?
 
(GobGob) 2014/05/20(火) 17:59

 7以上の一番下位に「多数」を表示として。

	A	B	C	D
1	名前		名前	頻度
2	AAA		AAA	8
3	BBB		BBB	8
4	CCC		CCC	8    ←多数対象
5	AAA		DDD	7    ←多数対象
6	AAA		EEE	4
7	BBB		FFF	1
8	CCC			
9	DDD			
10	CCC			
11	EEE			
12	BBB			
13	AAA			
14	DDD			
15	AAA			
16	EEE			
17	FFF			
18	DDD			
19	DDD			
20	AAA			
21	AAA			
22	BBB			
23	BBB			
24	BBB			
25	BBB			
26	CCC			
27	DDD			
28	AAA			
29	BBB			
30	CCC			
31	CCC			
32	CCC			
33	EEE			
34	CCC			
35	EEE			
36	DDD			
37	DDD			

 C2 =IF(D2="","",INDEX(A:A,300-MOD(LARGE(INDEX(COUNTIF(A$2:A$200,A$2:A$200)*(MATCH(A$2:A$200&"",A$2:A$200&"",0)=ROW(A$2:A$200)-1)*1000+(300-ROW(A$2:A$200)),),ROW(A1)),1000)))&IF(AND(D2>6,COUNTIF(D$2:D2,D2)=COUNTIF(D:D,D2)),CHAR(10)&"(多数)","")
 D2 =IF(SUMPRODUCT((COUNTIF(A$2:A$200,A$2:A$200)*(MATCH(A$2:A$200&"",A$2:A$200&"",0)=ROW(A$2:A$200)-1)>0)*1)<ROW(A1),"",LARGE(INDEX(COUNTIF(A$2:A$200,A$2:A$200)*(MATCH(A$2:A$200&"",A$2:A$200&"",0)=ROW(A$2:A$200)-1),),ROW(A1)))

 C2:D2 下へコピー。
 
(GobGob) 2014/05/20(火) 18:15

 >上位3位までを順番に下記に示す要領でA,B列に「名前」と頻度(重複数)を表示させる。 
 >2.重複が1個もないか最大2個以内の場合は、A列先頭行に「(なし)」と表示 

 見逃し・・・w
 
(GobGob) 2014/05/20(火) 18:16

 他にもいろいろ見逃してましたわ―。

 とりあえず、オイラ回答保留でw
 
(GobGob) 2014/05/20(火) 18:20

(GobGob)さん、ありがとうございます。

1位〜3位が表示対象なので、1位〜3位の個数が合計7個未満であれば
1位〜3位のみ表示(4位以降は表示しない)となります。

よろしくお願いします。
(MECO) 2014/05/20(火) 18:24


 まだ途中だけど、とりあえず今日の回答は終了しますー。

	A	B	C	D	E
1	名前	作業列		名前	頻度
2	AAA	8298		AAA	8
3	BBB	8297		BBB	8
4	CCC	8296		CCC	8
5	AAA			(多数)	
6	AAA			DDD	7
7	BBB			(多数)	
8	CCC			EEE	4
9	DDD	7291		FFF	1
10	CCC				
11	EEE	4289			
12	BBB				
13	AAA				
14	DDD				
15	AAA				
16	EEE				
17	FFF	1283			
18	DDD				
19	DDD				
20	AAA				
21	AAA				
22	BBB				
23	BBB				
24	BBB				
25	BBB				
26	CCC				
27	DDD				
28	AAA				
29	BBB				
30	CCC				
31	CCC				
32	CCC				
33	EEE				
34	CCC				
35	EEE				
36	DDD				
37	DDD				

 B列作業列
  B2 =IF(COUNTIF(A$2:A2,A2)=1,COUNTIF(A:A,A2)*1000+(300-ROW()),"")

  D1 =IF(MAX(INDEX(COUNTIF(A$2:A$200,A$2:A$200),))>2,"名前","(なし)")
  E1 =IF(D1="(なし","","頻度")

  D2 =IF(E2="",IF(N(E1)>6,"(多数)",""),INDEX(A:A,300-MOD(LARGE(B:B,COUNT(E$2:E2)),1000)))
  E2 =IF(D$1="(なし)","",IF(COUNT(E$1:E1)<COUNT(B:B),IF(OR(N(E1)<7,COUNTIF(E$1:E1,E1)<>COUNTIFS(B:B,">="&MIN(E$1:E1)*1000,B:B,"<"&MIN(E$1:E1)*1000+1000)),INT(LARGE(B:B,COUNT(E$1:E1)+1)/1000),""),""))

 B2:E2 下へコピー。
 
(GobGob) 2014/05/20(火) 19:27

 ・・・ダメっぽいね。理解しきれてないかも?

 1.同頻度数は同順位、以降の順位は繰下げない(1,1,1,2,2,3,4..) 
 2.重複が1個もないか最大2個以内の場合は、A列先頭行に「(なし)」と表示 
 3.名前の該当数が7個以上ある場合は以下による 
  -1.1位のみで7個以上:A列先頭行に「(多数)」と表示 
  -2.1位と2位で7個以上:1位の直後の行に「(多数)」と表示 
  -3.1位〜3位で7個以上:2位の直後の行に「(多数)」と表示 

 > A         B
 >名前    頻度
 >○○○   6
 >△△      4
 >(多数)

 この例ね。1位と2位で7個以上になってるのになんで2位に下に「多数」なの?
 
(GobGob) 2014/05/21(水) 13:59

 やっぱり勘違いだね。

 A,B,C,D,E,F,Gさんが「5」づつ 、 H,Iさんが「4」づつ 、Jさんが「3」の場合

     A    B
 1  名前 頻度
 2   A    5
 3 (多数)
 4

 A,B,C,D,E,F,Gさんが「4」づつ 、 H,Iさんが「3」づつ 、Jさんが「5」の場合

     A    B
 1  名前 頻度
 2   J    5
 3   A    4
 4 (多数)

 A,B,C,D,E,F,Gさんが「3」づつ 、 H,Iさんが「4」づつ 、Jさんが「5」の場合

     A    B
 1  名前 頻度
 2   J    5
 3   H    4
 4   I    4

 A,B,C,D,E,F,Gさんが「3」づつ 、 Hさんが「4」 、Jさんが「5」の場合

     A    B
 1  名前 頻度
 2   J    5
 3   H    4
 4   A    3
 5 (多数)

 すべての人が「2」以下。

     A    B
 1  名前 頻度
 2 (なし)

 ・・・こういうこと?
 
(GobGob) 2014/05/21(水) 14:24

ありがとうございます。 質問がわかりづらくてすみません。
こっちの返答が間に合わず、何回も書き直しているところですが..^^;

「7個以上」は頻度の合計ではなく、該当する名前の合計です。

アウトプット(表示)は後処理の都合上、最大でも6個までとしたいです。

 A,B,C,D,E,F,Gさんが「4」づつ 、 H,Iさんが「3」づつ 、Jさんが「5」の場合

の例では、表示は「Jさんの後に(多数)」となります。

要は、ある(勝手に意味があると思っている)統計データに対して、
 何回も名前が挙がるヤツはひょっとして優良銘柄ではないか?、
 じゃあ、上位3位ぐらいまでをピックアップして追跡しよう、
 でも、あまり多数いたら使えないよなぁ〜

と、いうことをやりたいのですが..(説明になってない?^^;)

よろしくお願いします。

更に補足しますと、(スペースの都合上、名前のみ横書きします)
・A,B,C,D,E,F,Gさんが「5」づつ 、 H,Iさんが「4」づつ 、Jさんが「3」の場合
→(多数)...1位が7個以上で該当なし

・A,B,C,D,E,F,Gさんが「3」づつ 、 H,Iさんが「4」づつ 、Jさんが「5」の場合
→J,H,I,(多数)...7個以上になるので2位までが該当

・A,B,C,D,E,F,Gさんが「3」づつ 、 Hさんが「4」 、Jさんが「5」の場合
→J,H,(多数)...上と同じ

・すべての人が「2」以下。
→(なし)...提示のでOKです。

・A,B,Cさんが「3」づつ 、 H,Iさんが「4」 、Jさんが「5」の場合
→J,H,I,A,B,C...計6個までで3位まで該当

・A,Bさんが「5」づつ 、 Hさんが「4」 、Jさんが「3」の場合
→A,B,H,J...上と同じ

(MECO)

(MECO) 2014/05/21(水) 15:00


 アクティブセルのある列が名前がある列として集計します。
 1行目が見出しで、2行目からデータがあるものとしています。
 結果は常に A2:B8 に表示します。

 '------
Sub MECO1()
    Dim i As Long, ii As Long, MxR As Long, rr As Long, cnt As Long
    Dim frq As Long, MyColumn As Long
    Dim tbl As Variant, ky As Variant, x As Variant, r As Variant
    Dim dic1 As Object, dic2 As Object
Set dic1 = CreateObject("Scripting.Dictionary")
Set dic2 = CreateObject("Scripting.Dictionary")
ReDim r(1 To 7, 1 To 2)
MyColumn = ActiveCell.Column
MxR = Cells(Rows.count, MyColumn).End(xlUp).Row
If MxR > 4 Then
    tbl = Cells(2, MyColumn).Resize(MxR - 1).Value    
    For i = 1 To UBound(tbl, 1)
        If tbl(i, 1) <> "" Then
            dic1(tbl(i, 1)) = dic1(tbl(i, 1)) + 1
        End If
    Next
    For Each ky In dic1.Keys
        dic2(dic1(ky)) = dic2(dic1(ky)) & "," & ky
    Next
    If Application.Max(dic2.Keys) < 3 Then
        r(1, 1) = "(なし)"
    Else
        For i = 1 To Application.Min(dic2.count, 3)
            frq = Application.Large(dic2.Keys, i)
            If frq < 3 Then
                Exit For
            Else
                x = Split(dic2(frq), ",")
                cnt = cnt + UBound(x)
                If cnt < 7 Then
                    For ii = 1 To UBound(x)
                        rr = rr + 1
                        r(rr, 1) = x(ii)
                        r(rr, 2) = frq
                    Next
                Else
                    rr = rr + 1
                    r(rr, 1) = "(多数)"
                    Exit For
                End If
            End If
        Next
    End If
    Range("A2:B8").Value = r
End If
End Sub
 '------
  
(HANA) 2014/05/22(木) 10:27

(HANA)さん、ありがとうございます。

数パターンで確認させていただき、うまくいきましたっ!

すぐに実データの確認をする環境にないため、最終結果は
追って報告させていただきます。

VBA無知のため、誤解を含めチグハグな問いかけをするかも
知れませんが..先ずはお礼申し上げます。
(MECO) 2014/05/22(木) 21:42

追記)2014/5/23 (MECO)
ご提示案を使わせていただこうと思っていますが、若干仕様を変えたく、
どこを変更したらよろしいでしょうか?
1.出力先を、例えば「C5:D11」にする
2.データ列を、例えば「H列」(単列)に指定する
3.データ列を、例えば「H列〜M列」(複数列)に指定する
(この場合は、出力先も複数になりますが)

実データは処理したい列が6列ほどあり、将来増える可能性もあります。
処理の効率化では「3.」が理想ですが、あまりに複雑になるようなら
1.か2.のVBAを複数作って、「マクロの自動化」で結合するつもりです。

どの程度の変更になるかが思い浮かばないため、そのあたりの判断も
含めて、ご教授願えないでしょうか?

よろしくお願いします。


 名前のある列は決め打ちにしてます。
 結果は A:B列へ下方向に書き出します。
 '------
Sub 出現頻度の抽出()
    Dim MxR As Long, MyColumn As Long, MyOffset As Long
    Dim tbl As Variant
    Range("A:B").ClearContents
    For MyColumn = 8 To 13
        MyOffset = (MyColumn - 8) * 10
        Range("A1").Offset(MyOffset).Value = Application.Substitute(Cells(1, MyColumn).Address(0, 0), 1, "") & "列"
        Range("A2:B2").Offset(MyOffset).Value = Array("名前", "頻度")
        MxR = Cells(Rows.Count, MyColumn).End(xlUp).Row
        If MxR > 1 Then
            tbl = Cells(1, MyColumn).Resize(MxR).Value
            Range("A3:B9").Offset(MyOffset).Value = MECO2(tbl)
        Else
            Range("A3").Offset(MyOffset).Value = "データ無し"
        End If
    Next
End Sub
 '------
Function MECO2(ByVal tbl As Variant)
    Dim i As Long, ii As Long, rr As Long, cnt As Long
    Dim frq As Long
    Dim ky As Variant, x As Variant, r As Variant
    Dim dic1 As Object, dic2 As Object
Set dic1 = CreateObject("Scripting.Dictionary")
Set dic2 = CreateObject("Scripting.Dictionary")
ReDim r(1 To 7, 1 To 2)
    For i = 2 To UBound(tbl, 1)
        If tbl(i, 1) <> "" Then
            dic1(tbl(i, 1)) = dic1(tbl(i, 1)) + 1
        End If
    Next
    For Each ky In dic1.Keys
        dic2(dic1(ky)) = dic2(dic1(ky)) & "," & ky
    Next
    If Application.Max(dic2.Keys) < 3 Then
        r(1, 1) = "(なし)"
    Else
        For i = 1 To Application.Min(dic2.Count, 3)
            frq = Application.Large(dic2.Keys, i)
            If frq < 3 Then
                Exit For
            Else
                x = Split(dic2(frq), ",")
                cnt = cnt + UBound(x)
                If cnt < 7 Then
                    For ii = 1 To UBound(x)
                        rr = rr + 1
                        r(rr, 1) = x(ii)
                        r(rr, 2) = frq
                    Next
                Else
                    rr = rr + 1
                    r(rr, 1) = "(多数)"
                    Exit For
                End If
            End If
        Next
    End If
    MECO2 = r
End Function
 '------

 列を決めているのは
 >For MyColumn = 8 To 13
 部分です。

 H列が、A列から数えて8列目
 M列が、13列目ですので
 H:Mが処理対象です。
  
(HANA) 2014/05/23(金) 17:24

(HANA)さん、うまくいきましたっ! ありがとうございます!!
PCの前に座る時間がとれず礼が遅くなってしまいました。

 >列を決めているのは
 >For MyColumn = 8 To 13

データ列の増減はこれで“一発”ですね!

A1列に“列名”でなく実データの“項目名”を表示させる変更が???で、
数時間もかかりました。(トホホ..情けない)
が、ほぼ理想通りのことができそうで大満足です。

にしても、エクセルでこのようなことができるか半信半疑でしたが、
スゴイですね!(HANA)さん..(エクセルもですが^^;)
また、(GobGob)さんも貴重な時間、ありがとうございました。

これからもよろしくお願いします。

P.S.
これはここの管理人さんに聞くべきかも知れませんが..
この後、実データで使用中に生じた新たな変更なり疑問点は、
「新規登録」した方がいいのか本件を「継続」した方がいいのか
どちらでしょうか?

(MECO) 2014/05/26(月) 14:24


 >データ列の増減はこれで“一発”ですね! 
 そうですね!!

 もしも、データの配置がH列が先頭は変更なしで
 何列続くかのみが未定であれば
 For MyColumn = 8 To 13 
 を
 For MyColumn = 8 To Cells(1, Columns.Count).End(xlToLeft).Column
 に変更してもらうと良いかもしれません。

 Cells(1, Columns.Count).End(xlToLeft).Column は
 1行目の一番最後の列のセルを選択して [Ctrl] + [←] で移動した先の列番号になります。

 データの状況によっては H1セルから [Ctrl] + [→] の方が良いかもしれませんが
 その場合は、マクロの記録等でコードを確認してみて下さい。

 >実データで使用中に生じた新たな変更なり疑問点は
 自力で解決してもらえると良いですが。。。
 >「新規登録」した方がいいのか本件を「継続」した方がいいのか 
 は、人によって考え方が違うので難しい所だと思います。

 まだそんなにスレが長いわけじゃないので続けてもらっても良いのかな と思いますし
   もしもしばらく待っても誰からも返信が無ければ、一旦閉めて
   このスレへのリンクと共に、新たにたててもらうと良いかもしれません。
 それまでの経緯がしっかりまとめられていて、参考程度に前スレを参照すれば良いのなら
 新たにたててもらった方が、すっきりする様にも思えます。
 (新たな質問したい事が、どの様な事かはまだわかりませんが このスレの情報・・・やり取りも含め・・・が
  すべて必要な質問になるとは思えませんので。)

   時々、前スレのリンクは読んでもらう事を前提に 新しいスレで「○○にしたい」
   だけ書いてある投稿があったりしますが、私はスルーの方向で読ませてもらいます。
   あくまでも「私は」って事ですが。
  
(HANA) 2014/05/26(月) 14:56

再々ありがとうございます。
継続列が未定の場合もうまくいきました!
これは嬉しいかぎりです..

で、データの開始列を変更したい場合は、

 >For MyColumn = 8 To 13
 >       MyOffset = (MyColumn - 8) * 10
→この2行の「8」を変えればいいんですよね?
(試行ではうまくいっていますが..)

 >>実データで使用中に生じた新たな変更なり疑問点は
 >自力で解決してもらえると良いですが。。。
→そうですね、これ以上甘えるわけにはいかないかと、一応は
 自覚しておりますが(一応です..^^;)、 最後に

結果の表示先をA1から変える場合はどうなりますでしょうか?

大幅な改変になるようでしたら、これはスルーでも構いませんが、
よろしくお願いします。

(MECO) 2014/05/26(月) 18:34


 想定していないので 細かくいろいろ変更が必要ですが
 面倒なので こんな感じで。

 '------
Sub 出現頻度の抽出2()
    Dim MxR As Long, MyColumn As Long, MyOffset As Long
    Dim StrColumn As Long
    Dim tbl As Variant
    StrColumn = 8       'データ、8列目から
    With Range("A1")    '結果、A1セルから
        .Cells.EntireColumn.Resize(, 2).ClearContents
        For MyColumn = StrColumn To Cells(1, Columns.Count).End(xlToLeft).Column
            MyOffset = (MyColumn - StrColumn) * 10
            .Range("A1").Offset(MyOffset).Value = Cells(1, MyColumn).Value
            .Range("A2:B2").Offset(MyOffset).Value = Array("名前", "頻度")
            MxR = Cells(Rows.Count, MyColumn).End(xlUp).Row
            If MxR > 1 Then
                tbl = Cells(1, MyColumn).Resize(MxR).Value
                .Range("A3:B9").Offset(MyOffset).Value = MECO2(tbl)
            Else
                .Range("A3").Offset(MyOffset).Value = "データ無し"
            End If
        Next
    End With
End Sub
 '------

 結果表示列を変更したい場合は With Range("A1") の所を変更して下さい。
 また、リストと範囲が重複しない様に気を付けて設定して下さい。

 開始列を変更したい場合は StrColumn = 8 の所を変更して下さい。

 >A1列に“列名”でなく実データの“項目名”を表示させる変更
 は、変更してみましたので 確認してみて下さい。
  
(HANA) 2014/05/27(火) 13:29

すべてうまくいきました!!
いゃあ〜何とお礼を言ったらいいのか..もう完璧です!
実データでいろいろ活用できそうで、すごく楽しみです。

実データへの転用(移植?)はこれからになりますが、
こちらの不注意でせっかくの“宝物”をうっかり使い物に
ならないようにしない為と、将来自分で変更を加えられる
ように(できるか? ^^;)教えてください。

今回のマクロでは「Function MECO2」の記述がないですが、
これは一体?になっていると考えてよろしいでしょうか?

仮に先の提案マクロを「削除」してしまっても問題ないでしょうか?
あるいは、安心安全のため、先のマクロからそのまま今回マクロに
コピペしても差支えないものでしょうか?

まだまだマクロのしくみがわからず、自分で変更を..といいながら、
はなはだ低レベルな質問で何だか恥ずかしいですが、よろしくお願いします。

(MECO) 2014/05/27(火) 17:07


 MECO2は
 .Range("A3:B9").Offset(MyOffset).Value = MECO2(tbl)
 の行で使ってます。

 同じなので再掲載しませんでしたが 残しておいてください。
 出現頻度の抽出 が、出現頻度の抽出2 と差し替えです。

 MECO → MECO2 に変更
 出現頻度の抽出 → 出現頻度の抽出2 に変更。
 変更前のコード(MECO,出現頻度の抽出)は要りませんので、削除してもらって大丈夫です。
  
(HANA) 2014/05/27(火) 19:11

ありがとうございます。

初歩の“初”の部分で心苦しいのですが、最終的に何を残せばいいのかが
わかりません。(_ _;)

マクロの一覧を見ても、「MECO2()」は表示されません。
先のマクロを登録する時に「..抽出()」と「MECO2()」を一緒にコピペ
したからでしょうか?
※マクロ一覧で「..抽出()」の内容を見ると「MECO2」も記述されています

ところが、試しに「..抽出()」を削除して「..抽出2()」を実行しても
問題なくできます。

どこかに「MECO2」が存在しているのでしょうか?

(MECO) 2014/05/28(水) 13:40


 どこかに「MECO2」が存在していると思います。

 >最終的に何を残せばいいのか
 「出現頻度の抽出2」と「MECO2」です。

 出現頻度の抽出2のコード内にカーソルを置いた状態で
 [F8]を押してください。
 黄色くハイライトされた行が出来ると思います。
 [F8]を押すたびに、一行ずつコードが実行されます。

 ずっと進んでいくと
.Range("A3:B9").Offset(MyOffset).Value = MECO2(tbl)
 の所で、Function MECO2 に切り替わると思います。
 MECO2が終わったら、またこの行に戻ってきます。

 データ量を少なくして、確認してみて下さい。

 MECO2がマクロの一覧に表示されないのは
 Function MECO2 
 ~~~~~~~~ ここが、Functionになっているからです。

 たとえば、SUM関数だと =SUM(A1:B2) と書けば A1:B2の合計を返してくれます。
 今、MECO2は = MECO2(tbl) と書けば
 7行2列の表(結果)
      <1>      <2> 
  [1] ○○○   6
  [2] △△      4
  [3] (多数)
  [4]
  [5]
  [6]
  [7]
 を返してくれるようになっています。

 ↓を見てもらうと、イメージがつきやすくなるかもしれません。
https://www.excel.studio-kazu.jp/tips/0501/
 ライブラリ「エクセルの関数を作る」
  
(HANA) 2014/05/28(水) 16:57

(HANA)さん

手取り足取り、本当にありがとうございます。

しっかり学習したいと思います。

マクロがわからないまま実データで使用するのに、一抹の不安が
ないわけではないですが、先ずは実践します。 ^^;

これからもよろしくお願いします。
(MECO) 2014/05/29(木) 08:24


 ステップインで実行中に、変数等の近くにポインタを持っていてしばらく待つと
 どの様なデータを処理しているのか 確認出来ます。

 それらを見ながら、コードを読んで行ってもらうとわかりやすいかもしれません。

 MECO2の方は簡単ではありますが、イメージを書いてみます。
    For i = 2 To UBound(tbl, 1)
 のループで、それぞれの人が何回出てくるか数えます。
        <1>     <2> 
    [1] 名前    回数
    [2] ○○○   6
    [3] △△      4
     [4]  □□□    6

    For Each ky In dic1.Keys
 のループで、今度は 回数毎に 名前をまとめます。
        <1>     <2> 
    [1] 回数    名前
    [2]   6     ,○○○,□□□
    [3]   4     ,△△
     [4]

    If Application.Max(dic2.Keys) < 3 Then
        r(1, 1) = "(なし)"
 <1>回数の列の最大値が、3未満だったら【すべての人が「2」以下。】なので(なし)を表示します。

        For i = 1 To Application.Min(dic2.Count, 3)
 この i は、後で i目に多い(回数が大きい)値 を取得するのに使います。
            frq = Application.Large(dic2.Keys, i)
 ここで、変数:frqに <1>回数の列でi番目に大きい値を代入します。
 ・・・iが「1」だったら、1番大きい値ですので、例では「6」です。
            If frq < 3 Then
                Exit For
 <1>回数の列でi番目に大きい値が3未満だったら それ以上書き出さないので ループを抜けます。
 3以上だったら
                x = Split(dic2(frq), ",")
 変数xに、frqの値に対応する名前を「,」で区切って入力します。
 ・・・frqが「6」の場合、対応する人は ,○○○,□□□ なので(<1>が6の行の<2>の列の値の事です。)
        <0>   <1>     <2> 
    [1]        ○○○ □□□
    って感じです。

                If cnt < 7 Then
 名前の数が7未満であれば、
                        r(rr, 1) = x(ii)
 変数rrの1列目に名前
                        r(rr, 2) = frq
 変数rrの2列目に何回出たか を代入します。
                Else
 名前の数が7以上だったら(多数)を表示して、名前を書き出すループ処理を終わります。

 MECO2がすべて済むと、変数rに結果が入ってるので
    MECO2 = r
 として、元のコードに戻ります。

 表組は説明の為のイメージとしてとらえて下さい。
 また、端折っている部分も多々ありますので 注釈のない部分の処理は
 解析してみてもらうと良いと思います。
  
(HANA) 2014/05/29(木) 10:09

またまた、ご厚意ありがとうございます!!
おぼろげながらですが、何を(=お考え)記述されているかは
イメージができつつあります。

問題は構文?(文法??−記述のしかた、決まり事)ですかね..
これはさすがに一朝一夕ではいかないですよねぇ〜
地道に学習していくしかないですね..

ただ、自分でマクロを記述できなくても、マクロをみて
ある程度何をやっているか判断できるレベルになれば、
ここのみなさんの“知恵=お力”を借りるのも“手”かな..
とも思っています。 ^^;(これは関数式でも同じです)

ちょっと本題から脱線しますが、実はあるデータ処理を
多くの「関数式」と「リンク貼付け」でしているのですが、
どうにもエクセルが重く(処理が遅い)閉口しています。

このような場合、マクロで解決(処理を早める)ことは可能なんでしょうか?
一般論で構いませんので、ご見解をいただけたら嬉しいです。

よろしくお願いします。

(MECO) 2014/05/29(木) 18:31


 構文なんかは、やりたいことが決まっていて
 それについて調べ、作成することを繰り返してたら
 基本的なものはすぐに身につくと思います。

 >どうにもエクセルが重く(処理が遅い)閉口しています。 
 一般論で良いと言う事であれば、可能だと思います。

 問題は、何の処理が重いのか だと思います。

 「どこかに入力するたびに再計算されて重い」
 であれば、計算方法を手動にして入力し、入力後に再計算させるのでも良いかもしれません。

 「めったに入力はしないんだけど、数式のせいで開くのが遅い。ブックが大きい」
 であれば、簡単なのは 数式を必要範囲に入力後値化
 (手作業であれば、数式を入力して、コピーして、すかさず値貼付)
 すれば、値だけのデータになります。

 通常のマクロは、実行ボタンを押さないと結果が出ませんが
 数式だと 関係セルの値を変更したらすぐに結果が出ています。
   もちろん、マクロでもイベント処理等ありますが。
 結果が出るタイミングにどの様な配慮が必要か と言うのも
 問題になってくるかもしれません。
  
(HANA) 2014/05/30(金) 09:24

 >構文なんかは(略)基本的なものはすぐに身につくと思います
→う〜ん、結構ハードルが高いように思いますが ^^;、徐々にチャレンジ
 したいと思います..

エクセルの処理速度の件、ブックを開く時とコピペやフィルタ操作など、
あらゆる操作が遅くなっている印象です..−−;
で、今はブックを開いた後にシート全体を別ブックに「値のみコピペ」
して作業しています。
※他ブックからのリンク貼付けにより、新規のデータ入力は一切していません

 >何の処理が重いのか だと思います
→そうですね、一応、ある関数式を入れてから遅くなっているので、
 それがアヤシイと考えてますが、もう少し精査したいと思います。

マクロで改善できる可能性があるようですので、質問内容を整理して
新規投稿させていただこうかと考えています。
※欲しいアウトプットに対し、途中の関数式が10列以上あります。
 一気のマクロ化は説明も難しいですし、的を絞りたいと思います..

今回の投稿では、いろいろと学ばせてもらいました。
貴重なお時間、本当にありがとうございました!!

これからもよろしくお願いします。

(MECO) 2014/05/30(金) 13:25


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.