ツイッター出題回答
ジャグ配列から順列を作成する

ExcelマクロVBAとエクセル関数についての私的雑感
公開日:2022-07-05 最終更新日:2022-07-07

ジャグ配列から順列を作成する


ツイッターで会話したので、それを実際にVBAで書いてみました。


ジャグ配列(配列の要素に配列が入っている)から、要素を1つずつ取り出して全順列を作成します。
競馬で言ったら、
1列目、2列目、3列目を指定した3連単のようなものです。

実際にVBAを書こうと思って、ふと考えたら、VBA練習問題でほぼ同じ問題を出していました。

練習問題24(再帰呼出し)
マクロVBA練習問題 ・以下の表の全組み合わせを作成して下さい。サンプルデータでは、組み合わせの数は、8*3*6*5=720通りです。・各項目はカンマ(,)で区切って下さい。・出力先は、新規シートを追加し、1行目に見出しとして"組み合わせ文字"と入れ、2行目より出力して下さい。
こちらでは、シートのデータをもとにシートに出力しているところが違うだけです。
以下のVBAは、ここの解答VBAのコードと基本的には同じやり方にしました。


出題ツイート

n次元の配列があり、各要素はランダム要素数の配列、つまりジャグ配列。
n次元の要素から1つずつ取り出す組み合わせ
まあつまり、3つなら3連単w
(1)1,2,3
(2)4,5
(3)6,7,8
なら
1,4,6
1,4,7
1,4,8
1,5,6
・・・
これだと結構難しいですかね。

Excel エクセル VBA問題
https://twitter.com/yamaoka_ss/status/1543923471087898626


作成したVBA

イミィディエイト ウィンド に順次出力

Sub test()
  'ジャグ配列を作成する。
  Dim inAry, tAry, i, j, v, dic As Dictionary
  ReDim inAry(1 To 3) 'とりあえず3次元で
  Debug.Print "入力ジャグ配列"
  For i = LBound(inAry) To UBound(inAry)
    Randomize
    ReDim tAry(1 To Int(4 * Rnd + 2)) 'とりあえず要素数は2~5で
    Set dic = New Dictionary
    For j = LBound(tAry) To UBound(tAry)
      Do
        v = Int(9 * Rnd + 1) 'とりあえず数値は1桁で
        If Not dic.Exists(v) Then Exit Do
      Loop
      tAry(j) = v
      dic.Add v, v
    Next
    inAry(i) = tAry
    Debug.Print Join(tAry, ",")
  Next
  
  'ジャグ配列から順列を作成する
  Debug.Print "出力組み合わせ"
  Dim tmpAry
  ReDim tmpAry(1 To UBound(inAry))
  Call func(inAry, tmpAry, 1)
End Sub

'再帰プロシージャー
Private Sub func(ByRef inAry, ByRef tmpAry, ByVal n As Long)
  Dim i As Long, v
  v = inAry(n)
  For i = LBound(v) To UBound(v)
    tmpAry(n) = v(i)
    If n >= UBound(tmpAry) Then
      Debug.Print Join(tmpAry, ",")
    Else
      Call func(inAry, tmpAry, n + 1)
    End If
  Next
End Sub

Excel エクセル VBA問題


全ての順列を配列で返す

Sub test()
  'ジャグ配列を作成する。
  Dim inAry, tAry, i, j, v, dic As Dictionary
  ReDim inAry(1 To 3) 'とりあえず3次元で
  Debug.Print "入力ジャグ配列"
  For i = LBound(inAry) To UBound(inAry)
    Randomize
    ReDim tAry(1 To Int(4 * Rnd + 2)) 'とりあえず要素数は2~5で
    Set dic = New Dictionary
    For j = LBound(tAry) To UBound(tAry)
      Do
        v = Int(9 * Rnd + 1) 'とりあえず数値は1桁で
        If Not dic.Exists(v) Then Exit Do
      Loop
      tAry(j) = v
      dic.Add v, v
    Next
    inAry(i) = tAry
  Next
  
  'ジャグ配列から順列を作成する
  Debug.Print "出力組み合わせ"
  Dim outAry
  Call func(inAry, outAry)
  
  'シートに出力
  For i = LBound(inAry) To UBound(inAry)
    Cells(i, 1) = Join(inAry(i), ",")
  Next
  For i = LBound(outAry) To UBound(outAry)
    Cells(i, 2) = outAry(i)
  Next
End Sub

'再帰プロシージャー
Private Sub func(ByRef inAry, ByRef outAry, _
         Optional ByRef n As Long = 1, _
         Optional ByRef tmpAry)
  If Not IsArray(tmpAry) Then ReDim tmpAry(1 To UBound(inAry))

  Dim i As Long, v
  v = inAry(n)
  For i = LBound(v) To UBound(v)
    tmpAry(n) = v(i)
    If n >= UBound(tmpAry) Then
      If IsArray(outAry) Then
        ReDim Preserve outAry(1 To UBound(outAry) + 1)
      Else
        ReDim outAry(1 To 1)
      End If
      outAry(UBound(outAry)) = Join(tmpAry, ",")
    Else
      Call func(inAry, outAry, n + 1, tmpAry)
    End If
  Next
End Sub

Excel エクセル VBA問題




同じテーマ「ツイッター出題回答 」の記事

数値変数の値を別の変数を使わずに入れ替える
Rangeオブジェクトを受け取り"行数,列数"で埋める
数式の関数の使用回数、関数名を配列で返す
日付型と通貨型のValueとValue2について
小文字"abc"を大文字"ABC"に変換する方法
オブジェクトのByRef、ByVal、Variant
「マクロの登録」で登録できないプロシージャーは?
ジャグ配列から順列を作成する
シート内の全テーブルを1つに統合
VBA穴埋め問題「On Error GoToの挙動」
数珠順列(配置に条件付き)を全て出力する


新着記事NEW ・・・新着記事一覧を見る

ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)
いくつかの数式の計算中にリソース不足になりました。|エクセル雑感(2023-12-28)
VBAでクリップボードへ文字列を送信・取得する3つの方法|VBA技術解説(2023-12-07)
難しい数式とは何か?|エクセル雑感(2023-12-07)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.変数宣言のDimとデータ型|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.並べ替え(Sort)|VBA入門
8.条件分岐(IF)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