Yut-Ishih
@Yut-Ishih

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

横方向にスプレッドしたExcel表から条件を満足する人数をカウントするには?

解決したいこと

こんな感じで複数のフラグから成り立つ属性をそれぞれの人がもってます

name,1st,2nd,3rd,4th
Alice,1,1,0,0
bob,0,1,1,1
Clara,1,0,1,0
joe,0,1,1,1
john,0,1,1,1
michel,0,1,1,1

そんでもって、この中で3番目のフラグが立っている人数を数えるなら
はなしは簡単です。

しかし、プロジェクトごとにグルーピングされた下のようなExcel表があたえられてます。(組織の人がExcelしか扱えないので、なにかとExcelの範囲内で何とかする文化なのです。)

私の環境です

  1. Windows10
  2. Excel2019(いわゆる買い切り、v16.0.....)をデスクトップで使ってます
  3. WSL2やパワーシェルも導入済みです

希望など

  1. 主観的な理由ですみませんがVBAはなるべく避けたい
  2. CSVを中間ファイルとして作って処理をawk/python/bash/powershellで行うのはOK
  3. 処理結果をExcelにコピペで貼り付けるのもOK
  4. 中間ファイルは同僚に見せないのでawk/python/bash/powershellでもいいといえばいいのです
  5. SQL初心者なので、そちらもなるべくさけたい。

話の続き

Prj1,Alice,Bob,Joe
Prj2,Clara,Michel,
Prj3,Bob,Joe,John

たとえばプロジェクト1の参加者のうち、3番目のフラグが立っている人数をカウント
してって言われてます。どうしたらいいですか?

あとそれぞれのプロジェクトの参加人数は一定ではありません。2人だったり3人だったり、いろいろ・・(人生いろいろ)

プロジェクト2も3もそういう条件を満足する人数をカウントせねば・・・それはプロジェクト1がうまくいけば、あとはコピペでいけますよね?

発生している問題

あとで提示した横方向にスプレッドしたテーブルにおける名前フィールドの右側に属性をインサートしていくという作業が必要になりそうですが、それのやり方がわかりません。

属性における4つのフラグを一つにするために16進数(ヘキサゴナル)に変換することをおもいつきました。Excelならこんな感じで。。

=DEC2HEX(B2*8+C2*4+D2*2+E2)

コピーペーストで逐一作業するのではなく、半自動で、横方向にスプレッドしたテーブルにヘキサゴナル化属性を右側に追加していくにはどうしたらいいですか?

Excelでやらせるより、Awkスクリプト書いたほうがいいですか?

bashの場合

まだ動作検証してませんが、Copilotはつぎのようなコードを提案してきました
(1.csvが、名前と16進数からなるテーブルで、2.csvがグルーピングした横ベタです)

#!/bin/bash
declare -A scores
while IFS=',' read -r name score
do
    scores["$name"]=$score
done < 1.csv

while IFS=',' read -r -a names
do
    for name in "${names[@]}"
    do
        name=$(echo "$name" | xargs)
        echo -n "$name,${scores[$name]},"
    done
    echo
done < 2.csv

もし属性を右側にインサートできたとしたら、テーブルのたとえば第2行はつぎのようになります。

name,hex,name,hex,name,hex
alice,C,bob,7,clara,A

ここまでなんとかこぎつければ、たとえば、3番目のフラグが立っている人数は簡単に求められますね

自分で試したこと

=--(MID(DEC2BIN(HEX2DEC(B2), 4), 3, 1)="1") + --(MID(DEC2BIN(HEX2DEC(D2), 4), 3, 1)="1") + --(MID(DEC2BIN(HEX2DEC(F2), 4), 3, 1)="1")

こんな感じでカウントできると思います。どうしたらここまでもっていけますか?ご助言ください。このMWEではフラグの数が4つなので、ヘキサゴナルなら1ケタで表現できますが、もっとフラグ数が増えた場合でも同じような考え方で拡張可能ですか?

0

2Answer

