
例えば、整数型配列a(6)={1,2,3,4,5,6}があったとして、
この中から2つ取り出し、その積と、残りの4つの数の積を求める
マクロを作りたいと考えております。
具体的に言いますと、まず{1,2}を選んだとすると、セルA1に1×2=2が入り、
セルB1に3×4×5×6=360が入るようにしたいです。
同種の質問等を検索した結果、
2つ取り出すときの組み合わせは、再起処理で可能だとは思うのですが、
それと同時に、残り4つの数の積を求めるには、
どうのようにしたら良いのでしょうか?
組み合わせの求め方を含んだ形で、ご教授頂けたら幸いです。
よろしくお願いいたします。
No.4ベストアンサー
- 回答日時:
本当は、数学的に解決する方法があるだろうけれども、以下は、結構、ネット内では知られた古くからあるアルゴリズムです。
ただ、VBAの実務的には、#1さんの書かれた内容のほうが上なのでした。以下は、一旦、組み合わせをアルゴリズムで作った後に、その残った補完数を羅列しただけで、後は、Product 関数で計算しました。単に、アルゴリズムにこだわっただけのコードです。
'//
Option Explicit
Sub MakingCombin()
Dim Stock As Variant
Dim i As Long
Dim r_PICK
r_PICK = 2 '抽出数
Stock = Array(1, 2, 3, 4, 5, 6) '配列ストック
ActiveSheet.UsedRange.ClearContents 'データを消す
'実行
Call sCombinations(Stock, r_PICK)
End Sub
Private Sub sCombinations(ByVal Stock, ByVal r As Long)
Dim num As Long
Dim ar As Variant
Dim ar_sp As Variant
Dim i As Long, j As Long
Dim k As Long, t As Long
Dim rOrg As Long
rOrg = r 'もとの抽出数を保管
num = UBound(Stock) - LBound(Stock)
r = r - 1
ReDim ar(0, r)
ReDim ar_sp(0, num)
Dim ar_compl 'もとの配列ストック
Dim arTmp
Dim idx() As Long
ReDim idx(0 To r)
For i = 0 To r
idx(i) = i
Next i
For i = 0 To UBound(Stock)
ar_sp(0, i) = Stock(i)
Next
ar_compl = ar_sp
Do
For j = r To 0 Step -1
ar(0, j) = Stock(idx(j))
Next
arTmp = ar_compl
For i = 0 To UBound(idx): arTmp(0, idx(i)) = Null: Next i
ReDim ar_sp(0, UBound(Stock) - rOrg) '補完変数に移し替え
For i = 0 To UBound(Stock)
If Not IsNull(arTmp(0, i)) Then
ar_sp(0, t) = arTmp(0, i)
t = t + 1
End If
Next i
k = k + 1 '書き出しの行
Cells(k, 1).Value = Application.Product(ar)
'Cells(k, 4).Resize(1, UBound(ar, 2) + 1).Value = ar '明細
Cells(k, 2).Value = Application.Product(ar_sp)
'Cells(k, UBound(ar, 2) + 5).Resize(1, UBound(ar_sp, 2) + 1).Value = ar_sp '明細
i = r: t = 0
While (idx(i) = num - r + i)
i = i - 1
If i = -1 Then
Exit Sub
End If
Wend
idx(i) = idx(i) + 1
For j = i + 1 To r
idx(j) = idx(i) + j - i
Next j
ar_sp = ar_compl
Loop
End Sub
ご回答ありがとうございます。
まさに私がやりたかった事です。
自分が考えていた、プログラムと全然違うので、
ものすごく勉強になりました。
誠にありがとうございました。
No.5
- 回答日時:
> 配列aの大きさ、数値、取り出す個数を任意にしたかったため、
配列の大きさや個々の数値はともかく、取り出す個数を2ではなく、3,4のようにしたい場合は、2次元マトリクスは使えません。
マクロしかないような気がします。
No.4 WindFalleさんの回答のままです。 取り出す数値のみ追加表示
Option Explicit
Sub MakingCombin()
Dim Stock As Variant
Dim i As Long
Dim r_PICK
r_PICK = 4 '抽出数
Stock = Array(9, 11, 13, 4, 5, 6, 7, 8, 17) '配列ストック
ActiveSheet.UsedRange.ClearContents 'データを消す
'実行
Call sCombinations(Stock, r_PICK)
End Sub
Private Sub sCombinations(ByVal Stock, ByVal r As Long)
Dim num As Long
Dim ar As Variant
Dim ar_sp As Variant
Dim i As Long, j As Long
Dim k As Long, t As Long
Dim rOrg As Long
rOrg = r 'もとの抽出数を保管
num = UBound(Stock) - LBound(Stock)
r = r - 1
ReDim ar(0, r)
ReDim ar_sp(0, num)
Dim ar_compl 'もとの配列ストック
Dim arTmp
Dim idx() As Long
ReDim idx(0 To r)
For i = 0 To r
idx(i) = i
Next i
For i = 0 To UBound(Stock)
ar_sp(0, i) = Stock(i)
Next
ar_compl = ar_sp
Do
For j = r To 0 Step -1
ar(0, j) = Stock(idx(j))
Next
arTmp = ar_compl
For i = 0 To UBound(idx): arTmp(0, idx(i)) = Null: Next i
ReDim ar_sp(0, UBound(Stock) - rOrg) '補完変数に移し替え
For i = 0 To UBound(Stock)
If Not IsNull(arTmp(0, i)) Then
ar_sp(0, t) = arTmp(0, i)
t = t + 1
End If
Next i
k = k + 1 '書き出しの行
For i = 0 To r
Cells(k, 1 + i).Value = ar(0, i)
Next i
Cells(k, 2 + r).Value = Application.Product(ar)
Cells(k, 3 + r).Value = Application.Product(ar_sp)
i = r: t = 0
While (idx(i) = num - r + i)
i = i - 1
If i = -1 Then
Exit Sub
End If
Wend
idx(i) = idx(i) + 1
For j = i + 1 To r
idx(j) = idx(i) + j - i
Next j
ar_sp = ar_compl
Loop
End Sub
No.3
- 回答日時:
> セルB1に3×4×5×6=360が入るように
残り4つの数の積を求めるには、つぎのようにしてはいかがでしょうか。
セルB1に3×4×5×6=360が入るように
セルB1に1×2×3×4×5×6÷(1×2)=360が入るように
セルB1に1×2×3×4×5×6÷(1×2)=360が入るように
セルB1に(1×2×3×4×5×6)÷(1×2)=360が入るように
どこかのセル(F1)に (1×2×3×4×5×6)を入れておいて、
セルA1に(1×2) セルB1に F1÷A1
セルA2に(2×3) セルB2に F1÷A2
セルA3に(1×4) セルB3に F1÷A3
セルA4に(2×4) セルB4に F1÷A4
4つの数値の中に、同じ値の数値が含まれている場合もあるとして、VBAを使わなくて、エクセルシート上に、組み合わせのスコアボードを表示するという方法もあるように思います。
縦横のマトリクスをつくれば、2つの組み合わせがすべて表示されます。
対角線は相手なしになるので、数値は入りません。
左下の領域に、2つの組み合わせの乗算値を表示させ、
右上の領域に、2つの組み合わせ以外の数の乗算値を表示させます。
都合上、全部の数の乗算値をどこかに表示させておきます。
右上の領域の2つの組み合わせ以外の数の乗算値は、全部の数の乗算値を割って出します。
ほとんどコピーでできます。
B2 =INDEX($A$3:$A$18,COLUMN()-1)
B1 =B2*C2*D2*E2*F2*G2*H2*I2*J2*K2*L2
B4 =$A4*B$2
C3 =$B$1/C$2/$A3

