[[20200418102717]] 『関数かVBAでグループ分けをしたい』(ももかん) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『関数かVBAでグループ分けをしたい』(ももかん)

お世話になります。

約150人のグループを約30〜40名の4つの班に分けたいです。

第1希望順にグループ分けをしたいのですが、第1希望グループの人数が定数に達した場合、できれば第2希望、第3希望・・・と順にグループに振り分けたいです。もし第1希望が偏った場合、?@番号が早いもの順、?A男女順でグループに振り分けていきたいです。(希望でないグループでもやむを得ない)

まず、第1条件として、5つの希望タイプがあり、A〜Eタイプの5項目に、第1〜5希望を書いています。希望がない場合、空欄の場合もあります。

第2条件として、4つの希望日があり、第1〜4希望を書いています。希望がない場合空欄の場合もあります。

この第1、第2条件を満たしていくと、第1希望がかなり重複するなどと偏ります。そういう時は第2希望を優先していきたいのですが、それでも重複するので、
そういう場合は、やむをえず?@番号順(1〜150までの番号が振ってあるので早いもの順)、?A男女順(男優先順)としたいです。
最終的に4つのグループに分け、一人一人にグループ番号を振りたいです。

何か良い方法はないでしょうか。

< 使用 Excel:Excel2013、使用 OS:Windows10 >


?@→1、?A→2、です、文字化けしてしまいました、申し訳ありません
(ももかん) 2020/04/18(土) 10:56

よくわからないので確認ですが、
まず、希望日というのとグループ分けの関係が不明です。
希望日とは何ですか?

何か例をひとつ上げてもらえませんか?
こういう希望になったときは、こう考えて、結果はこうするんだという。
できれば、行番号、列番号を明記したレイアウトを示してください。
150人は実際的でないので、もっと少数で結構です。二人とかは除きます。

(γ) 2020/04/18(土) 11:06


 1.どんな希望(アンケート?)データなのですか?
   1人分でもいいので、取り敢えず具体例を書いてください。

 >第1希望グループの人数が定数に達した場合、

 2.定数とは何ですか?
   タイプ別に決まっているなら、具体的に何人ですか?
   参加人数によって決まるなら、どうやって算出するのですか?

   定数合計と参加人数合計には何か関連性がありますか?

     希望日ごとにも定数があるんですか?
   あるなら
     希望日別の定数は、各タイプ別に何人となっているのですか?
     参加人数によって決まるなら、どうやって算出するのですか?

 3.希望タイプが5種類あるのに、なぜ4グループなんですか?

(半平太) 2020/04/18(土) 11:57


γ様、半平太様、レスありがとうございます!
説明が下手で本当に申し訳ありません。私もどうしたら良いのか混乱してきたのでもう一度頭を整理してから出直させてください・・!
(ももかん) 2020/04/18(土) 15:21

頭が整理されてなくて本当に申し訳ありません。
整理のために書かせてください。

N0 氏名    赤  青  黄  白  黒    色タイプ  4/1 4/2 4/3 4/4     性別

1  田中      2          3  1       赤     1   3   2         男

2  山田         2   1     3        黄     1   2      3      女

3  鈴木     1         2  3       赤     1   2             男

上記のようなデータがあります。
色に例えると、赤青黄白黒の5種類から第1希望、第2希望…を選びます。
しかし、白と黒は参考項目で、選んでも次点の赤青黄が優先され、?bPの田中さんのように色タイプは「赤」になります。
色タイプでは赤青黄の3グループになります。その3グループをさらに4種類の日付の4グループに分けたいです。

色タイプで第1希望タイプ 赤110人、青30人、黄10人 (計150人)になります。(赤が圧倒的に多い、次点青です)
さらに日付でも第1希望にそうようにしたいのですが、そうしたら赤、青、黄で4月1日を第1希望にした人が100人、
2日から4日にした人が50人と偏っています。
赤青黄を(30〜40人×4日=150人)の4グループに分けたいのです。定数は1日の平均値が理想(30〜39人、40人は決して超えない)です。

>希望日別の定数は、各タイプ別に何人となっているのですか?
1日赤青黄10〜13人、2日赤青15〜18人、3日目赤黄15〜18人、4日目赤青15〜18人とかでした・・・。
しかし、赤が圧倒的に多いため、青黄の代わりに赤を振り分けるのは有りです。(黄青を赤に振るのも有り)

