エクセル関数応用
複数列の直積(デカルト積、クロスジョイン)

Excel関数の解説、関数サンプルと高等テクニック
公開日:2025-10-23 最終更新日:2025-10-23

複数列の直積(デカルト積、クロスジョイン)


直積(デカルト積、クロスジョイン)とは、複数のデータ集合(リストやテーブル)の要素をすべて組み合わせてできる新しい集合のことです。
簡単に言うと、「ありとあらゆる組み合わせのリスト」です。


以下の数式は、あくまで1例です。
数式の作成及び解説には、生成AIを活用しています。


固定列数の直積(デカルト積、クロスジョイン)

2列固定の直積(デカルト積、クロスジョイン)

複数列の直積(デカルト積、クロスジョイン)

=LET(
    A,DROP(A:.A,1),
    B,DROP(B:.B,1),
    R_A, ROWS(A),
    R_B, ROWS(B),
    X, SEQUENCE(R_A * R_B),
    aIndex, INDEX(A, MOD(INT((X-1)/R_B), R_A) + 1),
    bIndex, INDEX(B, MOD(X-1, R_B) + 1),
    HSTACK(aIndex, bIndex)
)

数式の説明
  1. データの準備
    最初に、A列とB列からヘッダーを除いたデータ部分を取得します。
    それぞれの行数を調べて、A列の行数を「R_A」、B列の行数を「R_B」として記録します。
  2. 総組み合わせ数の算出
    A列とB列の全組み合わせ数は「R_A × R_B」で求まります。
    この総数分の連番(1から始まる番号リスト)を作り、各行がどの組み合わせに対応するかを判定する基礎とします。
  3. インデックスの計算
    次に、A列とB列のそれぞれについて「どの行の値を使うか」を数値的に計算します。
    A列はB列全体が1巡するごとに次の値に進むように設定し、B列は行ごとに順に変化するようにします。
    このしくみで、外側ループ(A列)と内側ループ(B列)の二重ループと同じ動きを再現しています。
  4. 直積の生成
    最後に、計算した行番号に従ってA列・B列の値を取り出し、横に並べます。
    これによって、A列とB列のすべての組み合わせを網羅した一覧表が完成します。
  5. 要点まとめ
    ヘッダーを除いた実データだけを使う。
    A列の値はゆっくり変化し、B列の値は速く変化する。
    Excel関数だけで二重ループ処理を実現している。
    結果として、A×Bの全組み合わせが表として生成される。

4列固定の直積(デカルト積、クロスジョイン)

複数列の直積(デカルト積、クロスジョイン)

=LET(
  A, DROP(A:.A,1),
  B, DROP(B:.B,1),
  C, DROP(C:.C,1),
  D, DROP(D:.D,1),
  X, SEQUENCE(ROWS(A)*ROWS(B)*ROWS(C)*ROWS(D)),
  aIndex, INDEX(A, MOD(INT((X-1)/(ROWS(B)*ROWS(C)*ROWS(D))), ROWS(A)) + 1),
  bIndex, INDEX(B, MOD(INT((X-1)/(ROWS(C)*ROWS(D))), ROWS(B)) + 1),
  cIndex, INDEX(C, MOD(INT((X-1)/ROWS(D)), ROWS(C)) + 1),
  dIndex, INDEX(D, MOD(X-1, ROWS(D)) + 1),
  HSTACK(aIndex, bIndex, cIndex, dIndex)
)

数式の説明
  1. データの準備
    まず、A~Dの各列からヘッダー行を除いたデータ範囲を取得します。
    これにより、A~D列のそれぞれに実データだけが格納されます。
    次に、各列の行数を調べ、全体の総組み合わせ数を「A行数 × B行数 × C行数 × D行数」で算出します。
    この総数分だけの連番を用意し、後の計算で行番号を決定する基礎とします。
  2. インデックスの計算
    直積を作るためには、「各列のどの値を、どの順番で使うか」を数式で決める必要があります。
    この計算は次のような規則で行われます。
    A列:最も外側のループに相当。B×C×Dの組み合わせが一巡するごとに次のAの値へ進む。
    B列:C×Dの組み合わせが一巡するごとに次のBの値へ進む。
    C列:Dの全要素が一巡するごとに次のCの値へ進む。
    D列:一番内側のループに相当し、行ごとに次の値に進む。
    このように、各列が入れ子構造(多重ループ)のように動くことで、すべての組み合わせが抜け漏れなく生成されます。
  3. 結合と出力
    計算された行番号をもとに、A~Dの各列から該当するデータを取り出し、横方向に結合します。
    その結果、A列・B列・C列・D列のすべての値を組み合わせた完全な直積リストが完成します。
    表全体は「外側がA、内側がD」という構造で展開され、行方向に全パターンが出力されます。
  4. 要点まとめ
    ヘッダーを除いたA~D列のデータを対象とする。
    各列はループ構造に対応し、外側から順にA→B→C→Dの順で値が変化する。
    全行数は「A×B×C×D」で求まる。
    Excel関数だけで4重ループを再現し、あらゆる組み合わせをリスト化する。