ご回答ありがとうございます。
なるほど、確かにおっしゃる通りです。
配列aの大きさ、数値、取り出す個数を任意にしたかったため、
VBAでの処理を考えていました。
その都度、処理していくしかないのでしょうか?
No.2
- 回答日時:
配列から選択した値をIndexで『1』に変更してしまい、全部をProduct関数で求めればよいのでは?
例えば今回の場合Index 0,1 が 1 になっている状態なので
Dim v
v = Array(1, 1, 3, 4, 5, 6)
MsgBox (Application.Product(v))
こんな感じでしょ。
あとは現在どのようになっているのかでも変わるでしょうけど、乱数でIndexを求めるなら 1 に変更するのも楽な気はしますけど。
ただ任意に選択してって事なら考え方として楽なのは配列の中を順次取得し比較して、選択した値と同じなら 1 に変えてしまうとかかな?
ご回答ありがとうございます。
一度「1」に書き換えてから積を取って、
配列の数値をリセットして次の組み合わせを考えるということでしょうか?
No.1
- 回答日時:
こんなかんじでしょうか。
扱う数値があまり大きくないのであれば
4つの積は、「6つの積 / i / j」 で求めても可ですね。
Sub test()
Dim a(1 To 6) As Long
Dim i As Long, j As Long, k As Long, v As Long
Dim mulAll As Long
Dim row As Long: row = 1
'ここでa(1)~a(6)に値を書き込む
For i = LBound(a) To UBound(a) - 1
For j = i + 1 To UBound(a)
Cells(row, "A").Value = a(i) * a(j)' 2つの積を書く
v = 1
For k = LBound(a) To UBound(a)
If k <> i And k <> j Then ' a(i),a(j)以外の4つの積を求める
v = v * a(k)
End If
Next
Cells(row, "B").Value = v ' 4つの積を書く
row = row + 1
Next
Next
End Sub
ご回答ありがとうございます。
扱う数値、配列の大きさは大きくないので、
ご教授頂いた方法で処理できそうです。
後だしになってしまい申し訳ないのですが、
3つ取り出して、残り3つ、4つ取り出して残り2つ、
5つ取り出して、残り1つというように、
取り出す個数を変更しつつ、すべての結果を得るためには、
IFで条件分岐させていく形になるのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Excel(エクセル) SUMIFのIF分岐について 4 2023/04/15 12:57
- Excel(エクセル) ExcelのIF関数について 4 2023/05/24 12:54
- その他(プログラミング・Web制作) パイソンのプログラミングについての質問です 2 2023/05/22 12:39
- Excel(エクセル) エクセルでエラーを無視して一番左側のセルの値を返したい 2 2023/07/27 13:06
- Visual Basic(VBA) vbaエクセルマクロ RemoveDuplicatesについて RemoveDuplicatesを使 1 2023/02/27 22:21
- Visual Basic(VBA) vbaエクセルマクロ RemoveDuplicatesについて RemoveDuplicatesを使 3 2023/02/28 01:13
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- Visual Basic(VBA) VBA初心者です 検索した数字の行に色をつける 5 2023/02/13 14:22
- Excel(エクセル) 判定結果に応じて〇印(図形)をつけるマクロ 4 2022/10/30 11:22
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルの関数について
-
エクセル GROUPBY関数について...
-
Excelで4択問題を作成したい
-
エクセルの複雑なシフト表から...
-
エクセル
-
Amazonでマイクロソフトオフィ...
-
エクセルシートの見出しの文字...
-
グループごとの個数をカウント...
-
【マクロ】変数に入れるコード...
-
エクセルのリストについて
-
【マクロ】別ファイルへマクロ...
-
グループごとの人数のカウント
-
エクセルについて
-
グループごとの人数のカウント
-
【マクロ】左のブックと右のブ...
-
【マクロ】元データと同じお客...
-
【マクロ】数式を入力したい。...
-
【マクロ】【相談】Excelブック...
-
【マクロ】実行時エラー '424':...
-
他のシートの検索
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
9月17日でサービス終了らし...
-
エクセル
-
【マクロ】WEBシステムから保存...
-
エクセルの循環参照、?
-
エクセル ドロップダウンリスト...
-
エクセルのdatedif関数を使って...
-
特定のセルだけ結果がおかしい...
-
【マクロ】A列にある、日付(本...
-
【マクロ】EXCELで読込したCSV...
-
【マクロ】アクティブセルの時...
-
【エクセル】期限アラートについて
-
iPhoneのExcelアプリで、別のシ...
-
【関数】同じ関数なのに、エラ...
-
Excelの新しい空白のブックを開...
-
【マクロ】3行に上から下に並...
-
【マクロ】宣言は、何のために...
-
VBA チェックボックスをオーバ...
-
Excelについての質問です 並べ...
-
【マクロ】アクティブセルの2...
-
【関数】不規則な文章から●●-●●...
おすすめ情報