>参加人数によって決まるなら、どうやって算出するのですか?
参加人数÷日数(必ず4日)です。

アナログな手順を考えているのですが、まず少人数の青と黄を日付の4グループに第1希望日ずつ振り分けてしまい(それでも40人を超えたら第2希望にする)、
圧倒的に多い赤かつ4月1日希望者を順位かつ性別毎に振り分けてしまう方法です。
(ももかん) 2020/04/18(土) 16:02


ようするに色別日付別に平均に分けたいということですね

(ふぃ) 2020/04/18(土) 16:47


ふぃ様、端的に言っていただいてありがとうございます!頭こんがらがっています・・

(ももかん) 2020/04/18(土) 19:42


 ちょっと分からない部分があるんですが。

 日程については、人数が偏らない様にすると言う方針は分かったのですが、
 色も偏ったらダメなんですか?

 今のところ30〜40人と言うのは、色は関係ない制限に読めるんですが・・

 >赤110人、青30人、黄10人 (計150人)
  赤 50人、青50人、黄50人 (計150人) になるべく調整するんですか?(更に日付毎に見ても均等に? ホント?)

 ※最悪のケースでは、希望してもいない色に変更させることもあり、ってことなんですか?

(半平太) 2020/04/18(土) 20:47


半平太様、

>赤 50人、青50人、黄50人 (計150人) になるべく調整するんですか?(更に日付毎に見ても均等に? ホント?)

1日目 赤23人、青10人、黄5人
2日目 赤27人、青10人
3日目 赤23人、青10人、黄5人
3日目 赤37人

例えば最終的に↑みたいな感じに分けたいです・・・。

(ももかん) 2020/04/18(土) 21:10


すみません!2つ目の3日目は4日目の間違いです
(ももかん) 2020/04/18(土) 21:11

  一番多い赤を強制的に減らす訳でもないですね。

  そうなると、色に関して第2順位以下の希望情報はどう言う場面で利用するんでしょうか?

  また、比率的に同じくらいでいいのであれば、
  下図を理想としてもいいと思えるんですが、何か違うんでしょうか?

            赤    青    黄 
    1日目   28     8     3 
    2日目   28     8     3 
    3日目   28     8     3 
    4日目   26     6     1 
     計   110    30    10 

  (まぁ、理想であって、そう仕上げられるとは限らないですけども)

(半平太) 2020/04/18(土) 22:26


半平太様、拙い説明から色々汲み取ってくださりありがとうございます。

すみません、青と黄は人数が少ないので第1希望を優先したいです。
なので、青と黄に関しては1日の上限受け入れ数を10人にしたいです。(10人に達するとは限りませんが)
その分、赤の人数を減らします。
   
     赤  青  黄
1日目  23 10  6
2日目  32  6   1
3日目  32  4   3
4日目  23  10  0
  計  110 30 10

例えば希望日によってはこういうこともありえます。  
(ももかん) 2020/04/19(日) 00:12


 >そうなると、色に関して第2順位以下の希望情報はどう言う場面で利用するんでしょうか?
   ↑
 こちらの疑問。
 第二希望の色を適用するのはどんな時なのですか?
 私には、第一希望だけ決定すればいいとしか思えないのですけど。

(半平太) 2020/04/19(日) 08:13


 >青と黄に関しては1日の上限受け入れ数を10人にしたいです。

 この10人は絶対的なルールなんですか?

 (例えば、青が45人いたとして)

 10を超えているのでマズイ   ┃第2順位があればそれに変えたり、赤に強制的に変えて
                ┃10に収めなければならないと言う事ですか
                ┃
 <自然体では不可>        ┃ <こちらに変更が必要>
         赤   青    黄       ┃          赤   青   黄色 
  1日目  23   11     6        ┃  1日目   24   10     6 
  2日目  24   11     1        ┃  2日目   25   10     1 
  3日目  24   11     3        ┃  3日目   25   10     3 
  4日目  24   12     0        ┃  4日目   21   10     5 
  計     95   45    10        ┃  計      95   40    15 

 いままでの論調では、10人がそんな厳格なルールとも思えないんですが。

(半平太) 2020/04/19(日) 08:41