不定列数の直積(デカルト積、クロスジョイン)

数式1:MAKEARRAY + インデックス計算

=LAMBDA(tbl,
  LET(
    cnt, BYCOL(tbl, LAMBDA(c, COUNTA(c))),
    T, PRODUCT(cnt),
    N, COLUMNS(tbl),
    Rev, INDEX(cnt, SEQUENCE(1, N, N, -1)),
    FD, HSTACK(1,DROP(SCAN(1, Rev, LAMBDA(a,v, a * v)), , -1)),
    FS, INDEX(FD, SEQUENCE(1, N, N, -1)),
    MAKEARRAY(
      T,N,
      LAMBDA(r,c,
        LET(
          X, r - 1,
          L_c, INDEX(cnt, c),
          D_c, INDEX(FS, c),
          Idx, MOD(INT(X / D_c), L_c) + 1,
          List, FILTER(INDEX(tbl, 0, c), INDEX(tbl, 0, c) <> ""),
          INDEX(List, Idx)
        )
      )
    )
  )
)(DROP(A:.D,1))

数式の説明
この数式は、列数が決まっていない表(A列~任意の列まで)に対応し、
入力された複数列のすべての組み合わせを自動的に生成するものです。
列数が2列でも5列でも、同じ構造の数式で直積を作ることができます。
  1. データの準備と基礎情報の計算
    まず、入力された表(tbl)から、各列に含まれるデータ行数を求めます。
    その結果をもとに、すべての列の行数を掛け合わせ、最終的に生成される行数(組み合わせ総数)を計算します。
    この値が直積リストの全行数となります。
    また、各列の繰り返し周期(何行ごとに値が変わるか)を算出し、
    後のインデックス計算で使えるように事前準備を行います。
    これにより、列が増えても自動的に対応できる柔軟な構造になります。
  2. インデックス計算の仕組み
    各セル(行番号r、列番号c)に対して、どのデータを取り出すかを数学的に決定します。
    具体的には、行番号から「何回目の繰り返しに当たるか」を割り算と余り(INTとMOD)を使って計算し、
    対応するデータ行のインデックスを求めます。
    これにより、A列が最もゆっくり、右の列ほど速く値が変化するという規則を自動的に再現します。
    つまり、列の数に応じて多重ループを自動的に展開していることになります。
  3. 直積の生成(MAKEARRAY)

    全体の行数(組み合わせ数)と列数をもとに、
    MAKEARRAY関数を使って新しい表を一括で生成します。
    各セルでは前段で計算したインデックスに基づき、元データの該当セルの値を取り出して配置します。
    これを行列全体で同時に行うため、列数が増えても高速かつ自動的に全組み合わせが展開されます。
  4. 結果
    こうして作成された表は、入力された任意列の全要素を網羅する直積リストになります。
    たとえば3列なら3重ループ、5列なら5重ループに相当する組み合わせを、
    1つの動的数式で完全に表現できます。
  5. 要点まとめ
    列数が変わっても自動的に全組み合わせを生成できる。
    各列のデータ行数と繰り返し周期を数式内で算出。
    MOD・INTを用いて多重ループ構造を数学的に再現。
    MAKEARRAY関数により全パターンを一括生成。
    汎用性が高く、列数に制限されない動的な直積リストが得られる。

数式2:REDUCE + MAKEARRAY

=LAMBDA(tbl,
  REDUCE(
    FILTER(TAKE(tbl,,1),TAKE(tbl,, 1)<>""),
    SEQUENCE(1,COLUMNS(tbl)-1,2),
    LAMBDA(acc,i,
      LET(
        nc,INDEX(tbl,,i),
        ncc, FILTER(nc,nc<>""),
        MAKEARRAY(
          ROWS(acc)*ROWS(ncc),
          COLUMNS(acc)+1,
          LAMBDA(r,c,
            IF(c<=COLUMNS(acc),
              INDEX(acc,QUOTIENT(r-1,ROWS(ncc))+1,c),
              INDEX(ncc, MOD(r-1,ROWS(ncc))+1,1)
            )
          )
        )
      )
    )
  )
)(DROP(A:.D,1))

