[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『組合せ作成』(亜美ちゃん)
ABC ABC ABC の組合せ簡単に作成したいのですがいい方法ありませんでしょうか。 INIDRECT関数と&を使ってできそうな気がするのですが・・・ ちなみにAAA AAB AAC ABA ACA・・・CCC まで作成したいのですがいちいち入力が 大変ですし、間違いがあるかもしれないのでよろしくお願いいたします。 例では3つのグループで3*4*3種類なのですが 実際は4つのグループで40*70*40種類作成しなければならないのです。 XP-SP2,2003使用です。
不得意な分野なので、取りあえずご質問の内容だけ確認させてください。
>例では3つのグループで3*4*3種類なのですが
何が3つのグループなのですか? 3*4*3のそれぞれの意味は?
私には、一つのグループで、3*3*3 (全27種類)に思えるのですが。
<追記> カキコしたあとで、気がついたのですが、
第1ABC、第2ABC、第3ABC で3つのクループと云うことですか?
しかし、3*4*3だとすると 第1はABC、第2はABCD、第3はABC ではないですか? ↑ つまり、ここは"D"では?
それが正しいとすると、実際は 40*70*40ですから、全112,000種類と云うことになりますか?
(半平太)
すみません 第1はABC、第2はABCD、第3はABC ではないですか ご指摘のとおりです。 実際は 40*70*40ですから、全112,000種類ということです。
> 実際は 40*70*40ですから、全112,000種類ということです。
あまりの量に逃げ出し寸前です。取りあえずの案(バージョンは、XL2007を想定しています)。
1.A、B、C 各列一行目に「1」と入力
2.式の入力 (1) A2セル =IF(AND(B1=70,C1=40),A1+1,A1) (2) B2セル =IF(C1=40,IF(B1=70,1,B1+1),B1) (3) C2セル =MOD(ROW(A2)-1,40)+1
2行目の式を112,000行目までコピー
行 _A_ _B_ _C_ 1 1 1 1 2 1 1 2 3 1 1 3 4 1 1 4
(半平太)
こんな塩梅でどうでせう。(ROUGE) '---- Sub test() Dim txt1 As String, txt2 As String, txt3 As String Dim x, y, z, tbl() Dim i As Long, ii As Long, iii As Long, n As Long, m As Long txt1 = Application.InputBox("組み合わせに使用する文字を" & Chr(10) _ & "「,」区切りで入力してください。", "その1", Type:=2) txt2 = Application.InputBox("組み合わせに使用する文字を" & Chr(10) _ & "「,」区切りで入力してください。", "その2", Type:=2) txt3 = Application.InputBox("組み合わせに使用する文字を" & Chr(10) _ & "「,」区切りで入力してください。", "その3", Type:=2) x = Split(Replace(txt1, ",", ","), ",") y = Split(Replace(txt2, ",", ","), ",") z = Split(Replace(txt3, ",", ","), ",") m = 1 ReDim tbl(1 To WorksheetFunction.Min(Rows.Count, (UBound(x) + 1) * (UBound(y) + 1) * (UBound(z) + 1)), 1 To 1) For i = 0 To UBound(x) For ii = 0 To UBound(y) For iii = 0 To UBound(z) n = n + 1 If n > Rows.Count Then n = 1 m = m + 1 ReDim Preserve tbl(1 To UBound(tbl, 1), 1 To UBound(tbl, 2) + 1) End If tbl(n, m) = x(i) & y(ii) & z(iii) Next iii Next ii Next i Cells.ClearContents Range("A1").Resize(UBound(tbl, 1), UBound(tbl, 2)).Value = tbl Erase tbl, x, y, z End Sub
新規ブックの標準モジュールに
'============================================================ Sub main() Dim idx As Long Dim g0 As Long Dim wk As Variant Dim ans() As Variant ' ↑組み合わせメンバーを取得する配列 Dim rng As Range ' ↑組み合わせセル範囲
Call サンプル作成
Set rng = Range("a1").CurrentRegion Call ttlhit_init(rng.Columns.Count) For g0 = 1 To rng.Columns.Count With rng.Cells(1, g0) Call ttlhit_add(Range(Cells(1, .Column), Cells(Rows.Count, .Column).End(xlUp))) End With Next idx = 10 ReDim ans(1 To rng.Columns.Count) Do While ttlhit_get(ans()) = 0 wk = "" For g0 = LBound(ans()) To UBound(ans()) wk = wk & ans(g0) Next Cells(idx, 1).Value = wk idx = idx + 1 Loop MsgBox "以上" & idx - 10 & "通り" Call ttlhit_term End Sub '============================================================ Sub サンプル作成() Cells.ClearContents Range("a1:d1").Value = [{"a","a","a","a"}] Range("a2:d2").Value = [{"b","b","b","b"}] Range("a3:d3").Value = [{"c","c","c","c"}] Range("d4").Value = "d" MsgBox "サンプル作成 セルA10から処理を開始します" End Sub
別の標準モジュールに組合せ処理ルーチン
Private ttl_rng() As Range Private ttl_idx() As Long Private ttl_a_num As Long '=================================================================== Sub ttlhit_init(hitnum As Long) '組合せ処理の開始宣言 'input : hitnum 抜き取り数 Dim g0 As Long Erase ttl_rng() Erase ttl_idx() ReDim ttl_rng(1 To hitnum) ReDim ttl_idx(1 To hitnum) For g0 = LBound(ttl_idx()) To UBound(ttl_idx()) ttl_idx(g0) = 1 Next ttl_idx(UBound(ttl_idx())) = 0
ttl_a_num = 0 End Sub '====================================================================== Sub ttlhit_add(rng As Range) '組合せ標本セル範囲の登録 'input : rng 連続したセル範囲 Set ttl_rng(ttl_a_num + 1) = rng ttl_a_num = ttl_a_num + 1 End Sub '====================================================================== Function ttlhit_get(ans()) As Long '組み合わせメンバーを配列に出力する 'output: ans() メンバの配列 ' ttlhit_get:0 -- 正常に配列取得 ' 1 -- メンバの終わり Dim g0 As Long ttlhit_get = 1 For g0 = UBound(ttl_idx()) To LBound(ttl_idx()) Step -1 If ttl_idx(g0) + 1 <= ttl_rng(g0).Count Then ttl_idx(g0) = ttl_idx(g0) + 1 ttlhit_get = 0 Exit For Else ttl_idx(g0) = 1 End If Next If ttlhit_get = 0 Then For g0 = LBound(ttl_idx()) To UBound(ttl_idx()) ans(g0) = ttl_rng(g0).Cells(ttl_idx(g0)).Value Next End If End Function '====================================================================== Sub ttlhit_term() '組合せ処理に終了 Erase ttl_rng() Erase ttl_idx() ttl_a_num = 0 End Sub
予め組合せ処理部分を再利用可能にしておくと 同じような事象に対応できると思いますよ!! (私は、よくクラス化(オブジェクト)して利用しています) 尚、列が増えてもコードの変更は殆ど要らないと思います。
ichinose
これは一体何のデータでっしゃろ? スポーツでは無いみたいやし、薬品混合の臨床データ? それとも金属強度テストの データ? ま、それはともかく、Sheet2でグループ分けしたデータをSheet1に標本別に取り出す マクロをROUGEせんぱいの工法をパクリながら作成してみました。 Sheet2のデータをこんな塩梅に並べて実行しませう。 A B C D E 1 Aグループ Bグループ Cグループ Dグループ Eグループ 2 標本A1 100g C1 D1 E1 3 標本A2 120g C2 D2 E2 4 標本A3 130g C3 D3 E3 5 ... ... ... ... ... 6 ... ... ... ... ... 7 ... ... ... ... ... 8 ... ... ... ... ... . ... ... ... ... ... . . (弥太郎) '-------------------------- Sub Get組合せ() Dim i As Long, n As Long, m As Integer, Cnt As Long, u As Integer, x(), tbl, y() Dim ii As Long, iii As Long, iiii As Long, iiiii As Long, b As Integer With Sheets("sheet2") b = StrConv(InputBox("グループ数はなんぼでっか?"), vbNarrow) tbl = .Cells(2, 1).Resize(.Range("a:" & Chr(64 + b)). _ Cells.Find("*", , , , xlByRows, xlPrevious).Row - 1, b) End With For u = 1 To b For i = 1 To UBound(tbl, 1) If Not IsEmpty(tbl(i, u)) Then ReDim Preserve y(i - 1) y(i - 1) = tbl(i, u) End If Next i ReDim Preserve x(u - 1) x(u - 1) = y If u > 2 Then Cnt = IIf(Cnt = 0, (UBound(x(u - 2)) + 1) * (UBound(x(u - 1)) + 1), _ Cnt * (UBound(x(u - 1)) + 1)) Next u Application.ScreenUpdating = False ReDim tbl(1 To IIf(Cnt > 60000, 60000, Cnt), 1 To UBound(x) + 1) With Sheets("sheet1") .Cells.ClearContents For i = 0 To UBound(x(0)) For ii = 0 To UBound(x(1)) For iii = 0 To UBound(x(2)) Select Case u - 1 Case 3 Call work(u, n, tbl, m, Cnt) For b = 1 To 3 tbl(n, b + m) = x(b - 1)(IIf(b = 1, i, IIf(b = 2, ii, iii))) Next b Case 4 For iiii = 0 To UBound(x(3)) Call work(u, n, tbl, m, Cnt) For b = 1 To 4 tbl(n, b + m) = x(b - 1)(IIf(b = 1, i, IIf(b = 2, ii, _ IIf(b = 3, iii, iiii)))) Next b Next iiii Case 5 For iiii = 0 To UBound(x(3)) For iiiii = 0 To UBound(x(4)) Call work(u, n, tbl, m, Cnt) For b = 1 To 5 tbl(n, b + m) = x(b - 1)(IIf(b = 1, i, IIf(b = 2, ii, _ IIf(b = 3, iii, IIf(b = 4, iiii, iiiii))))) Next b Next iiiii Next iiii End Select Next iii Next ii Next i .Cells(1, 1).Offset(, m).Resize(, u - 1) = Sheets("sheet2").Cells(1, 1).Resize(, u - 1).Value .Cells(2, 1).Resize(UBound(tbl, 1), UBound(tbl, 2)) = tbl End With Application.ScreenUpdating = True End Sub Sub work(u, n, tbl, m, Cnt) n = n + 1 If n > UBound(tbl, 1) Then With Sheets("sheet1") .Cells(1, 1).Offset(, m).Resize(, u - 1) = Sheets("sheet2").Cells(1, 1).Resize(, u - 1).Value n = 1 m = m + u ReDim Preserve tbl(1 To UBound(tbl, 1), 1 To UBound(tbl, 2) + u) End With End If End Sub
ちょとしゅうせぇ^^ (弥太郎)5/7 10:04
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.