半平太様、おはようございます!お付き合いいただいてすみません。

>そうなると、色に関して第2順位以下の希望情報はどう言う場面で利用するんでしょうか?

   ↑
> こちらの疑問。
 >第二希望の色を適用するのはどんな時なのですか?
 >私には、第一希望だけ決定すればいいとしか思えないのですけど。

11とか12までだったらオーバーしても大丈夫です。
もし例えば青が1日10〜12に収まらず、4日で60人(1日15人)になってしまったとすると、第2希望の赤か黄グループに入れたいと思いました。

もう一度月曜日仕事のパソコンで1日の上限受け入れ数などを確認してこようと思います。
ありがとうございます!
(ももかん) 2020/04/19(日) 10:52


 1.グループと呼ぶものは
   着色のグループ(3つ)のことなんですか?
   日付のグループ(4つ)のことなんですか?

 2.仮にアンケート結果が自然体で下図になったとします。
   私は、十分に均等だと思うんですが、

           赤   青   黄 
   1日目   20   15    3 
   2日目   20   15    3 
   3日目   20   15    2 
   4日目   20   15    2 
    計    80   60   10 

  上の結果を第2希望の色を利用して、
  下図になるように調整する必要があると言うことなんですね?(仮に10個の上限があった場合)

           赤   青   黄 
   1日目   25   10    3 
   2日目   25   10    3 
   3日目   25   10    2 
   4日目   25   10    2 
    計   100   40   10 

(半平太) 2020/04/19(日) 11:59


半平太様
> 1.グループと呼ぶものは
   着色のグループ(3つ)のことなんですか?
   日付のグループ(4つ)のことなんですか?

着色と日付、両方の条件を満たす必要があるので両方グループと呼びました…がすみません、
おっしゃる通り最初の第1希望の色だけ考慮すればいいかなと思えてきました‥
<半平太様の例>

       赤   青   黄 
   1日目   20   15    3 
   2日目   20   15    3 
   3日目   20   15    2 
   4日目   20   15    2 
    計    80   60   10 

↑青が1日5人(上限10人とする)多いので、

       赤   青   黄 
   1日目   25   10    3 
   2日目   25   10    3 
   3日目   25   10    2 
   4日目   25   10    2 
    計   100   40   10 

↑このように赤か黄に振り分ける必要があるのですが、第2希望が皆この例のように「赤の1日目〜4日目」を指定するわけではなく、「黄の1日目〜4日目」を指定する可能性があります。(黄色は余裕があるので振り分けることは可能です)

(ももかん) 2020/04/19(日) 13:10


詳細に読んでいませんので、誤解があるかもしれません。
少し感想をメモしてみます。

 まず、4つのグループの考え方です。
 (1)大事なのは、色々な制約の中で、
    色についての希望、日付についての希望をどこまで叶えられるか、という話ですね。
 (2)各人の、色、日付が決まれば、
    色×日付のメッシュごとに、そこに割り当てられた人たちを、
    それぞれ4分割して4グループにわければよいわけですね。
   (むろん、4で割り切れない人数なら、不均等分割にならざるを得ないが、
     それは割り切りの世界)

 そこで、(1)の話です。
 まず、選択肢は色で2種類(赤、青)、日付で2種類(4/1、4/2)と仮において説明します。
 採りうる選択は、選択1(赤4/1)、選択2(赤4/2)、選択3(青4/2)、選択4(青4/2)の4つとなります。

 ・i に 選択j を割り当てたときには x(i,j) = 1 、その他は x(i,j) = 0 とします。

 ・各人i が 選択j したときの満足度 s(i,j)を
     色の選択が第1希望、日付の選択が第1希望なら   100
     色の選択が第1希望、日付の選択が第2希望なら    90
     色の選択が第1希望、日付の選択が希望でない     20
     色の選択が第2希望、日付の選択が第1希望なら    50
     色の選択が第2希望、日付の選択が第2希望なら     40
     色の選択が第2希望、日付の選択が希望でない      10
     ・・・・
     ・・・・
     希望とすべて異なる                              -10000
     等と定めます。(ここの評価関数の水準如何によって結果の妥当性に影響があるでしょう)

 ・制約
       ・  各iについて,jの合計Σx(i,j) = 1  
       ・  各jについて、iの合計Σx(i,j)については、
                 下限(j) ≦ iの合計Σx(i,j)  ≦  上限(j)

 上記の前提のもとで、
           すべてのi,jにわたる合計 Σ x(i,j)* s(i,j) を最大化する
 という線形計画法の問題になると思います。

 Excelソルバーを使って解決できればよいのですが、
 残念ながら 変数の数は300が上限だと思います。(最新のバージョンでの上限は未確認です)
 ですから、Excel以外のなんらかの最適化ソルバーと使うと解決に近づくかもしれません。
 興味があれば、
 [[20190121121551]]の 2019/01/26(土) 23:41 に少しだけメモしましたのでご覧下さい。