数式の説明
の数式は、REDUCE関数を使って「列を順に追加しながら直積を拡張していく」仕組みを持っています。
列数が2列でも10列でも、1つの数式で順次すべての組み合わせを作り出せます。
MAKEARRAY版と比べて、構造が段階的で理解しやすいのが特徴です。
  1. 初期状態の設定
    最初に、入力された表(tbl)の1列目を取り出し、空白を除いたデータリストを初期値とします。
    この時点では、まだ直積ではなく単一列のリストです。
    REDUCE関数の「累積処理(acc)」の出発点となります。
  2. REDUCEによる逐次展開
    REDUCEは、列を1つずつ順に処理し、前回までの結果(acc)に新しい列を組み合わせる形で直積を拡張していきます。
    つまり、
    2列目と1列目を組み合わせて2列の直積を作成
    次に3列目を追加して3列の直積を作成
    さらに4列目を追加して4列の直積を作成
    …というように、列が増えるたびに組み合わせを広げていきます。
    この段階的な繰り返し処理により、列数が何列でも柔軟に対応できます。
  3. MAKEARRAYによる直積生成
    各ステップの中では、MAKEARRAY関数が使われています。
    ここでは、既存の直積結果(acc)と新しい列(ncc)を組み合わせて、
    行数=既存行数×新列の行数、列数=既存列数+1 の新しい表を作ります。
    各セルにどの値を入れるかは、行番号を割り算と余りで分解して求めます。
    具体的には、
    既存の列は「新しい列の行数分だけ同じ値を繰り返す」
    新しい列は「一定周期で値を切り替える」
    という構造になっており、二重ループを1回の計算で再現しています。
  4. 累積処理の完了
    REDUCEがすべての列を処理し終えると、最終的な直積リストが完成します。
    各列が段階的に追加され、全列のあらゆる組み合わせが行方向に展開されます。
    列数が多くても、ループ構造を意識せずに全組み合わせを作成できるのがこの方法の利点です。
  5. 要点まとめ
    REDUCEを使い、列を1つずつ順に直積へ組み込む構造。
    初期値は1列目のデータ、以降の列を順に追加。
    各ステップではMAKEARRAYが二重ループの役割を担う。
    行番号の商と余りを使って値の繰り返しパターンを制御。
    列数が増えても自動で拡張され、柔軟な直積生成が可能。




同じテーマ「エクセル関数応用」の記事

セル参照を戻り値とする関数
REDUCE+VSTACKが遅い理由と解決策
HSTACKは速い?遅い?実際に試してみた結果
条件付きMEDIAN関数を作る|LAMBDA関数で汎用〇〇IFSを実現
複数列の直積(デカルト積、クロスジョイン)
フィボナッチ、トリボナッチ、テトラナッチ数列を1数式で作成
表データから複数条件による複合抽出 (横AND/縦OR)
配列を自在に回転させる数式
掛け算(*)を使わない掛け算|足し算(+)を使わない足し算
2段階の入力規則リスト作成:最新関数対応
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン


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

AIは便利なはずなのに…「AI疲れ」が次の社会問題になる|生成AI活用研究(2026-02-16)
カンマ区切りデータの行展開|エクセル練習問題(2026-01-28)
開いている「Excel/Word/PowerPoint」ファイルのパスを調べる方法|エクセル雑感(2026-01-27)
IMPORTCSV関数(CSVファイルのインポート)|エクセル入門(2026-01-19)
IMPORTTEXT関数(テキストファイルのインポート)|エクセル入門(2026-01-19)
料金表(マトリックス)から金額で商品を特定する|エクセル練習問題(2026-01-14)
「緩衝材」としてのVBAとRPA|その終焉とAIの台頭|エクセル雑感(2026-01-13)
シンギュラリティ前夜:AIは機械語へ回帰するのか|生成AI活用研究(2026-01-08)
電卓とプログラムと私|エクセル雑感(2025-12-30)
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン|エクセル関数応用(2025-12-25)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.FILTER関数(範囲をフィルター処理)|エクセル入門
5.RangeとCellsの使い方|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
8.マクロとは?VBAとは?VBAでできること|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.メッセージボックス(MsgBox関数)|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」をお願いいたします。
本文下部へ