• ベストアンサー

【Excel】 組み合わせ

A B C という行があった場合 A B C A C B B A C B C A C A B C B A というように 組み合わせを出力する マクロを作りたいのですが どのようにすればよいのででしょうか? よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

順列のアルゴリズムは、0から自分で考えようとすると微妙にムツカシイ気がします。ただこれ自体有名なものなので、まずはそれに倣って組みながら仕組みを理解していくと良いです。 大まかな考え方は、『最小(または最大)の組み合わせから、1つずつ大きい(または小さい)ものを取り出していき、最後に最大(または最小)のもを取り出す』ような操作を考えます。 VBAでは文字列の大小の比較も出来てしまうのでこのあたりは何も考えなくて大丈夫です。 もう少し具体的にはどうなるかというと、A B Cであれば最小の並びになっていますが、とりあえずは最小の並びを作ります。 ここから、1つ大きい組み合わせを考えますが、ここにちょっとくせがあります。操作は以下の通りです。 1:一番右の値を【基点】にする 2:【基点】と【基点】の1つ左隣の値を比較して、【基点】のほうが大きいかをチェックする 3:2が成り立てば6へ 4:2が成り立たなければ、【基点】を1つ左へ移す 5:【基点】が一番左にきたら終了(これ以上大きいものはない) 6:【基点】の1つ左の値と、【基点】より右(【基点】含む)にある値の内最大のものを、【基点】の1つ左の値と交換する 7:【基点】より右(【基点】含む)にある値で最小の順列を作りこのとおり並び替える 8:2に戻る 微妙に面倒です。ただこの通り組めばできます。 一応組みました。値はA1に書き込んでください。その後はB列に書き出します。A列の値が大きいとめちゃくちゃ時間かかります。 Option Explicit Type cordinate Number As Variant Order As Byte End Type Function get_permutation() Rem データ格納変数:Cordinate型 Dim memory() As cordinate Rem 汎用関数:Cordinate型 Dim dummy As cordinate Rem カウンタ変数 Dim count, check_count, i, j, k As Byte Rem 桁数 Dim num As Byte Dim ans As Variant num = Len(Range("a1").Value) Rem num個分の配列 ReDim memory(num) Dim total_counter, counter As Variant Dim sub_counter As Byte Rem 初期化--ここから---------------------------------- For i = 0 To num - 1 memory(i).Number = Mid(Range("a1").Value, i + 1, 1) memory(i).Order = i + 1 Next Rem 最小の組み合わせに並べ替える For i = 0 To num - 2 For j = 0 To num - 2 If memory(j).Number > memory(j + 1).Number Then dummy = memory(j) memory(j) = memory(j + 1) memory(j + 1) = dummy End If Next Next Rem 最小の組み合わせ出力 For i = 0 To num - 1 ans = ans & memory(i).Number Next Range("b1").Value = ans ans = "" Rem msgbox ans Rem 初期化--ここまで---------------------------------- count = num - 1 counter = 1 Rem 最小の組み合わせから初めて、現在の組み合わせよりも大きくてかつ最も近い組み合わせを検索し、 _ この繰り返しで最大値に至るようにループさせる。 Do While i If memory(count).Number > memory(count - 1).Number Then Rem msgbox count total_counter = total_counter + 1 dummy = memory(count) check_count = count If count <> num - 1 Then For i = count To num - 1 If dummy.Number > memory(i).Number And _ memory(i).Number > memory(count - 1).Number Then dummy = memory(i) check_count = i End If Next memory(check_count) = memory(count - 1) memory(count - 1) = dummy For i = count To num - 2 For j = count To num - 2 If memory(j).Number > memory(j + 1).Number Then dummy = memory(j) memory(j) = memory(j + 1) memory(j + 1) = dummy End If Next Next Else dummy = memory(num - 1) memory(num - 1) = memory(num - 2) memory(num - 2) = dummy End If count = num - 1 ans = "" For i = 0 To num - 1 ans = ans & memory(i).Number Next Range("b1").Offset(total_counter, sub_counter).Value = ans counter = counter + 1 If total_counter > 65534 Then total_counter = 1 sub_counter = sub_counter + 1 End If Else count = count - 1 If count = 0 Then Exit Do End If End If Loop MsgBox counter end function