(γ) 2020/04/19(日) 13:18


γ様

丁寧なご説明ありがとうございました。
初心者には難易度高いですが、考え方の整理にもなり、リンク先も興味深く拝見させていただきました!
どこを自動化してどこを手動化するかも自分のレベルでの見直しが必要だと思いました。
またご相談させてください!
(ももかん) 2020/04/19(日) 22:38


 【追記】
 この手の問題は、「クラス編成問題」と呼ばれているようです。
 ネット検索では、今野浩さんの記事が最初にヒットしました。
 「最適クラス編成問題」
 http://www.orsj.or.jp/~archive/pdf/bul/Vol.36_02_085.pdf
 参考にしてください。

 【まったくの余談】
 今野さんは線形計画法を特に専門にされたかたですね。

 カーマーカー法(線形計画法の手法。従来の単体法によらない内点法と呼ばれる手法の一種)の
 特許問題に関する新書も著しており、彼の闘争的姿勢(まっとうなものだが)に感心した覚えが
 あります。(アルゴリズムは特許になじまない、しかもカーマーカー法は公知の事実も含んで
 おり範囲が広すぎる、というのが彼の主張だった。今はそれとは違う方向に進んでいるようですが)

 彼は、「金融工学」(彼は「理財工学」と称していたが、その名前は普及しなかった)の発展に
 努めた一人なので、その世界にいた人の間ではよく知られた方でしょう。
 また退官されてからは「工学部ヒラノ教授」シリーズを何冊も書いていますので、
 それでご存じの方も多いでしょう。無駄口失礼しました。

(γ) 2020/04/19(日) 23:38


 >>希望日別の定数は、各タイプ別に何人となっているのですか? 
 >1日赤青黄10〜13人、2日赤青15〜18人、3日目赤黄15〜18人、4日目赤青15〜18人とかでした・・・。 

 すみません。そこを見逃していました。 m(__)m

  青は、3日目は希望すらできないし、
  黄は、2日目と4日目は希望すらできない。

 と言う理解でいいですか?

(半平太) 2020/04/20(月) 12:36


 ようやく解った気がします。

  希望日はどの4つを選んでもいいが、第1順位が黄色なら、
  2、4日目は無効日と化す。でも、それで割振りが出来ないなら、
  第2順位以降に落して貰い、2,4日目に空があるならその枠に割振ることができる。

 と言うことですか。

(半平太) 2020/04/20(月) 13:31


γ様、ありがとうございます。数字に疎い初心者なもので仕事が落ち着いてから勉強させていただきます!

半平太様、私のわかりづらい説明を読み返してくださってたみたいでありがとうございます。
私の方こそ説明が足りず、蛇足や後出しも多く、申し訳なさでいっぱいです。

>希望日別の定数は、各タイプ別に何人となっているのですか?
>青は、3日目は希望すらできないし、

  黄は、2日目と4日目は希望すらできない。
 と言う理解でいいですか?

これは私の勘違いで、今日確認してきたら4日とも3つの色は希望できました。
4日とも、赤15人、青10人、黄10人くらいの枠がありました。半平太様が日曜日に書いてくださった例に近いです。

希望日の4つも、色の3つも、どれを選んでもいいのですが、4つの日は3つの色を受け入れる上限があります。
アナログ手順として、
まず1番少ない黄を、全て第1希望に振り分けます。
次に、青は微妙に上限を超えてしまうかもしれませんが、なるべく第1希望になるように振り分けます。
最後に1番多い赤は第1希望にならない人が確実に出てくるので、
赤の1日目を選んだ人が、20人いたら、そのうち5人は別の日か別の色の枠に入ってもらうなどして対処しようと思います。
その枠を算出するのに、第2希望が必要かなと思ったのですが、第1希望の日か色を優先して振り分ければいいし、
第2希望はいらないかなと思えてきました。
今はこの手作業を一発で解決することを考えず、補助するような関数やマクロを考えたほうがいいかなと思っています。

