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

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 ・・・新着記事一覧を見る

「Python in Excel」入門:コードを読むための基礎知識|エクセル関数応用(2026-09-10)
M言語入門:Power Queryのコードを読むための基礎知識|Power Query(M言語)入門(2026-09-09)
Excelの正規表現関数(REGEXTEST・REGEXREPLACE・REGEXEXTRACT)の使い方|エクセル関数応用(2026-09-08)
スピルとVBA(Formula2とスピル範囲の取得)|VBA入門(2026-09-08)
「Withの功罪」:コードを読みやすくする強力な道具と、その落とし穴|VBA技術解説(2026-09-03)
可変長配列をVSTACKする4つの方法|REDUCE・Thunk・チャンク・再帰分割|エクセル関数応用(2026-09-01)
Excel表とMarkdownテーブルを相互変換する数式|エクセル関数応用(2026-08-24)
「Python in Excel」数独(ナンプレ)解法プログラムの移植と最適化|エクセル関数応用(2026-08-14)
「Python in Excel」で自作関数を登録|アンピボット関数と計算順序|エクセル関数応用(2026-08-12)
ListBox・ComboBoxをマウスホイール対応させる|ユーザーフォーム入門(2026-08-09)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.Excelショートカットキー一覧|Excelリファレンス
5.RangeとCellsの使い方|VBA入門
6.FILTER関数(範囲をフィルター処理)|エクセル入門
7.マクロとは?VBAとは?VBAでできること|VBA入門
8.繰り返し処理(For Next)|VBA入門
9.メッセージボックス(MsgBox関数)|VBA入門
10.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門




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


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.



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