ExcelVBAクイズ今回は先日投稿したクイズの問6~問8のVBAの配列に関する問題について解説していきたいと思います。出題ページはこちらになります。VBAのRange操作の注意事項www.excel-chunchun.com解説についてまず初めに申し上げて起きますが、ここで解説する内容は実際に実行した結果から中の動きを推測して説明しているものです。全ての説明にMicrosoft公式の根拠があるわけではないため、正確性に欠けるかもしれない点にご注意ください。誤りや不明な点がありましたら、遠慮なく教えてください。今回はRangeに関する問題の続きとして、問6~問8について説明していきます。基礎知識まずは本記事で使用しているプロパティのリンク集を貼っておきます。SubVBAで高速化を目指すなら避けては通れない二次元配列のデータをセルに一括出力する場面における問題です。二次元配列をコード上で作って、セルに出力なんてことは少ないんですけどね。正解1.答えは実は空欄なのでした。このプログラムの問題を実行すると何が表示されるのかお見せしましょう。\ABC1234はい、実は何も表示されません。なんとABCが出力されてすらいません。このプログラムには間違いと思われる原因が2つあり、どちらかを修正する必要があります。その2つの間違いについて解説していきます。dataの宣言文が間違っている。1)が不適切なんです。Baseで指定した値が開始値になります。Aと答えた人は、縦3、横1の配列変数だと思っていたかと思いますが、この時点で間違っているわけです。(きっと間違えた人は、たまたま見落としただけだと思いますが。1つ目の説明の通りズレていたとして、data全体をセルに出力したらこういうことになるはずです。Cが、実際にはなにも出力されていませんでした。dataという式を見慣れない方のために簡単に説明すると、「dataの内容をA1を起点として縦に3、横に1の範囲のセルにdataを出力する。この縦に3、横に1が曲者です。UBoundは配列の要素番号の最大値を取得する関数であって、要素数を返す関数ではありません。従って、dataは4行あるのにも関わらず、出力範囲が3行しかなかった。dataは2列あるのにも関わらず、出力範囲が1列しかなかった。いう理由から、2列目にあるA、B、Cは出力されなかったのです。いう点に注意してください。はみ出した要素はエラーが出ることもなく無視されます。data(3,1)がミスではなかったとして、A1:A3にABCを出力したいなら次のようにそこら中直さなければなりません。無駄に長くて面倒ですが、そればかりは仕方ありません。実際に使うとなると、dataの要素番号が0~になって、Cellsと1ズレるので別のバグを誘発する元となります。更新の必要のない行と列が末尾に1つ増えるので美しくありません。1)とするように心がけています。これで目的どおりの動きになります。1に直したほうが良いのですが、そもそも二次元配列の要素が0から始めていることが間違いの元だと私は思っているので、セル出力においてはLBoundは無視することにしています。Sub二次元のあとに一次元・・・というのも辺な話ですが、エクセルは二次元が基本ですから一次元配列の問題を敢えて後にしました。"4")ですが、格納された結果はこのようになります。4もし要素番号を1,2,3,4と振っていた場合はその時点で間違いなのでした。次に右辺のWorksheetFunction.Transpose(v)ですが、二次元配列の行と列を反転させるワークシート関数です。WorksheetFunction.Transpose(v)とした場合、変数の内容がどのように変化するのかを示す表を掲載します。4なんと行方向にデータの続く二次元配列に変化しました!これでセルに一括代入できますね!※WorksheetFunctionには配列を返すことの出来る関数(RESIZEやINDEX等)がありますが、私の知る限り全てのワークシート関数の結果は要素番号が1からになるので、覚えておくと良いかも知れません。(例外があったら教えて下さい。1).Valueですが、先の通りvは0~3の配列でした。「4」だけが出力されなかった原因はココにあります。ため、「4」は出力されていなかった。WorksheetFunction.Transpose(v)を追記します。巨大な配列だと後者はコピーロスが大きいので避けるべきですが、一次元配列なら後者でも気になるほどのロスは出ないのでまず大丈夫です。前者の方が間違いないですけどね。私はデバッグしやすい後者のほうが好きだったりします。※先の通りワークシート関数は1から開始するという前提があるので。Subなんとなんと、ここへきて基本中の基本。333(1)は文字通りの出力なので問題なさそうですね。