TRANSPOSE関数は禁止!縦の配列を横に変換する8つの数式

TRANSPOSE関数は禁止!縦の配列を横に変換する8つの数式 関数パズル・縛りプレイ

はじめに:「〇〇関数なしで□□する」シリーズ開幕!

はじめに、当ブログ「Excelで暇つぶし」恒例の縛りプレイ企画のお時間です。

今回のミッションは、「TRANSPOSE関数なしで、縦の配列を横の配列に変換せよ!」です。

※注意:今回は挙動をわかりやすくするため「1次元配列」のみをターゲットとしています。この記事で紹介する数式は、複数行・複数列にまたがる「2次元配列」の変換には対応していないのでご注意ください。

A3:A9の範囲に、以下のような縦方向のデータがあるとします。

{"Excel1"; "Excel2"; "Excel3"; "Excel4"; "Excel5"; "Excel6"; "Excel7"}

Excelの説明画像

通常であれば =TRANSPOSE(A3:A9) と打てば一発で横に展開されます。

Excelの説明画像

しかし、今回はこのTRANSPOSE関数を封印し、あの手この手で同じ結果を導き出してみましょう。

本記事では、無料のWeb版Excelを使用して検証を行っています。Windowsはもちろん、MacやLinuxの方もブラウザさえあれば挑戦できます!

前提条件とルールの確認

空白セルの扱いは「0」とする

元の範囲(A3:A9)に空白セルがあった場合、結果は空白ではなく「0」を返すこととします。
なぜなら、本家 TRANSPOSE(A3:A9) が空白を0に変換する仕様なので、今回はその挙動に完全に合わせます。

Excelの説明画像

数式は1つでスピル(展開)させる

右に向かって数式をコピーするのではなく、1つのセルに数式を入れるだけで横に展開させます。

参照していい範囲は「A3:A9」のみ

A3 単体や A2 など、範囲外や部分的なセル参照は禁止します。

参照回数は少なく(メンテナンス性の追求)

数式の中に「A3:A9」という文字が何回出てくるかに注目してください。
参照回数が少ないほど、後で別の範囲(例:B3:B10など)に変更する際の修正箇所が減り、メンテナンスが楽になります。


【Microsoft 365対応】最新関数でスマートに解決

関数の詳細な仕様については、Microsoft公式のヘルプも参考にしてください。

次に、Microsoft 365(またはWeb版Excel)で使える最新の関数を使ったアプローチを4つ紹介します。

数式1:間違いなく現代の王道(TOROW関数)

=TOROW(A3:A9)

【A3:A9の参照:1回】

Excelの説明画像

1次元配列の変換であれば、間違いなくこれが最短・最強の王道数式です。

