質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

1回答

736閲覧

スプレッドシートで複数セルの組み合わせをCOUNTIF条件としたい

kikuchi33

総合スコア12

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2020/07/15 10:48

やりたいこと

Googleスプレッドシートを使っています。

通常のCOUNTIF関数はセル単位で条件を指定するのものかと思いますが、
複数セルのセット単位で条件を指定したいと考えています。
(この時点で説明が難しく、うまく表現できず申し訳ございません)

具体的には、以下のサンプルファイルのシート2を見ていただきたいのですが、
(以下の文章での説明に限界があるため)
https://docs.google.com/spreadsheets/d/1LhiR3GDR4tqNt6JMHw1CWJUwc4eLdHbi9h3Bm2TsJLQ/edit?usp=sharing

###▼サンプルI2:J2(どちらかの組が4連勝以上した後に、もう片方の組が4連勝以上したかどうか)
D3:G64の中で、
(1)E列を縦方向に見て、値が4以上のセルの下のセルの値が0だったとき
(2)上記E列の値が0だったセルの行から下のG列を見て値が4以上のセルの下のセルの値が0だったとき
(もしくはその反対=(1)でG列をベースに検索し(2)でE列をベースで検索)
これら2つの条件すべてに何回当てはまったケースがあったかを
カウントしたいと思っています。
(当てはまった回数をJ2に出力したい)

サンプルファイルではI2メモに記載の部分をカウントして
J2には2と出力したい。

###▼サンプルI3:J3(3連続以上の交互の単勝(連勝ではない)が何回出たか)
また、D3:G64の中で、
(1)E列を縦方向に見て、値が1のセルの下のセルの値が0だったとき
(2)上記E列の値が0だったセルの行から下のG列をみて値が1のセルの下のセルの値が0だったとき
(3)上記G列の値が0だったセルの行から下のE列をみて値が1のセルの下のセルの値が0だったとき
(4)以下、2連勝以上が出たら終了
(もしくはその反対)
これら4つの条件すべてに何回当てはまったケースがあったかを
カウントしたいと思っています。
(当てはまった回数をJ3に出力したい)

サンプルファイルではI3メモに記載の部分をカウントして
J3には4と出力したい。

###▼サンプルI4:J4(4連続の交互の単勝(連勝ではない)が何回出たか)
また、D3:G64の中で、
(1)E列を縦方向に見て、値が1のセルの下のセルの値が0だったとき
(2)上記E列の値が0だったセルの行から下のG列をみて値が1のセルの下のセルの値が0だったとき
(3)上記G列の値が0だったセルの行から下のE列をみて値が1のセルの下のセルの値が0だったとき
(4)上記E列の値が0だったセルの行から下のG列をみて値が1のセルの下のセルの値が0だったとき
(もしくはその反対)
これら4つの条件すべてに何回当てはまったケースがあったかを
カウントしたいと思っています。
(当てはまった回数をJ4に出力したい)

サンプルファイルではI4メモに記載の部分をカウントして
J4には3と出力したい。

##これら3つの計算方法について
技術的に可能なものでしょうか?

私の知識ではどのような関数を用いたらいいかが検討が付きません。

もし技術的に可能なのであれば
お知恵をお貸しいただければ幸いです。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ルールが複雑なものは作業用の列・行を作って整理することで、ルールをわかりやすくすることが出来ます。
今回のケースもこのまま一足飛びにカウントは出来ないので、紅、白それぞれの連勝数をカウントしているE列、G列の値を使った作業列を作って整理すると良いです。

とはいえ、どういう作業列をつくってどう集計すればいいのかわからないと思うので、回答例を記載しておきます。細かい検証はしてないので、間違いがあるかもしれない点と、あくまでも1つの手法であって、COUNTIFなど他の関数を使って実現する方法もあるという点をご承知おきください。

最終的に作業列を式内で処理できて、比較的短い式となるものを作りました。
今回のケースだと文字列として処理した方が楽そうってとこがポイントでしょうか。
正規表現のところは検索すれば解説サイトが色々あります。

▼サンプルI2:J2(どちらかの組が4連勝以上した後に、もう片方の組が4連勝以上したかどうか)
・作業列で 紅の4連勝を 1、白の4連勝を 2 と置き換え、他は全て消去
・JOINで文字列化 → 1221
・同じチームの4連勝は無視していいので、 1の繰り返しや 2の繰り返し を置き換え → 121
・最初の4連勝はカウントしないので、文字数-1 としたものが求める数値 2

=LEN(REGEXREPLACE(REGEXREPLACE(JOIN(,ARRAYFORMULA(IF(E3:E70=4,1,IF(G3:G70=4,2,)))),"1+","1"),"2+","2"))-1

 
▼サンプルI3:J3(3連続以上の交互の単勝(連勝ではない)が何回出たか)
・作業列で 紅の連連勝と白の連勝数を合算
・JOINで文字列化 → 1234512345671111121234123411111211111231111...
・1が3つ以上繰り返される箇所を A に置き換え → 123451234567A12341234AA3A300...
・数字の部分を全て消去 → AAAA
・Aの数(残ってる文字の数) が求める数値 4

