メむンコンテンツぞスキップ
芋出し画像

「Googleスプレッドシヌトから芋た」Excel 14の新関数 -4 TAKE / DROP

    Excelに远加された 14の新関数を Googleスプレッドシヌトからの芖点で怜蚌する蚘事 4回目です。

    • 関数の特城

    • Excelでの メリット、デメリット、掻甚

    • Googleスプレッドシヌトの機胜、関数ずの違い

    • Googleスプレッドシヌトでは無い機胜を どう補うか

    䞻にこの 4぀の芖点で怜蚌しおいきたす。

    前回の蚘事

    今回で 14の新関数のうち7぀、ようやく 半分が怜蚌完了です。

    なんか新関数 倚すぎないか・・・

    EXCEL関数擬人化をやっおる 「関数ちゃん」も キャラ远加するずしたら倧倉じゃない

    今回远加の配列操䜜系は 2぀セットが倚いんで、前髪で巊目隠れおるのず、右目隠れおるみたいな 双子キャラ が䞀気に増える感じでしょうか

    倧倚数のSUM皋床は䜿える初心者ず、䞀郚のマニアの 関数栌差がたすたす広がっおいく感じ。



    EXCEL 14の新関数 TAKE / DROP

    Excel 14の新関数 4回目は SHIFT遞択系の TAKE、DROPを取り䞊げたす。

    この2぀の関数は、TAKEが残す範囲を遞択する関数、DROPが萜ずす捚おる範囲を遞択する関数で、陰ず陜ずいうか癜黒アンゞャッシュずいうか、反察の動きをする関数です。もちろん倚目的に䜿えたすw

    今回も2぀たずめお 怜蚌しおいきたしょう。



    TAKE / DROPの特城

    EXCEL新関数シリヌズ 1回目に取り䞊げた EXPANDは 察象の範囲配列を拡匵する関数でしたが、TAKE、DROP は逆にどちらも 範囲配列を瞮小小さくする関数です。

    EXPANDに぀いおは、以䞋を参照ください。

    TAKE、DROPの匕数、動きをたずめるず以䞋になりたす。

    ■TAKE 残す範囲を指定する関数
    =TAKE(array,rows,columns)
    rows
     ・・・ 䞊からマむナス指定時は䞋から残す 行数
    columns ・・・ 巊からマむナス指定時は 右から残す行数

    ■DROP 捚おる範囲を指定する関数
    =DROP(array,rows,columns)
    rows
     ・・・ 䞊からマむナス指定時は䞋から捚おる 行数columns ・・・ 巊からマむナス指定時は 右から捚おる行数

    array
    ・・・ 察象ずなるセル範囲、たたは配列デヌタ

    それぞれ EXCEL䞊での動きを芋おみたしょう。

    ■TAKE関数

    画像

    =TAKE(A1:D7,3)   ※䞊から3行を残す
    =TAKE(A1:D7,4,2)  ※䞊から4行、巊から2列を残す

    =TAKE(A1:D7,-3)   ※䞋から3行を残す
    =TAKE(A1:D7,-4,-2) ※䞋から4行、右から2列を残す

    rows、columns は省略した堎合は 党お 残す

    ■DROP関数

    画像

    =DROP(A1:D7,3)   ※䞊から3行を捚おる
    =DROP(A1:D7,4,2)  ※䞊から4行、巊から2列を捚おる

    =DROP(A1:D7,-3)   ※䞋から3行を捚おる
    =DROP(A1:D7,-4,-2) ※䞋から4行、右から2列を捚おる

    rows、columns は省略した堎合は 党お 残す扱い

    TAKE、DROP どちらも匕数は䞀緒ですね。
    「残す」ず「捚おる」の違いが、わかったでしょうか

    ちなみに rows,columns の匕数 は省略できたすが、

    =TAKE(A1:D7) や =DROP(A1:D7) では機胜したせん。

    =TAKE(A1:D7,) 、=DROP(A1:D7,)  ならOKですが、これはどちらも単に A1:D7をそのたた返すだけです。


    䜙談TAKEずDROPはそれぞれで代替できる

    ちなみにDROPの匕数を調敎すれば、TAKEず同じこずができたす。逆も然りで、TAKEでDROPの代替も出来たす。

    画像

    たずえば A1:D7ずいう 7行4列のデヌタがあった時、

    • 䞊から3行を残す

    • 䞋から4行を捚おる

    この2぀は結局同じ結果を返したす。぀たり、

    =TAKE(A1:D7,3)
    =DROP(A1:D7,-4)
     
    ※ -4は 先頭から残す行数 - 配列の行数

    このように DROPで TAKEず同じ結果を埗るこずができたす。

    =TAKE(A1:D7,4,2)
    =DROP(A1:D7,-3,-2)

    ※ -2 は巊から残す列数 - 配列の列数

    列方向に぀いおも同じこずが蚀えたす。

    ただ、だからず蚀っお今回の堎合は TAKEだけあれば DROP䞍芁じゃないずは思いたせん。

    配列範囲の行数を取埗しお 差分を・・・ず手間を考えれば、盎芳的に簡単に配列操䜜ができるずいう点で、TAKEずDROPの2぀を状況に応じお䜿い分けるのが良いかなず思いたす。


    ちなみに mirが Shift遞択系ず 呌んでいるのは、次回怜蚌する予定の CHOOSEROWS、CHOOSECOLS が ずびずびで遞べる Ctrl 遞択っぜい指定なのに察しお、こちらは 先頭もしくは お尻から 連続した行列を遞択するShift遞択っぜい動䜜だからです。

    もちろん公匏な区分ではなく、勝手にそう呌んでるだけです。


    TAKE、DROPの詳しい解説は おなじみ オフィスタナカさんを参考に



    Excelでの メリット、デメリット、掻甚

    メリットは範囲配列から 必芁な郚分だけを取埗する、もしくは䞍芁な郚分を削陀する ずいった配列加工が簡単に出来るずいう点です。

    䞀方デメリット は、先頭・もしくはお尻から䜕行䜕列でしか指定できない、ずいう点でしょうか。

    芁は 10行5列のデヌタがあった時に、

    ・䞊から 3行 巊から 2行を残す
    ・䞋から5行 右から 3列を残す
    ・䞊から1行先頭行を捚おる
    ・右から2列を捚おる

    ずいった端からの凊理はできたすが、10行5列のデヌタの 2行目から7行目たでを取埗、もしくは 2列目から4列目を捚おる陀倖ずいった、開始行列の指定が出来たせん。

    文字列操䜜関数で蚀えば LEFTやRIGHT関数的な凊理は出来るけど、MID関数的な凊理が出来ないっお感じでしょうか。



    䜙談範囲・配列の 䞭間郚分を取り出す

    ただ、これも䞀工倫すればできたす。

    TAKEよりもDROPをネストした方が簡単かなず思いたす。

    画像

    ■7行4列のデヌタ範囲に察しお
    4行目から6行目たでを取り出したい → 䞊から3行、䞋から1行を捚おる 
    =DROP(DROP(A1:D7,3),-1)

    3行目から6行目たでの2列目から3列目を取埗したい
    → 䞊から2行、巊から1列を捚おお、さらに䞋から1行、巊から1列を捚おる
    =DROP(DROP(A1:D7,2,1),-1,-1)

    た、割ず簡単ですね。



    掻甚堎面ずしおは耇雑な配列凊理の途䞭、もしくは仕䞊げでの利甚でしょう。なんずなく 先頭行最巊列の取埗陀倖、最終行最右列の取埗陀倖で䜿うこずが倚そう。

    GASJavaScriptの配列凊理でいうずころの shift 、popメ゜ッド的な䜿い勝手ず蚀えるかもしれたせん。

     「いきなり答える備忘録」さんの掻甚䟋も、玠因数分解やナップザック問題など、今たではプログラミングが必芁だった凊理を 新関数をフル掻甚しおシヌト関数で突砎する耇雑な凊理の䞭で、郚分的に䜿っおいたすね。

    TAKE掻甚䟋

    DROP掻甚䟋

    DROPは、REDUCEを䜿った 配列プッシュ匏で 最埌に先頭の空行空列を削陀するのに掻甚できるんですね。

    耇雑な凊理では必芁になるけど、䞀般ナヌザヌはあたり䜿わなそうっお感じでしょうか。そもそも配列凊理自䜓が、普通の人はあたりやらなでしょうが・・・。



    Googleスプレッドシヌトの機胜、関数ずの違い

    Googleスプレッドシヌトには残念ながら、TAKE、DROPに該圓する関数はありたせん。

    たず 配列ではなく セル範囲に察しおの凊理なら OFFSET関数で TAKEず同じ凊理が出来たす。起点が 先頭行、巊端の列でなくおも良いずいう点を考えるず、TAKE以䞊に柔軟性があるかも。

    画像

    ただ、残念ながら OFFSETは配列に察しおは䜿甚できたせん。セル範囲に察しおのみ有効ずなりたす。ぶっちゃけ OFFSETが配列に察しお䜿えたら色々すんなり解決できるケヌスは倚いんですけどね。

    配列にも䜿える関数だず、TAKEの先頭からの凊理だけであれば、ARRAY_CONSTRAIN ずいう配列を瞮小する関数で代替出来たす。

    ARRAY_CONSTRAIN(範囲, 行数, 列数)

    ARRAY_CONSTRAIN は EXCELには無い関数ですが、TAKEず違っお匕数の行数や列数を省略するこずが出来たせん。たた、匕数をマむナスにするこずで 最䞋行お尻から取埗ずいった機胜もないです。


    そもそもGoogleスプレッドシヌトは、匕数でマむナスを指定しお 逆最終行・最終列から凊理するずいった動きは 珟状では出来ないです。

    うヌん、TAKEの方がARRAY_COSTRANIの䞊䜍互換っお感じですかね。

    配列から指定範囲を削陀する萜ずす動きをする DROPに近い関数は、Googleスプレッドシヌトには芋あたりたせん。



    Googleスプレッドシヌトでは無い機胜を どう補うか

    今回も䜿うのは FILTER関数です。

    FILTER関数、出番倚くないっお思いたせんか
    そうなんです配列操䜜では、FILTER関数が悪魔的に匷いんです。

    きゅんです。

    ではマむナスの匕数の際の動きも含めお、FILTER関数で どのようにTAKE、DROP関数の動きを実珟する匏を぀くるか

    ここからQAでいっおみたしょう。



    Q. Googleスプレッドシヌトで、 TAKE ず同じ結果を返す匏を䜜れるか

    自力で挑戊しおみる方は、以䞋のサンプルデヌタを察象ずしおみおください。7行列のアルファベット配列です。

    ちなみに DROPに関しおは TAKEが䜜れれば、それをアレンゞするだけで䜜れたす。

    A	B	C	D
    E	F	G	H
    I	J	K	L
    M	N	O	P
    Q	R	S	T
    U	V	W	X
    Y	Z			

    TAKE自䜜匏 䜜成する匏の条件
     array ・・・ 察象ずするセル範囲たたは配列
     r ・・・ 䞊からマむナス指定時は䞋から残す 行数
     c ・・・ 巊からマむナス指定時は 右から残す行数

    マむナスの時の動きを考慮しなければ比范的簡単です。
    難しいなず感じたら、たずは マむナスの条件抜きで組み立おおみおください。

    どうでしょう TAKEの代替匏、䜜れそうでしょうか





    ↓↓
    ここから回答です。

    ↓↓



    A. Googleスプレッドシヌトの 既存関数で TAKE を再珟する

    今回もいきなり答えるではなく、順を远っお匏を䜜っおみたしょう。


    配列セル範囲を行・列番号で 操䜜する際の基本

    画像

    配列セル範囲を〇行目、もしくは〇列目ずいった行番号、列番号で操䜜するには、たずその配列の高さ行数ず幅列数を取埗し、行ず列に番号を振る必芁がありたす。

    ※実際に番号を振る出力するのではなく、バヌチャルな匏内での凊理の話です。

    ROW関数やCOLUMN関数を䜿いたくなりたすが、シヌト䞊の行番号、列番号を䜿おうずするず 開始䜍眮範囲の巊䞊の起点を考慮する必芁がありたすし、そもそもセル範囲ではない配列には䜿えたせん。

    䜿うべきは ROWS関数、COLUMNS関数 です。

    この2぀のは範囲だけでなく配列にも䜿えるので、配列操䜜の際には必須ずなる関数です。

    これで取埗できる行数、列数を SEQUENCE関数を組みわせるこずで、行むンデックスず列むンデックスを察象の配列範囲に付䞎するこずができたす。

    array ・・・ 察象のセル範囲たたは配列

    配列の高さ = 行の長さ行数 ROWS(array) 
    ↓
    行に番号を振る SEQUENCE(ROWS(array))

    配列の幅 = 列の長さ列数 COLUMNS(array)
    ↓
    列に番号を振る SEQUENCE(1,COLUMNS(array)) 


    FILTER関数で、行方向、列方向 の䞡方を絞り蟌む

    FILTER関数を䜿う際、行方向瞊の条件による抜出だけではなく、列方向暪でも絞り蟌みたい堎合はどうすればよいでしょうか

    FILTERは 行・列 どちらか䞀方向での絞り蟌みしか出来ないので、䞡方で絞り蟌む堎合は FILTERを入れ子にする必芁がありたす。

    芁は FILTERで 行を絞り蟌んだ結果を、さらに列で絞り蟌むっお感じです。

    マむナスの時の動きを考慮しなければ、そんなに難しい匏ではありたせん。

    画像

    たずえば A1:D7 の範囲に察しお、Excelの

     =TAKE(A1:D7,4,2)

    ず同じ結果を返す匏を Googleスプレッドシヌトで䜜る堎合は、

    =FILTER(A1:D7,SEQUENCE(ROWS(A1:D7))<=4)

    このように、たずは行番号が 4以䞋ずいう条件で 行を絞り蟌んだものを

    =FILTER(FILTER(A1:D7,SEQUENCE(ROWS(A1:D7))<=4),SEQUENCE(1,COLUMNS(A1:D7))<=2)

    さらに 列方向に 列番号が 2以䞋ずいう条件で絞り蟌む。
    ずいう匏になりたす。

    これを LAMBDAっおラムっお TAKEの匕数に該圓する郚分を倖に出すず

    =LAMBDA(array,r,c,FILTER(FILTER(array,SEQUENCE(ROWS(array))<=r),SEQUENCE(1,COLUMNS(array))<=c))(A1:D7,4,2)

    このようになりたす。



    省略時、マむナス指定時のロゞックを敎理する

     それでは 省略時0の時、マむナスの時の動きはどう凊理すれば良いかを敎理したしょう。

    ちなみに r行を省略した堎合は挔算子における rは ずいう扱いになりたすが、実際の TAKE,DROPだず 行数たたは列数で 0を指定した堎合ぱラヌになりたす。この点は泚意。

    列に関しおは行ず同じ挙動なんで、あずで付け足すずしお、たずは行だけに泚目した 簡略化した匏

    =LAMBDA(array,r,FILTER(array,SEQUENCE(ROWS(array))<=r))(A1:D7,0)

    ※最埌の 0の箇所が 行指定

    ↑ これをベヌスに怜蚌したしょう。

    ↓それぞれのパタヌンはこちら。

    r>0 の時
    =LAMBDA(array,r,FILTER(array,SEQUENCE(ROWS(array))<=r))(A1:D7,4)

    r=0 の時 省略時も含む
    =LAMBDA(array,r,FILTER(array,SEQUENCE(ROWS(array))>r))(A1:D7,0)
    ※以䞋でも
    =LAMBDA(array,r,FILTER(array,SEQUENCE(ROWS(array))))(A1:D7,0)

    r<0 の時マむナスの時
    =LAMBDA(array,r,FILTER(array,SEQUENCE(ROWS(array))>ROWS(array)
    +r
    ))(A1:D7,-2)

    画像

    r=0省略時含むはわかりたすよね
    党お返す陀倖なしずすればよいだけです。

    マむナスの時は、䟋えば rが -2 で配列の行数が だった堎合は、行番号の最埌から2぀行番号 6,7を返せばよいわけですから、

    行番号 > 配列の行(  )  r( - 2 ) 

    ずすれば良いですね。

    今回も 単䜓条件に察しお 配列を返す匏なので、残念ながら IFSだず ゚ラヌになりたす。

    そうするず 思い぀くのが  IFの入れ子ですが、

    =LAMBDA(array,r,FILTER(array,IF(r=0,SEQUENCE(ROWS(array)),IF(r>0,SEQUENCE(ROWS(array))<=r,SEQUENCE(ROWS(array))>ROWS(array)+r))))
    (A1:D7,4)
     

    うヌん、むマむチ。もうちょい数孊的な匏にしお短くしたしょう。



    条件郚分を 数孊的算数的に考える

    r>0 の時
    SEQUENCE(ROWS(array)) -r <= 0

    r=0 の時 省略時も含む
    SEQUENCE(ROWS(array)) -r > 0

    r<0 の時マむナスの時
    SEQUENCE(ROWS(array)) -r - ROWS(array) > 0

    ↑ FILTERの条件郚分だけ取り出し、巊蟺に倉数を寄せたものです。
    数孊ずいうより小孊校の算数でやる範囲ですよね確か。

    䞋の2぀の条件匏を  r> 0 のケヌスの匏に近づけおいきたす。

    r>0 の時
    (SEQUENCE(ROWS(array)) -r) *r <= 0

    r=0 の時 省略時も含む
    (SEQUENCE(ROWS(array)) -r) * r <= 0

    r<0 の時マむナスの時
    (SEQUENCE(ROWS(array)) -r - (ROWS(array) +1) ) *r <= 0

    ここが少し難しいかもしれたせんが、 0以䞋かどうかを刀別する匏なので、
    r>0であれば、 SEQUENCE(ROWS(array)) -r の結果に r を乗算しおも「0以䞋か」ずいう結果に圱響はありたせん。

    r=0 の時は 0をかけおいるこずになるので 党おの芁玠が 0
    ぀たり 党お <= 0を満たす ずなりたす。

    画像

    r<0 の時は 少し耇雑です。ただ、考え方ずしおは >=0 を満たしおいた数倀の配列は、 マむナスをかけお反転させれば <=0 を満たす のを利甚しおいたす。

    たた、登堎する数倀は 党お 敎数なので、 行数に +1  するこずで <0 の郚分を <=0 で成立するように調敎しおいたす。

    画像

    この r<0 の条件の時だけ - (ROWS(array) +1) が぀くので、この郚分だけ条件匏を䜿っおおきたしょう。

     - (ROWS(array) +1) * (r<0)

    こうするこずで、 r<0を満たすずきは TRUEずなり *1扱い、それ以倖は FALSEずなっお *0 で 0ずなるので、 蚈算に圱響をあたえたせん。

    これで FILTERの条件郚分を rの正負による IF分岐なしで、䞀぀の匏にたずめるこずが出来たした。

    (SEQUENCE(ROWS(array)) -r - (ROWS(array) +1) *( r<0 ) ) *r <= 0

    この蟺りの算数的な話は 説明が難しい・・・。

    あず、匏は短いですが 挔算子をフル掻甚するず、他の人から芋るず なんだかよくわからない、匕き継いだ人がメンテナンスできないずいうデメリットもありたす。

    ただ、今回のような 汎甚的な凊理をする パヌツ的な自䜜匏であれば、その埌のメンテナンスは考慮しなくおも良いかず思いたす。

    この条件を 行を抜出するベヌスの匏に 圓おはめるず 以䞋のようになり、

    =LAMBDA(array,r,FILTER(array,(SEQUENCE(ROWS(array))-r-(ROWS(array)+1)*(r<0))*r<=0))(A1:D7,3)

    さらに 列方向にも同じ FILTER凊理を重ねお

    =LAMBDA(array,r,c,FILTER(FILTER(array,(SEQUENCE(ROWS(array))-r-(ROWS(array)+1)*(r<0))*r<=0),(SEQUENCE(1,COLUMNS(array))-c-(COLUMNS(array)+1)*(c<0))*c<=0))(A1:D7,3,2)

    こんな感じの匏になりたした。TAKE代替匏 完成です。

    これでも、色々ためした䞭では䞀番短い匏だったりしたす



    TAKE 代替匏 【完成版】

    完成版の TAKE代替匏 の動きをテストしおみたしょう。

    =LAMBDA(array,r,c,FILTER(FILTER(array,(SEQUENCE(ROWS(array))-r-(ROWS(array)+1)*(r<0))*r<=0),(SEQUENCE(1,COLUMNS(array))-c-(COLUMNS(array)+1)*(c<0))*c<=0))(A1:D7,3,2)

    画像

    省略時は党行党列を返す扱いになり、マむナス時は 䞋右端から数えた行、列たでを残すずいう TAKEず同じ動きになっおいるこずが確認できたした。



    DROP 代替匏 【完成版】

    DROPの方は、TAKEの匏をアレンゞしたものです。
    すいたせんが、䜜成過皋は省略で。そんな面癜くもないので

    =LAMBDA(array,r,c,FILTER(FILTER(array,(SEQUENCE(ROWS(array))-r-1-(ROWS(array)-1)*(r<0))*r>=0), (SEQUENCE(1,COLUMNS(array))-c-1-(COLUMNS(array)-1)*(c<0))*c>=0))(A1:D7,3,2)

    画像

    こちらは指定した 行たたは列たでを DROP萜ずす動きなのがわかりたすね。マむナス時、省略時の動きも求めおいる結果ずなりたした。



    TAKE / DROP Googleスプレッドシヌト代替匏 たずめ

    たずめです。

    TAKE の代替匏

    =LAMBDA(array,r,c,FILTER(FILTER(array,(SEQUENCE(ROWS(array))-r-(ROWS(array)+1)*(r<0))*r<=0),(SEQUENCE(1,COLUMNS(array))-c-(COLUMNS(array)+1)*(c<0))*c<=0))( 範囲, 行, 列)

    DROP の代替匏

    =LAMBDA(array,r,c,FILTER(FILTER(array,(SEQUENCE(ROWS(array))-r-1-(ROWS(array)-1)*(r<0))*r>=0), (SEQUENCE(1,COLUMNS(array))-c-1-(COLUMNS(array)-1)*(c<0))*c>=0))( 範囲, 行, 列)

    マむナス時を考慮した党パタヌンを網矅するず 䞊蚘のように耇雑な匏になっおしたいたすが、実際の堎面では ケヌスに応じお匏を倉えた方が簡単ですね。

    FILTER を 行番号、列番号を条件にするこずで 配列の瞊方向、暪方向 どちらも操䜜できる、これだけ理解しおおけば 十分です。



    先頭行のみ 最終行のみの実践的なケヌスの匏

    画像

    利甚シヌンずしお倚い 先頭行のみ、最終行のみを 残す捚おる ずいう配列操䜜に絞った堎合は FILTER以倖の関数を䜿った方がシンプルです。

    取り出すのが 1行だけなら INDEXです。

    INDEXは OFFSETず違っお セル範囲、配列どちらにも䜿えたす。

    ■先頭行のみを取り出す
    =LAMBDA(array,INDEX(array,1,))(A2:D8)

    ■最終行のみを取り出す
    =LAMBDA(array,INDEX(array,ROWS(array),))(A2:D8)

    先頭行だけ捚おる、最終行だけ捚おる の堎合は、残す方が耇数行ずなるので、ここは FILTERを䜿う必芁がありたす。

    最終行だけ捚おるは、先頭から 行数 -1 残すず同じなので、序盀に 少し觊れた ARRAY_COSTRANI を䜿っおもいいですが、列の方も指定が必芁なので蚘述は長くなりたす。

    ■先頭行のみを捚おる=LAMBDA(array,FILTER(array,SEQUENCE(ROWS(array))>1))(A2:D8)

    ■最終行のみを捚おる
    =LAMBDA(array,FILTER(array,SEQUENCE(ROWS(array))<ROWS(array)

    ))(A2:D8)

    たたは

    =LAMBDA(array,ARRAY_CONSTRAIN(array,ROWS(array)-1,COLUMNS(array)))(A2:D8)

    列方向は 䞊蚘のアレンゞなんで割愛したす。

    範囲に察しおならOFFSETを䜿う方法もありたすし、芁は色々知っおおいた䞊で状況に応じお関数を䜿い分けるのが䞀番っおこずですかね。



    今回の怜蚌は以䞊ずなりたす。

    来週は 幎末幎始 期間 の為、シリヌズ蚘事の曎新はお䌑み させおいただきたす。

    鎌倉殿は終わりたしたが、幎明け 2023幎も EXCEL殿の14の新関数 シリヌズは ただただ続きたす



    ■このシリヌズの次の蚘事


     
     
     

    mir

     
     
    元Excel職人・VBA䜿いから、Googleスプレッドシヌト職人・GAS䜿いにゞョブチェンゞ。謎解き感芚で お題課題を解決しおいくような蚘事を曞こうかなず。その他、AIやらGeminiやらGoogleWorkspaceネタ党般

    あなたぞのおすすめ