(私の方ではまだ解法は見つけることができていませんが・・・)
・まず、動作環境(プラットフォーム、Windows or macOS/デスクトップ版 or Web版等)、Excelのバージョンを明記してください(バージョンによって使える数式や動的配列の使用可不可も異なります)
・VBA(or OfficeScript or python)を使ってはダメで、あくまで「一つの数式」で結果を出さなければなりませんか?
・VBA(or OfficeScript or python)を使ってはダメでも、第一段階で、数式を使って別シートや別のセル範囲に中間結果を出力し、その中間結果をさらに数式で加工して結果を出力する、という方法はダメですか?

1Like

Comments

  1. @Yut-Ishih

    Questioner

    @Qnoir ありがとうございます!なぜ横ベタにしたいかというと、そうしておけば、たとえば、project name, number of persons satisfy 3rd flagみたいなテーブルをエクセル関数のコピペ攻撃でかんたんに作られると考えたからです。

  2. なるほど、わかりました。
    bashに比べればショボいですが、Excel数式での回答を示します。

    説明の便宜上、
    ・メンバーごとのフラグを記載したシートの名前を「フラグ」
    ・プロジェクトとそのプロジェクトに属するメンバーを記載したシートの名前を「プロジェクトメンバー」
    とします。

    ・また、下記の数式が有効に機能するには、「フラグ」シートのメンバー名と、「プロジェクトメンバー」シートのメンバー名が大文字・小文字レベルで一致している必要があります。


    「フラグ」シートは下記のような状態であると仮定します。
    image.png

    「プロジェクトメンバー」シートの K2 セルに、下記の数式を入力し、データの最下行までコピーします。

    =SUM(IFERROR(INDEX(フラグ!$B$2:$Z$100,MATCH($A2:$G2,フラグ!$A$2:$A$100,0),K$1),0))
    

    またL列~N列にもK2セルに入れた数式を同様にコピペします。($を入れているので、K2セルに入れた式をコピペすれば、必要な列だけ自動的にずれます)

    image.png

    また、K1~N1 セルには、そのフラグを持っている人数をしらべたいフラグの番号を記入します。
    ここで、入力するフラグ番号は、「フラグ」シートの2列目を「1」とし、以降左の列に行くにしたがって、「2」、「3」・・・とインクリメントした数字を指定します。

    たとえば、画像の例で、フラグ "3rd"と "4th"を持っている人数を調べたいとします。

    "3rd" は「フラグ」シートにおいて、B列を1番目として左から3番目にあるので
    「プロジェクトメンバー」シートの K1 セルに「3」を入力します。

    "4th" は「フラグ」シートにおいて、B列を1番目として左から4番目にあるので
    「プロジェクトメンバー」シートの L1 セルに「4」を入力します。

    これにより、K列以降2行目以降の各行に、その行のプロジェクトのメンバーのうち指定したフラグを持っているメンバーの合計人数が表示されます。

    画像の例で言えば、

    • Prj1のメンバーである Alice, Bob, Joe のうち、3rd のフラグを保持しているのは Bob と Joe の2名なので、セルK2には「2」が返ってきます。
    • Prj3のメンバーである Bob, Joe, John 3名のうち全員が 4th のフラグを保持しているので、セルL4には「3」が返ってきます。
       
  3. @Yut-Ishih

    Questioner

    @Qnoir ありがとうございます! エクセル+bashの両刀使いすると手首が痛くなり、できればエクセルで完結したかったので良かったです。元のDBには、部署内外・会社内外・男女・老若・国内外とかフラグがいっぱいあり、出すべき表は、会社内の数(=部署OR社内)・社外(プロジェクト参加総人数ー社内数)の人数って感じだったとおもうので、ORがつかえると大変助かるのでした。たしか規則では、部署がUpなひとは, 会社は0にしてたと思うので・・

  4. 解決したのであれば、本問をクローズにしましょう。

Comments

  1. @Yut-Ishih

    Questioner

    @culage ありがとうございます!自己レス(Copilotに教えてもらいました)です。「2ndもしくは4thをどちらか」満たしてる人数なら=IF(VLOOKUP(B13,$A$2:$E$8,3,FALSE)+VLOOKUP(B13,$A$2:$E$8,5,FALSE)>0,1,0)でした。これで明日うつうつとせず出勤できそうです!

Your answer might help someone💌