(ももかん) 2020/04/21(火) 00:17


 どれくらい偏ったアンケート結果なのか分からないので、
 考えづらい面がありますねぇ。

 取り敢えず、以下の方針で作ってみました。
 
  黄>青>赤>番号 の順で割振る。

  ※日付の優先順位は、各色別に適用する。
   ※H列の色タイプは使い方が分からないので利用していません。
  ※男女の別は優先順位に加味しない。

 結果が芳しくない場合は、実データ(と同等)を提示していただく方が、お互いにストレスが減ります。

  <Sheet1 実行前>
 行 _A_ __B__ _C_ _D_  E   F  _G_ ____H____  I   J  _K_  L  __M__ _N_  O   P   Q  __R__ _S_ _T_ _U_ _V_ _W_ _X_
   1 N0  氏名  赤  青  黄  白  黒  色タイプ  4/1 4/2 4/3 4/4 性別 
   2   1 田中    3   2   1   3   1 赤                  1     男   
   3   2 山田        2   1       3 黄          1   2       3 女   
   4   3 鈴木    1           2   3 赤          2   4   3   1 男   
   5   4 相内    1   3   2         赤              1              
   6   5 相賀    3   1   2         赤              1   3   2      
   7   6 相川    2   1   3         赤          1       2          
   8   7 愛川    1   3   2         赤          1       2          
   9   8 会川    1   3   2         赤          1       3          
    ::::::::::::::::::

 <Sheet1 実行後>
 行 _A_ __B__ _C_ _D_  E   F  _G_ ____H____  I   J  _K_  L  __M__ _N_  O   P   Q  __R__ _S_ _T_ _U_ _V_ _W_ _X_
  1 N0  氏名  赤  青  黄  白  黒  色タイプ  4/1 4/2 4/3 4/4 性別  4/1 4/2 4/3 4/4 不叶  色  4/1 4/2 4/3 4/4    
  2   1 田中    3   2   1   3   1 赤                  1     男              3             1  18  29  25  26  98
  3   2 山田        2   1       3 黄          1   2       3 女      3                     2  10   9   5   0  24
  4   3 鈴木    1           2   3 赤          2   4   3   1 男                  1         3  10   0   8   8  26
  5   4 相内    1   3   2         赤              1                     1                    38  38  38  34 148

 以下すべて一つの標準モジュールに貼り付けて、Mainを実行する

 Enum ColOrder
     色1 = 2 'B列
     色2
     色3
     日1 = 9 'I列
     日2
     日3
     日4
     希色1 = 14
     希日1 = 17
     確定 = 21
 End Enum

 Type 日付別
     合計上限数 As Long
     合計余裕数 As Long
     色別確定数(1 To 3) As Long
     色別上限数(1 To 3) As Long
     色別余裕数(1 To 3) As Long
 End Type

 Dim 対象者数 As Long
 Dim DB()
 Dim ResultAry()
 Dim cntByDateAndColor(1 To 4) As 日付別

 Sub Main()
     Dim ColorAry()
     Dim ID As Long
     Dim individClrAry()
     Dim individDateAry()
     Dim clrPos, DatePos, minNum
     Dim k, i
     Dim goForNext As Boolean
     Dim colorPrio As Long
     Dim datePrio As Long
     Dim 割当優先色
     Dim maxSofar(1 To 2), maxOrder(1 To 2), dateOrder

     Erase cntByDateAndColor
     Erase ResultAry

     対象者数 = Cells(Rows.Count, "A").End(xlUp).Row - 1
     ColorAry = Range("C1:E1").Value             '色データ格納
     DB = Cells(2, "A").Resize(対象者数, 13).Value

     ReDim Preserve DB(1 To UBound(DB), 1 To 21)
     ReDim ResultAry(1 To UBound(DB), 1 To 4)

     For i = 1 To 4 ' 上限値格納
         cntByDateAndColor(i).合計上限数 = Int(対象者数 / 4) + 1
         cntByDateAndColor(i).合計余裕数 = Int(対象者数 / 4) + 1

         cntByDateAndColor(i).色別上限数(1) = Int(対象者数 / 4) + 1
         cntByDateAndColor(i).色別上限数(2) = 10
         cntByDateAndColor(i).色別上限数(3) = 10

         cntByDateAndColor(i).色別余裕数(1) = cntByDateAndColor(i).色別上限数(1)
         cntByDateAndColor(i).色別余裕数(2) = cntByDateAndColor(i).色別上限数(2)
         cntByDateAndColor(i).色別余裕数(3) = cntByDateAndColor(i).色別上限数(3)
     Next i

     Rem 色と日付の希望順位を調査
     For ID = 1 To 対象者数

         individClrAry = Application.Index(DB, ID, Array(3, 4, 5)) '希望色抜き出し
         minNum = 0
         For i = 1 To 3  '色希望順
             clrPos = Application.Match(i, individClrAry, 0)
             If IsNumeric(clrPos) Then
                 minNum = minNum + 1
                 DB(ID, 13 + minNum) = clrPos & "-" & ColorAry(1, clrPos)
             End If
         Next i

         individDateAry = Application.Index(DB, ID, Array(9, 10, 11, 12))
         minNum = 0

         For i = 1 To 4 '日付希望順
             DatePos = Application.Match(i, individDateAry, 0)
             If IsNumeric(DatePos) Then
                 minNum = minNum + 1
                 DB(ID, 16 + minNum) = DatePos
             End If
         Next i
     Next ID

     '先に、第一希望が黄と青についてのみ割振る
     For Each 割当優先色 In Array(3, 2)   '黄→青の順
         For ID = 1 To 対象者数
             If DB(ID, 確定) <> 1 Then
                 If Left(DB(ID, 希色1) & 1, 1) * 1 = 割当優先色 Then
                     goForNext = False '初期化
                     For datePrio = 1 To 4
                         If AssignedAndUpdate(ID, 割当優先色, datePrio) Then
                             goForNext = True
                             Exit For
                         End If
                     Next datePrio
                 End If
             End If
         Next ID
     Next

     '希望日付に沿った割振り

     For ID = 1 To 対象者数
         '        If ID = 4 Then Stop
         If DB(ID, 確定) <> 1 Then

             '希望日順に成立するかチェックする-------------------
             goForNext = False '初期化

             For colorPrio = 1 To 3

                 For datePrio = 1 To 4
                     If AssignedAndUpdate(ID, Left(DB(ID, 希色1 + colorPrio - 1) & 1, 1) * 1, datePrio) Then
                         goForNext = True
                         Exit For
                     End If
                 Next datePrio

                 If goForNext = True Then
                     Exit For
                 End If
             Next colorPrio
         End If
     Next ID

     '不本意な割振り(未確定者処理)

     For ID = 1 To 対象者数
         If DB(ID, 確定) <> 1 Then

             Erase maxSofar
             Erase maxOrder

             For dateOrder = 1 To 4
                 If DB(ID, 希日1 + dateOrder - 1) > 1 Then '有効希望日あり
                     If maxSofar(1) < cntByDateAndColor(dateOrder).合計余裕数 Then
                         maxSofar(1) = cntByDateAndColor(dateOrder).合計余裕数
                         maxOrder(1) = dateOrder
                     End If
                 Else '有効希望日無し
                     If maxSofar(2) < cntByDateAndColor(dateOrder).合計余裕数 Then
                         maxSofar(2) = cntByDateAndColor(dateOrder).合計余裕数
                         maxOrder(2) = dateOrder
                     End If
                 End If
             Next

             '強制割当て
             If maxSofar(1) > 0 Then
                 Update ID, maxOrder(1), 1
             ElseIf maxSofar(2) > 0 Then
                 Update ID, maxOrder(2), 1
             Else
                 Stop 'ロジックミス
             End If
         End If

     Next ID
     '結果打ち出し

     Columns("N:R").Resize(対象者数).ClearContents

     With Range("N2:Q2").Resize(対象者数)
         .Value = ResultAry
         .Columns(5).FormulaLocal = "=REPT(""色"",AND(COUNTBLANK(C2:E2)<3,INDEX(C2:E2,SUM(N2:Q2))<=0))&REPT(""日"",AND(INDEX(I2:L2,MATCH(9,N2:Q2))<=0,COUNTBLANK(I2:L2)<4))"

         .EntireColumn.FormatConditions.Delete
         .FormatConditions.Add Type:=xlExpression, Formula1:="=N2=1"
         .FormatConditions(1).Interior.Color = vbRed
         .FormatConditions(1).Font.Color = vbYellow

         .FormatConditions.Add Type:=xlExpression, Formula1:="=N2=2"
         .FormatConditions(2).Interior.Color = vbBlue
         .FormatConditions(2).Font.Color = vbYellow

         .FormatConditions.Add Type:=xlExpression, Formula1:="=N2=3"
         .FormatConditions(3).Interior.Color = vbYellow

     End With

     Range("N1").Resize(1, 4).Value = Range("I1").Resize(1, 4).Value
     Range("R1").Value = "不叶"
     Range("T1").Resize(1, 4).Value = Range("I1").Resize(1, 4).Value

     Range("S2:S4").Value = [{1;2;3}]
     Range("T2:W4").FormulaLocal = "=COUNTIF(N$2:N$500,$S2)"
     Range("T5:W5").FormulaLocal = "=SUM(T2:T4)"
     Range("X2:X5").FormulaLocal = "=SUM(T2:W2)"

 End Sub

 Private Function AssignedAndUpdate(ByRef ID As Long, colorOrder, datePrio) As Boolean
     Dim dateOrder As Long

     dateOrder = DB(ID, 希日1 + datePrio - 1)

     If colorOrder > 0 And dateOrder > 0 Then
         If cntByDateAndColor(dateOrder).合計余裕数 > 0 Then
             If cntByDateAndColor(dateOrder).色別余裕数(colorOrder) > 0 Then

                 Call Update(ID, dateOrder, colorOrder)
                 AssignedAndUpdate = True
             End If
         End If
     Else
         AssignedAndUpdate = False
     End If
 End Function

 Private Sub Update(ID As Long, dateOrder As Variant, colorOrder As Variant)
     DB(ID, 確定) = 1

     cntByDateAndColor(dateOrder).色別確定数(colorOrder) = _
     cntByDateAndColor(dateOrder).色別確定数(colorOrder) + 1

     cntByDateAndColor(dateOrder).色別余裕数(colorOrder) = _
     cntByDateAndColor(dateOrder).色別余裕数(colorOrder) - 1

     cntByDateAndColor(dateOrder).合計余裕数 = _
     cntByDateAndColor(dateOrder).合計余裕数 - 1

     ResultAry(ID, dateOrder) = colorOrder
 End Sub