=LEN(REGEXREPLACE(REGEXREPLACE(JOIN(,ARRAYFORMULA(E3:E70+G3:G70)),"111+[02]","A"),"\d",))

 
▼サンプルI4:J4(4連続の交互の単勝(連勝ではない)が何回出たか)
・作業列で 紅の連連勝と白の連勝数を合算
・JOINで文字列化 → 1234512345671111121234123411111211111231111...
・11110 と111112を A に置き換え → 123451234567A12341234AA3111A3000...
・1の繰り返し+A の箇所は 5連続以上の交互の単勝なので消去 → 123451234567A12341234AA330..
・数字の部分を全て消去 → AAA
・Aの数(残ってる文字の数) が求める数値 3

=LEN(REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(JOIN(,ARRAYFORMULA(E3:E70+G3:G70)),"1111[01][02]","A"),"1+A",),"\d",))

 
試合数が何千、何万となると動きが悪くなりそうですが。あとは、必ず勝敗が付く(引き分け等はなし)という条件が必要です。

投稿2020/07/16 01:40

編集2020/07/16 23:57
sawa

総合スコア3002

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kikuchi33

2020/07/16 16:36

お忙しいところ、 とても詳細なご回答をいただき、 誠にありがとうございました! こういったケースの場合は 考え方としてまず作業用の列を作るのですね。 おっしゃる通り、そう言われてもどこから手をつけたらいいかが 全く分からない状況でしたので、 実コードを書いていただけて大変助かりました。 実際の作業用列を作らなくても、 このように数式内でできてしまうのですね。 ありがとうございます。 知らない関数もありましたが いま1つ1つの関数について調べていますが、 実コードだけでなく、 それぞれの解説がとてもわかりやすく、 おかげで大変理解が深まりやすいです。 コードを分割してその結果を見ながら 「なるほど、この箇所は投稿いただいた解説のこの部分を処理しているんだ」 と勉強ができます。 お陰様で100%ではないですが これらの式の意味がわかってきました。 (これを自分で生み出せるかというと全く別の話ですが…) 検証をしていく中で、 追加で質問させていただきたいことが出てきてしまいました。 I2:J2の件ですが、 本件についてこちらの質問の仕方が悪かったようです。 申し訳ございませんでした。 「紅組4連勝以上した直後に白組が4連勝以上したケースを1カウント」 (カウントした連勝は次回以降はカウントしない)、 もしくは 「白組4連勝以上した直後に紅組が4連勝以上したケースを1カウント」 (カウントした連勝は次回以降はカウントしない)、 という計測方法を考えておりました。 例えば =JOIN(, ARRAYFORMULA( IF(E3:E70=4,1, IF(G3:G70=4,2,) ) )) の結果が1221212111112だった場合は、 12-21-21-21-111-12 と分けて、12のペア、21のペア、21のペア、21のペア、12のペアの合計5を 値として出力させたいと考えております。 そうなると、上記の1221212111112を REGEXREPLACEでどのように置換するか、というところまではたどり着きました。 最初はREGEXREPLACEで ・"12","A" ・"21","A" という処理をさせたあとに数字を削除してAの数をカウントしようと思いましたが、 A2AA1111A という結果になってしまい、思うようにいきませんでした。 (AAAA111Aと出力させて数字を消してLENでAの数をカウント、と思ったのですが) また単純に1221212111112の文字数÷2だと やはり希望とする結果にはなりません。 正規表現周りを調整すればできそうな気もするのですが、 1221212111112 を AAAA111Aと出力させるために、 なにかヒントを頂ければ幸いです。 (このアプローチ自体がおかしい場合はご指摘いただければ幸いです) よろしくお願いいたします。 どのような関数があるか、どのような動きをするかという膨大な知識と それら関数の組み合わせ方、活用方法のひらめきは 相当の経験値がないとできないことですね。 そんな貴重なお知恵をお貸しいただき、 誠にありがとうございました! 奥が深く、大変おもしろくも感じており、 今後も投稿いただいた解説とコードを元に、 勉強させていただきます。 引き続きよろしくお願いいたします。
sawa

2020/07/17 00:07 編集

ご質問いただき、自分の回答の一部に誤りがあったのに気づきました。 正規表現で or を使いたい時は、 一文字なら []で、二文字以上の塊なら | で区切るでした。。今回は両方使ってしまっており、動きとしては問題ないものの、書き方としてはおかしいので修正しときました。 参考 http://www-creators.com/archives/5039 で、4連勝交互の際の数字カウントのルールですが、追記内容で理解しました。最初のサンプルだとたまたま私の数え方でも同じになったので勘違いしてたようです。 置き換えという考え方の方向性としてはコメントされた内容で合っていて、あとはまさに上記の OR を使うだけです。 >REGEXREPLACEで >・"12","A" >・"21","A" と順番にやるのではなく、 =REGEXREPLACE(対象文字列,"12|21","A") とORで記載することで、文字列の頭から順に見つけた12か21の塊をAに置き換えてくれるので、期待する AAAA111A という結果が得られるかと思います。
kikuchi33

2020/07/17 01:45

お忙しいところお返事いただき、 誠にありがとうございます! なるほど、順番に置換させずにORでやればよいのですね。 まさに理想通りの動作となりました。 こういった複雑な処理を行う際は作業列を作る、 そして結果を文字列として扱って置換して…というやり方があることを 今回学ぶことができました。 いつも貴重なお知恵をお貸しいただき、 誠にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問