web-dev-qa-db-ja.com

ワークシート関数の配列からサブ配列をどのように抽出しますか?

セルワークシート関数の開始配列よりも小さいサイズの配列をExcelで取得する方法はありますか?

だから私が持っていた場合:

{23, "", 34, 46, "", "16"}

私は最終的に:

{23, 34, 46, 16}

その後、他の関数で操作できます。

結論:これらの多くを行う場合は、間違いなくjtolleのUDFコームソリューションを使用します。 PPCが使用する式は近いですが、調べてみると、空のスロットでエラーが発生し、最初の値が欠落していることがわかりました。行番号を取得する簡単な方法があります。これが私の最終的な解決策です:

=IFERROR(INDEX($A$1:$A$6, SMALL(IF(($A$1:$A$6<>""),ROW($A$1:$A$6)),ROW(1:6))),"")

これは配列数式として入力する必要があります(CTRL-SHIFT-ENTER)。表示されている場合は、すべての結果を表示するために、少なくとも結果セットと同じ大きさの領域に入力する必要があります。

9
Lance Roberts

配列のサブセットを取得するだけの場合、そして必要な要素の位置がすでにわかっている、インデックス引数の配列でINDEXを使用できます。 。あれは:

_=INDEX({11,22,33,44,55},{2,3,5})
_

_{22,33,55}_を返します。しかし、あなたは位置を知らないので、それは通常あまり役に立ちません、そして私はUDFなしでそれらを得る方法を知りません。

この種のワークシート内配列フィルタリングに対して私が行ったことは、次の形式でUDFを作成することです。

_'Filters an input sequence based on a second "comb" sequence.
'Non-False-equivalent, non-error values in the comb represent the positions of elements
'to be kept.
Public Function combSeq(seqToComb, seqOfCombValues)

    'various library calls to work with 1xn or nx1 arrays or ranges as well as 1-D arrays

    'iterate the "comb" and collect positions of keeper elements

    'create a new array of the right length and copy in the keeper elements

End Function
_

私の実際のコードは、位置の収集操作や位置からのコピー操作を含む、ライブラリ関数へのすべての呼び出しであるため、疑似コードのみを投稿しました。それはおそらく基本的な考えを曖昧にするでしょう、それはかなり単純です。

あなたはそのようなUDFを次のように呼ぶでしょう:

_=combSeq({23, "", 34, 46, "", "16"}, {23, "", 34, 46, "", "16"} <> "")
_

または

_=combSeq(Q1:Q42, SIN(Z1:Z42) > 0.5)
_

excelの通常の配列メカニズムを使用して「くし」を生成します。これは、他のプログラミングシステムで見られる可能性のあるより標準的なfilter(list-to-filter, test-function)関数の多くの利点を得る、軽量でExcelに適した方法です。

「フィルター」は通常「この関数を使用したフィルター」を意味するため、「comb」という名前を使用します。Excelでは、フィルター関数を呼び出す前にテスト関数を適用する必要があります。また、中間結果として1つの「コーム」を計算し、それを使用して複数のリストをコーミングすることも役立ちます。

7
jtolle

このサイトには答えがあります: http://www.mrexcel.com/forum/showthread.php?t=112002 。しかし、あまり説明はありません。

列Aに空白のセルがあるデータがあり、これを列Bに配置するとします。空白をスキップして同じ順序でデータを取得します

=INDEX(  $A$1:$A$6, 
         SMALL(  
            IF(
               ($A$2:$A$6<>""), 
               ROW($A$2:$A$6)
            ), 
         ROW()-ROW($B$1)
         )
      )

説明は次のとおりです。

  • ROW()-ROW($ B $ 1)は、増分を与える単なるトリックです番号(つまり、B1に1、B2に2 ...)
  • IF(...、ROW($ A $ 2:$ A $ 6))がメインですトリックの一部:IF条件が真である行番号の配列を作成します(IFには「else」値がないことに注意してください)
  • SMALL(..)は、その配列のX番目に小さい値(この場合は数値)を返します。 X番目の空白でない行の)、ここでXは現在のセルの行番号(B1の1 ...)
  • [〜#〜] index [〜#〜]は、行番号からその行番号に変換されます値
  • [〜#〜] index [〜#〜]および[〜#〜] row [〜#〜]実際のテーブルの1行上から開始して、常にオフセット> 0( INDEXはゼロが好きではありません)
5
PPC

考えられるワークシート関数ソリューション:

_=INDEX(A1:A6,N(IF(1,MODE.MULT(IF(A1:A6<>"",ROW(1:6)*{1,1})))))
_

_MODE.MULT_関数は、インデックスの縮小された配列を返し、N(IF(1,.))が挿入されるため、配列はINDEX関数に参照により渡されます。

1
lori_m

上記の回答はすべて、シート上の別の場所に移動できず、挿入された行と列に非常に敏感な脆弱な数式を示しています。

これは機密性がなく、任意の行に移動できるバージョンです。

=INDEX($A$10:$A$40, SMALL(IF(B$10:B$40,ROW(INDIRECT("1:30"))),ROW(INDIRECT("1:30"))))

この例では、元の配列値は$ A $ 10:$ A $ 40に配置されます(元のデータが列ではなく行の場合は、配列数式{TRANSPOSE(originalArray)}を使用する可能性があります)。

列B $ 10:B $ 40には、この配列要素を結果に保持するか(TRUE)、保持しないか(FALSE)を決定するブールフラグ(TRUEまたはFALSE)が含まれています。この列には、必要な関数を使用してデータを入力できます。 OPに記載されているテストを作成するには、<> ""、B $ 10に次のように入力する必要があります:= A10 <> ""(その後、B $ 40までコピーします)。列Aには絶対列参照があり、列Bには相対列参照があるため、数式をさらに右側の列にコピーして、他のタイプの属性とサブ配列を作成できます。これらは、入力したブールテストによって管理されます。列CおよびDなど。

この例では、最大30個の要素の元の配列を処理します。より大きな配列の場合は、範囲$ A $ 10:$ A $ 40とB $ 10:B $ 40(30行を表す)を調整し、「1:30」の2つのオカレンスを適切に調整します。

1
Shlomo Swidler