| 
    
     |  | ゆか さん、皆さん、こんばんは。 
 
 >エクセル初心者です。
 >例えば、A、B、C、D 4つのアルファベットを、二組に分けたものの組み合わせを全て表示させるようなプログラムを作りたいのですが、探してもアイデアが見つかりません。
 >どなたかわかる方教えてください。
 この問題は、組合せリストを作成するアルゴリズムがネックですよね!!
 例えば、例題のようにメンバがA、B、C、Dの場合だと
 A組 : B組のメンバ数が
 1 : 3
 2 : 2
 
 という組合せがあります。
 
 1:3の場合は、Combin(4,1)=4の組合せ数になりますが、
 2:2の場合は、Combin(4,2)/2=3の組合せ数になりますよね?
 (Combinについては、ワークシート関数を参照して下さい)
 基本的には、総リストから1を選ぶ組合せ、2つを選ぶ組合せのリストを作成し、
 残ったメンバがもう一組のメンバと言う事になりますが、
 
 既に投稿されいるように
 
 1:3の場合は、4つから1つを選ぶ組合せリストを作成すると
 残り
 A    BCD
 B    ACD
 C    ABD
 D    ABC
 
 でも、2:2の場合は、4つから2つを選ぶ組合せリストを作成すると
 
 4つから2つを選ぶ組合せリストを作成すると
 残り
 1 AB    CD
 2 AC    BD
 3 AD    BC
 4 BC    AD
 5 BD    AC
 6 CD    AB
 
 とダブりが生じるのでここの工夫が必要ですが、これは帰納的な発想をすると、
 上記の1(AB)と6(CD)、2と5、3と4 という組を形成できます。
 
 「アイデア」とあったので、全部のコードは載せませんが、
 組合せだけ・・・・。
 実は、組合せはここのサイトで以前にも質問がありまして、
 
 http://www.vbalab.net/vbaqa/c-board.cgi?cmd=one;no=16249;id=excel
 
 こんな方法でも可能だし、場合によっては、これの方が都合の良い事も有るのですが、
 私の勉強も兼ねて別解で作りました。
 
 '============================
 Sub test()
 Dim 組合せ
 組合せ = combin_list(Array("a", "b", "c", "d"), 2)
 Range(Cells(1, 1), Cells(UBound(組合せ, 1) - LBound(組合せ, 1) + 1, 2)).Value = 組合せ
 End Sub
 '========================================
 Function combin_list(総リスト, 抜取り数, Optional ByVal nest As Long = 0, Optional ByVal st As Long = 0)
 '組合せリストを作成する
 'input :総リスト----組合せリストを作成する元リスト(1次元の配列)
 '    抜取り数----組合せ抜取り数
 ' nest及び、stは、指定不可 内部で使用するパラメータ
 'output:combin_list---組合せリスト2次元配列
 Static ans()
 Static idx() As Long
 Static jdx As Long
 If nest = 0 Then
 jdx = 0
 ReDim idx(抜取り数 - 1)
 ReDim ans(WorksheetFunction.Combin(UBound(総リスト) - LBound(総リスト) + 1, 抜取り数) - 1, 抜取り数 - 1)
 st = LBound(総リスト)
 End If
 For idx(nest) = st To UBound(総リスト)
 If nest < 抜取り数 - 1 Then
 Call combin_list(総リスト, 抜取り数, nest + 1, idx(nest) + 1)
 Else
 For kdx = 0 To 抜取り数 - 1
 ans(jdx, kdx) = 総リスト(idx(kdx))
 Next kdx
 jdx = jdx + 1
 End If
 Next
 If nest = 0 Then
 combin_list = ans()
 End If
 End Function
 
 これでnCrの組合せリストの作成は可能です。
 
 後は、呼び出し元で、抜取り数が1のとき、2のときの残りのメンバを作成する方法
 を上記を参考にして考えてみて下さい。
 
 |  |