TOROW 関数は、指定した配列を「1行(横方向)」に並べ替える関数です。

  • 第1引数: 変換したい配列(A3:A9)
  • 第2引数(省略可): 無視する値(1=空白を無視、2=エラーを無視など。今回は空白を0にしたいので省略または0
  • 第3引数(省略可): スキャン方向(縦方向の配列を横にするだけなので省略でOK)

数式2:文字列の結合&分割(TEXTJOIN & TEXTSPLIT)

=LET(a, TEXTSPLIT(TEXTJOIN("ゑ", 0, A3:A9), "ゑ"), IF(a="", 0, a))

【A3:A9の参照:1回】

一度すべての文字をくっつけてから、横方向に分割し直すという力技です。

TEXTJOIN の第2引数を「0(FALSE」にすることで、空白セルも無視せずに結合します。

区切り文字に「ゑ」を使用しているのがポイントです。

もし「-」や「,」を使うと、元のデータの中にその記号が含まれていた場合にロジックが破綻してしまいます。

普段使わない文字を選ぶのが鉄則です。

Excelの説明画像

TEXTSPLIT で横に分割した際、元の空白部分は文字がない空の文字列(””)になります。
これを IF(a="", 0, a) で「0」に変換し、TRANSPOSEの挙動に合わせます。

Excelの説明画像

【注意】文字数上限の壁
Excelの1セルあたりの文字数上限は「32,767文字」です。
これを少しでも超えるとエラーになるため、超大量データの変換には向かないという弱点があります。

数式3:REDUCE関数を利用(ラムダヘルパー)

=DROP(REDUCE("", A3:A9, LAMBDA(a, b, HSTACK(a, b))), , 1)

【A3:A9の参照:1回】

少し上級者向けの数式です。

REDUCE は、配列の要素を1つずつ取り出して処理を繰り返す関数です。

ここでは、取り出した要素(b)を、HSTACK でどんどん横に連結(蓄積)させています。

最初に用意した初期値("")が先頭に余分にくっついてしまいます。
なので最後に DROP 関数を使って左から1列目を削り落としています。

Excelの説明画像

【注意】処理激重の罠!
この数式は配列を1つずつ順番に結合していく性質上、数千行レベルのデータに適用すると処理が重くなります。

数式4:MAKEARRAY関数を利用(グリッド生成)

=MAKEARRAY(1, ROWS(A3:A9), LAMBDA(r, c, INDEX(A3:A9, c)))

【A3:A9の参照:2回】

MAKEARRAY は、指定した行数・列数の「枠」を作り、そこに計算結果を埋め込む関数です。

ここでは「1行 × 元の行数(7列)」の枠を作り、列番号(c)をインデックスとして活用します。

そして、元の配列から INDEX 関数で上から順に値を取り出して埋め込んでいます。

Excelの説明画像

【Excel 2019以前対応】古き良き関数でパズルを解く

続いて、スピル機能や最新関数が存在しなかった時代の関数で挑みます。

※注意:Excel 2019以前のバージョンでこれらの数式を実行して横に展開させるには、事前の範囲選択が必要です。

結果を表示したい範囲(例えばC3:I3)をあらかじめ選択します。

数式を入力した後 Ctrl + Shift + Enter(CSE)を同時に押して配列数式として確定してください(数式が {} で囲まれます)。

【マニアック豆知識】
ここから登場する数式5〜8のロジックは、実に約30年前のExcel97の時点で既にすべての関数が揃っていました。
理論上は当時から再現可能なものであり、一部の関数はさらに昔のExcel 4.0の時代から存在します。古の知恵がいかに優れていたかが分かりますね。

数式5:HLOOKUPという斬新なアイディア

=HLOOKUP("*", A3:A9, COLUMN(INDEX(1:1, 1) : INDIRECT("r1c" & ROWS(A3:A9), 0)), FALSE)

【A3:A9の参照:2回】

縦の配列に対して HLOOKUP を使うという、非常にトリッキーで面白い数式です。

ここでのハイライトは、横方向の配列 {1,2,3…} を作り出す以下の部分になります。

INDEX(1:1, 1) : INDIRECT("r1c" & ROWS(A3:A9), 0)

つまり、Excelでは INDEXINDIRECT のように「セル参照そのものを返す関数」同士を、コロン(:)で繋いで範囲を作ることができるのです!

Excelの説明画像

内部的には、A1セルから、行数分の列番号を持つセル(この場合はG1セル、R1C7)までの範囲 A1:G1 を生成しています。

【警告】ワイルドカードの落とし穴

検索値に "*"(ワイルドカード)を使って先頭セル(A3)を無理やりヒットさせるこのロジックはまさに変態的(褒め言葉)です。

しかし、このアプローチには致命的な弱点が存在します。

それは「A3セルが数値(例:100など)だった場合、ワイルドカードが反応せずにエラー(#N/A)になる」という仕様です。

Excelの説明画像

文字列データ限定の裏技であることに注意してください。

【解説】揮発性関数にご用心

この数式で使用している INDIRECT 関数は、「揮発性関数」と呼ばれます。

これは、シート内のどこか全く関係ないセルが編集されただけでも「毎回必ず再計算される」という厄介な性質を持っています。

そのため、この数式を数万行にわたって多用すると、Excelの動作が目に見えて遅くなる原因となります。

【R1C1形式は小文字推奨!】

当ブログでは、INDIRECT関数でR1C1形式を指定する際、「r1c1」のように小文字で書くことを強く推奨しています。

なぜなら、大文字の「R1C1」だと、「R1セル」や「C1セル」といったA1形式のセル番地と人間の目で混同する恐れがあるからです。

r5c1 のように小文字で書いてもExcelは正しく認識してくれます。

Excelの説明画像

数式6:行番号からセル番地を作る王道

=INDEX(A3:A9, COLUMN(INDIRECT(ADDRESS(1,1) & ":" & ADDRESS(1,ROWS(A3:A9)))))

【A3:A9の参照:2回】

先ほどの「配列 {1,2,3...} を作る」という課題に対し、ADDRESS 関数を使ったアプローチです。

Excelの説明画像

単純に COLUMN(A1:G1) と直接書けば済む話に思えます。

しかし、参照する行数が変わった場合、列をアルファベットで動的に指定するのは非常に面倒です。

仮に行数が100行だったら、COLUMN(A1:CV1) と書く必要があります。

それを回避するため、ADDRESS関数で「1行目の1列目〜1行目のN列目」という文字列("$A$1:$G$1")を作り、INDIRECTでセル範囲に変換しています。

Excelの説明画像

数式7:参照を返す関数の応用(LOOKUP)

=LOOKUP(COLUMN(INDEX(1:1,,1) : INDEX(1:1,,ROWS(A3:A9))), ROW(INDIRECT("r1",0) : INDIRECT("r" & ROWS(A3:A9),0)), A3:A9)

【A3:A9の参照:3回】

検索値に「横の配列 {1,2,3...}」、検査範囲に「縦の配列 {1;2;3...}」、対応範囲に「元の配列(A3:A9)」を指定することで、縦横を入れ替えて取得するテクニックです。

ここでも「参照を返す関数」が大活躍しています。INDEX : INDEXINDIRECT : INDIRECT といったコロン連結を多用しています。

すなわち、セル範囲を動的に作る場合、OFFSET関数を含め、これらの関数が「参照」を返す性質を持っていることを理解しておくことが重要です。

Excelの説明画像

【解説】LOOKUP関数の真骨頂
ここで注目すべきは、LOOKUP関数は行方向と列方向の向きが異なっていても、空気を読んで正しく値を返してくれるという素晴らしい性質を持っている点です。
現代の最強関数 XLOOKUP では、検索範囲と戻り値範囲の縦横が一致していないとエラーになってしまいます。
古い関数だからこそできる、変態的かつアクロバティックな配列操作ですね。

LOOKUP関数の基本的な挙動については、以下の記事で紹介しています。

IF関数のネストは不要!LOOKUP関数で「条件分岐」をスッキリ書く方法

数式8:INDEX関数フル活用(揮発性関数なし)

=INDEX(A3:A9, COLUMN(INDEX(1:1,,1) : INDEX(1:1,,ROWS(A3:A9))))

【A3:A9の参照:2回】

最後は、INDIRECTOFFSETのような再計算負荷がかかる「揮発性関数」を一切使わずに、スッキリと書き上げた最も実用的な古典的数式です。

INDEX : INDEX だけで A1:G1 の範囲を作り出し、それを COLUMN で横配列にして INDEX(A3:A9, ...) に渡しています。美しさと処理の軽さを兼ね備えた名作ですね。

Excelの説明画像

最後に:ロジックを知ればExcelはもっと面白い

さて、ここまで読んでいただいた方の中には、

TRANSPOSE関数を使えば一瞬で終わるのに、わざわざこんな遠回りをして何の意味があるの?」

と思う方もいるかもしれません。

確かに実務のスピードだけを求めれば、専用の関数を使うのが正解です。

しかし、こうした「縛りプレイ」には、Excelの学習面において以下のような絶大なメリットがあります。

  • 論理的思考力の向上: 既存の関数をどう組み合わせれば目的の動きを作れるか、アルゴリズムを構築するパズル思考が鍛えられます。
  • 関数の深い理解: 「INDEX関数が参照を返す」「IF関数で配列を分岐させる」といった、普段は意識しないマニアックな仕様を深く知ることができます。
  • 応用力への昇華: ここで培った「配列を自在に生成し、操作する技術」は、将来全く別の複雑な課題に直面したとき、必ずあなたを助ける強力な武器になります。

標準機能でできることを、あえて別の関数で遠回りして再現してみる。

そこに、Excelのスキルを飛躍させる大きなヒントが隠されています。

ぜひ、皆さんも独自の「縛りプレイ」で関数パズルを楽しんでみてください!

【Excelクイズ】ABS関数は使用禁止!「絶対値」を求める9つの方法、いくつ思いつきますか?

【Excelクイズ】LEN関数は使用禁止!文字数を数える5つの裏ワザ、わかりますか?

タイトルとURLをコピーしました