その他の回答 (3)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

参考になるかどうかは分かりませんが、ここのサイトで、Visual Basic で、「順列」という語で探してみました。 http://oshiete1.goo.ne.jp/qa2113807.html ↑ これが、よい(ただし、質問自体に無理はあります) http://oshiete1.goo.ne.jp/qa1537159.html (これは意味が少し違いますが、私の書いた内容で、途中までで使えるはずです。別所途で解答したこともありますが、最初のURLの方式と時間比べをして負けてしまいました。)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんにちは。 #1さんに補足ですが、順列は、ここのカテゴリやVBカテゴリでも出ています。私は、以前は公開していたのですが、最近は、この質問の回答は控えるようにしています。これは、パスワード解除のために使用されることもあるからです。 本当に、マクロやVBAを勉強しようという気持ちがあるなら、インターネット検索すれば、入手できるはずで、Q&Aで、そのままお渡しするというのはしておりません。また、#1さんのおっしゃっているのは、順列のアルゴリズムですが、それを扱うレベルは、ひととおり、VBA卒業のレベルで、また、この種のものが分からない場合、必ず、Google検索で、調べてほしいです。ただし、順列で、VBAでは、必ずしも、「再帰」を使うかどうかは、なんとも言えません。単にループでもよいはずです。 また、組み合わせのアルゴリズムは、一部の方が非公開にしているようですので、こちらも基本的には公開はしないようにしております。ご質問は、どうやら順列のようですが。

yn001ster
質問者

お礼

私の検索の仕方が悪かったようです。 検索したのですが、有料のExcelマクロしか見つけられませんでした。 私の欲しいのはあくまでキーワードの順列だったようですね。 見つからないはずですね。 ありがとうございます。

  • Dxak
  • ベストアンサー率34% (510/1465)
回答No.1

お答え付きませんね^^; 「組み合わせ」と称しているのは、「順列」と言い、国語辞書だと「組み合せと」逆に位置する言葉になります で、こういうマクロは、再帰アルゴリズムを使用して、「順列の挙列」を行うのですが、考えるのに時間が掛るかなと思ったら・・・ 過去の質問で、いくつか回答が出てますので、「順列 再帰」で検索してみてください

yn001ster
質問者

お礼

ありがとうございます。 いろいろと難しそうですね がんばってみます!