(半平太) 2020/04/21(火) 12:41


半平太様こんばんは。今やっと家に帰ってきました。
せっかく作ってくださったのに、今さっきコロナと上司の気まぐれで条件をまた変えると言われてしまいました。
掲示板を開いたらお返事くださっていて泣いてしまいました・・・。
今すぐに検証できない環境で、申し訳ありません。絶対後で検証して活かしたいです。
取り急ぎ、お礼まで、ありがとうございました。
(ももかん) 2020/04/21(火) 22:00

  >条件をまた変えると言われてしまいました。

  ・・で、どんな条件に変わったんですか?

  こちらとしては、実データがないと、どの程度の偏りなのか分からないので非常にやりにくいです。
  下記のプログラムで、実データをアップしていただけないですか?
   ※ C2:G150,I2:L150の9列分のデータを吸い上げます。
   ※ 空欄は「#」に変換される。

  私が使用したテストデータなら、以下となってイミディエイトウィンドウに出ます。
  それをコピーして、ここへ貼り付けていただければ、こちらで1文字ずつ分解します。

  3#1132111#1111111111111111112121113111111111311112113111311111211121313111・・以降省略(全149文字)
             途中省略
  #31#2#####################################################################・・以降省略(全149文字)

  Sub PickUpData()
     Dim Strs
     Dim col As Range, aCell As Range

     For Each col In Range("C2:G150,I2:L150").Columns
         For Each aCell In col.Cells
             Strs = Strs & IIf(aCell.Value = "", "#", aCell.Value)
         Next
         Debug.Print Strs
         Strs = ""
     Next
 End Sub

(半平太) 2020/04/22(水) 12:24


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.