関連するQ&A

  • Excel2007で組み合わせ

    Excel2007で記号の組み合わせの計算がしたいです。パターンの出力と言うんですかね?ちょっとその辺の単語力に乏しいのですが…。 質問させていただきます。 A列、B列、C列、D列の10行目までにアイウエオカキクケコのいずれかがが各セルに入ってます。 この場合は全部で1万通りになるんですがそのパターンをF列に並べてからそのパターンの数をF列の先頭で隣のG列に表したいたいです。 誰か教えて下さい。お願いします。

  • Excel2007で組み合わせの計算

    Excel2007で記号の組み合わせの計算がしたいです。パターンの出力と言うんですかね?ちょっとその辺の単語力に乏しいのですが…。 質問させていただきます。 A列、B列、C列、D列の10行目までにアイウエオカキクケコのいずれかがが各セルに入ってます。A列×B列×C列×D列 この場合は全部で1万通りになります。 できたパターンをF列に一通りずつ(できるならまとめて一発ででもいいのですが)上から入れていき、 F列のパターンの入った先頭セルの隣のセルGに10000通りと表したいたいです。 教えて下さい。

  • 組み合わせをすべて出力したい

    c sharp環境です。 フレームワークは.net 4.5.2になります。 組み合わせを全パターン出力したいと思ってます。 例: A B C 出力したいパターン: A B C A C B B A C B C A C A B C B A 組み合わせが3つであればいいのですが、実際には最大で6つの文字の 組み合わせ全パターンを出力する必要があります。 (文字の数は動的なので、1~6まであります) 例:A B C D E F linqなどを活用すれば簡単にできるものでしょうか? 泥臭くループを続けていく方法しか思い浮かびません。 良いやり方がありましたら、教えてください。 よろしくお願いします。

  • Excelですべての組合せ(重複組合せ)を出力するには?

    Excelですべての組合せ(重複組合せ)を出力するには? 次の条件のような場合、Excelですべての組合せ(重複組合せ)をVBAで出力するにはどうしたらいいのでしょうか? 10種類のお菓子の中から、好きなものを3個選んでセットにするとします。 同じものを複数選ぶのはありですが「菓子A、菓子B、菓子C」と「菓子B、菓子C、菓子A」は選んだ順が違うだけで同じ組合せなので、どちらか片方だけにします。 この場合、すべての組合せの数は Excelの関数で求めることができるようで COMBIN(10+3-1,3) = 220 通りあることまではわかりましたが、このすべての組合せの一覧をどのようにして出力したらいいのかがわかりません。 いろいろ検索した結果、順列という方法は見つかりましたが、重複組合せでの方法は見つけることができませんでした。 また、Accessを使っても似たようなことができるのでしょうか? 直積? できれば、3個固定ではなく5個の場合も出来るとうれしいです。 よろしくお願いします。

  • エクセル マクロ 組み合せ

    エクセルのマクロでa,b,c,d,e,f,g の2組合せ (7C2)の全組合せを洗い出して表示したいですが、、、、、、

  • エクセルで組合せを求めたい

    A列B列にa~Zまでの任意一文字が5000行まで入力されているとします。 たとえば A1=a、B1=b A2=y、B2=z などと入力されていると仮定してください。5000行もあるので、A列B列が同じ組合せが出現します。 この組合せが同じ行を検索したいのですが、厄介な条件があって(a、b)の組合せと(b、a)は同じ組合せと見なしたいのです。 どなたかご教示下さい。

  • 組み合わせの計算

    6人の中で4人組を作る場合、何通りの組み合わせができるのでしょうか? (A-B-C-DとD-C-B-Aのようなものは同じ組み合わせとします) 書き出したところ、15通りになりましたが、合っているかどうかわかりません。 また、組み合わせの計算方法がありましたら教えてください。 よろしくお願いします。

  • Excelで組み合わせ

    Excel2007で記号の組み合わせの計算がしたいです。パターンの出力と言うんですかね?ちょっとその辺の単語力に乏しいのですが…。 質問させていただきます。 A列、B列、C列、D列の10行目までにアイウエオカキクケコのいずれかがが各セルに入ってます。A列×B列×C列×D列 4個×5個×3個×6個=360通り 何通りでもいいのですが できたパターンをF列に一通りずつ(できるならまとめて一発ででもいいのですが)上から入れていきたいです。全部4文字固定です ご協力お願いします。

  • Excel2000での列集計

    過去の質問では見つからず、初めて質問させていただきます 【質問】 Code1 Code2 Name 1 2 3 4 5 6 7~               月    ~   日 月    ~   日 a1   111  あ    A A            A a1   111  あ                 B B a1   111  あ      C C C      C a2   222  い                   A A a2   222  い    B B a2   222  い      C C          C C a2   222  い                   D a3   333  う    A A a3   333  う                 B   ・   ・ 上の1年分のデータ表を下記のような週毎に月曜日のみ残した表にその週にあるデータ(文字列)を月の列に集め、空白の行は上に詰めて表示させ、詰めたことによって全ての月曜日の列(1年分)にデータの無い行は削除したい Code1 Code2 Name  1  8 ~                月 月 a1   111  あ     A A a1   111  あ     C B a1   111  あ       C a2   222  い     B A a2   222  い     C C a2   222  い       D a3   333  う     A B   同人の行の中ではひとつの行には同じデータしかない "あ"の3行はA行B行C行になっています "い"の4行中には、またABCそれぞれの行があり加えてD行もある "う"の行はAとBのみなので行が少ない 関数でも試したのですが無理で、マクロでしかできないのではと思っています。 マクロは良く分からないのでお分かりになる方教えて下さい。お願いします。

  • Office 2000 Excel マクロについて

    A1=A A2=B A3=C A4=A A列がAの行だけを表示させたい場合は、どのようなマクロを組めば良いのでしょうか? ご教示よろしくお願いいたします。

専門家に質問してみよう