• 締切済み

[VBA]指定範囲の値に指定人数の担当を割り振る

こちらの識者の方々にはいつもお世話になっています。 VBAの質問です。 環境は下記になります。 OS=windows7 pro 64bit Office=Excel2010(14.0.7128.5000) ・やりたいこと VBAを使用して指定範囲の数値の合計(a)を求め、aを指定の値(b)で割った数値の近似値をbの各値に割り振る 日本語にすると難しいので図を見ていただきたいのですが、 担当の人数がB1(毎日変わります) B6:B16の範囲の合計がB2(毎日変わります)、 B1/B2の値がB3となります。 このあたりはsumやaverageで求めればよいのですが、 4人の担当に対して、おおよそ各項目の個数の合計が似た値となるように C1:C16に番号を割り振りたいのです。 (C1:C16の番号の最大値がB1となるように) このようなことがVBAで可能でしょうか? 高校生のころ勉強した記憶がそこはかとなくあるのですが、思い出せず。 もしよろしければコードをご教授いただけますでしょうか。 質問に不備不足等ございましたらご指摘ください。 ご面倒お掛けしますがよろしくお願いします。

みんなの回答

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.5

ソルバーを使って解かせれば、85,85,85,86の組み合わせをエクセルが勝手に計算してくれます。 ただしこの問題ではエボリューショナリを指定する必要がありますが。 もちろんマクロを使い、ソルバーをマクロで操作しても構いません。 準備: D列に担当名1,2,3,4を列記 E列に =SUMIF(C:C,D2,B:B) 以下コピーを準備 F2: =(E2-B$3)^2 以下コピーを準備 F6: =SUM(F2:F5) 目的セルはF6を最小にする 変数セルはC6:C16を指定する 制約条件は C6:C16>=1 C6:C16<=4 C5:C16=int(整数) を設定、解決方法の選択はエボリューショナリ―にして解決する。

  • kkkkkm
  • ベストアンサー率65% (1618/2457)
回答No.4

No3です。 番号と人数の最終照合をするように変更したものです。 Example()のほうだけ変更してます。ただ、どちらにしてもこのやり方では、質問の画像にあるような最適解は出ないので採用しがたいですよね(^^; Sub Example() Dim i As Long, MinValue As Long, k As Long, BRow As Long, TRow As Long Dim Total As Long, MenNo As Integer, Multiplier As Single Multiplier = 0.9 TRow = 6 BRow = Cells(Rows.Count, "B").End(xlUp).Row Do Total = 0 MenNo = 1 MinValue = Range("B3").Value * Multiplier Range(Cells(TRow, "C"), Cells(1000, "C")).ClearContents For i = BRow To TRow Step -1 Total = Total + Cells(i, "B").Value If Total > MinValue Then If Cells(i, "C").Value <> "" Then Exit For ElseIf Cells(i, "B").Value > MinValue Then Cells(i, "C").Value = MenNo Total = 0 MenNo = MenNo + 1 End If Else Call Under(Total, MenNo, TRow, MinValue, i) End If Next Multiplier = Multiplier + 0.1 TRow = 6 Loop Until Range("B1").Value = Application.WorksheetFunction.Max(Range(Cells(TRow, "C"), Cells(1000, "C"))) End Sub

  • kkkkkm
  • ベストアンサー率65% (1618/2457)
回答No.3

No2です。 番号と人数の最終照合はしていないので、データ数が多いと番号が人数より多くなります。 実際のデータで多くなった場合 MinValue = Range("B3").Value * 0.9 の0.9を0.95とかに調整してください。この0.9がなんの根拠もないので強引なものになってます。すみません。

  • kkkkkm
  • ベストアンサー率65% (1618/2457)
回答No.2

たぶん、ちゃんとしたアルゴリズムがあるのかもしれませんが、知らないので、強引に以下のようなものを作ってみました。よろしければ試してみてください。 B列の個数を昇順にしてから実行してみてください。B3に平均があるものとして考えています。 Sub Example() Dim i As Long, MinValue As Long, k As Long, BRow As Long, TRow As Long Dim Total As Long, MenNo As Integer BRow = Cells(Rows.Count, "B").End(xlUp).Row Range(Cells(5, "C"), Cells(1000, "C")).ClearContents TRow = 6 Total = 0 MenNo = 1 MinValue = Range("B3").Value * 0.9 For i = BRow To TRow Step -1 Total = Total + Cells(i, "B").Value If Total > MinValue Then If Cells(i, "C").Value <> "" Then Exit For ElseIf Cells(i, "B").Value > MinValue Then Cells(i, "C").Value = MenNo Total = 0 MenNo = MenNo + 1 End If Else Call Under(Total, MenNo, TRow, MinValue, i) End If Next End Sub Sub Under(ByRef Total As Long, ByRef MenNo As Integer, ByRef TRow As Long, ByRef MinValue As Long, ByRef i As Long) Total = Total + Range("B" & TRow).Value If Cells(TRow, "C").Value = "" Then If i = TRow Then Cells(TRow, "C").Value = MenNo - 1 Else Cells(TRow, "C").Value = MenNo Cells(i, "C").Value = MenNo If Total > MinValue Then Total = 0 MenNo = MenNo + 1 TRow = TRow + 1 Else TRow = TRow + 1 Call Under(Total, MenNo, TRow, MinValue, i) End If End If End If End Sub

  • kkkkkm
  • ベストアンサー率65% (1618/2457)
回答No.1

担当 2 合計 76 平均 38 りんご 20 バナナ 6 みかん 50 のような場合 りんご 20 1 バナナ  6 1 みかん 50 2 でいいのでしょうか。

rihitomo
質問者

補足

はい、あくまで可能な限りの近似値で問題ありません。

関連するQ&A

  • VBA 範囲指定について

    VBAでシートAの範囲A1:B200までをコピーして シートBの範囲A1:B200にコピペしたいのですが、 範囲のB200のみ変動する可能性があるので、その変動に対応出来るようにしたいです。 例) Worksheets("A").Activate PD = Worksheets("入院費用一覧").Range("A1:B〇〇〇").Value Windows("B").Activate Worksheets("B").Range("A1:B〇〇〇").Value = PD B〇〇〇の所に変動できる数値を関数でC1に行数指定して対応できないかと考えていますが、何かいい方法有りますでしょうか。 宜しくお願い致します。 ※VBAあまり詳しくはありません。

  • エクセルの範囲指定

    セルの範囲指定で、例えば、「=average(A1:C30)」という計算式を入れるとします。 そこに、もう1つセルを足す場合は、「,F1」を足して、「=average(A1:C30,F1)」と すると思うのですが、その逆は無いのでしょうか? 「A1:C30」という範囲指定の中の「B20」というセルは省いて範囲指定したい場合は、 なにかいい手が無いでしょうか? エクセルにはそんな考え方はありませんか? どなたかよろしくご教授ください!!

  • ☆Excel VBAでAVERAGE関数を使うとき・・・

    こんにちは。VBA初心者です。 VBAでAVERAGE関数を使いたいのですが、参照範囲を最終行まで指定したい場合、 どのようプログラムすれば良いのでしょうか?     A   B   C    1 5000  2 2000  3 3000  4 1000  5 6000  6  :  7  :    ← A列の値を平均する。           A列には膨大な行が存在すると仮定します。 VBAに詳しい方、教えてください。 どうか、よろしくお願いしますm(_ _)m

  • 選択範囲を値を指定して下げる方法はありませんか?

    EXCEL2007にて 選択範囲の値を指定して拡張したいのですが、 何か方法はありませんでしょうか? 上下左右への拡張や、最後尾までの選択マクロはよく聞くのですが、 指定した数だけ範囲を上下、または左右へ拡張する方法をご教授願いたく投稿いたしました。 たとえばA2:C2選択されている場合、 Range("A2:C5")というマクロではなく、 -4,-5というような数値で範囲を拡張したいのです。 ..........|A|B|C .....1..|10..10..10 .....2..|□□□□ .....3..|■■■■ .....4..|■■■■  .....5..|■■■■ .....6..|10..10..10 .....7..|10..10..10 例: Range("A2:C2").Select Selection.Range(Down:=3) みたいな感じで記述できないでしょうか? 初心者のため説明不足で申し訳ないのですが、 よろしくお願いいたします。

  • Excelで指定した範囲内に値を一定数配置したい

    皆様、お力を貸して下さい。 Excelにて、指定した範囲内に値を一定数配置したいです。 例えば、A1からC50までの範囲に、"1"という値を、全部で8個セルに入力したいです。 どの場所に入れるかはランダムに指定したいです。 VBAを使用しなくてはいけないんだと思っていますが、 ランダムにセルを指定する部分がよくわかりません。 どなたか教えていただけないでしょうか?

  • Excelの数値範囲を指定したクロス集計

    Excel2010です。 やりたいことは、 フィールドA(文字列)、フィールドB(文字列)、フィールドC(文字列)、フィールドD(数値)、フィールドE(数値)、というデータがあり、フィールドDの値を「1未満」「1以上10未満」「10以上30未満」「30以上」と範囲を分けて、フィールドA、B、Cのそれぞれの組み合わせにおけるフィールドDの合計値を求める ということです。 フィールドA="あ"且つフィールドB="イ"且つフィールドC="山"且つフィールドDが1以上10未満のレコードのフィールドEの合計値、というような全ての組み合わせです。 目標の形式としては、ピボットテーブルは、列にフィールドA、Bを、行にフィールドC、Dを設定します。この時、フィールドDのすべての値が羅列することになりますが、上記のように数値範囲を指定して集計したいです。 範囲指定してその合計値を出すにはSUMIFでできるようですが、ピボットテーブルと組み合わせて使えればいいのかなと思ってますが。。。やり方が分かりません もし、一発では無理というのであれば、先に別処理をすることで可能であればその方法でもいいですので、教えてください。

  • VBAで範囲指定をかえるには?

    マクロで範囲の選択したいのですが、任意のセルの値で範囲の大きさをかえるということは可能でしょうか? 例:range("A1:C5").seiect   任意のセルの値より    range("B1:D6").seiect という具合です    全くのトーシローなんで宜しくお願いします。   

  • エクセルVBAで指定範囲をしたい

    今、シート上である文字列を検索してそれを別のシートに転記させる簡単なツールを作っています。 そこでシート丸ごと 検索するのは大変なので、行と列を指定範囲するように入力するようにしました。 例: [列]→ A [行]→ 10 入力した列の値を数値に変換したいのですが、どうすればよいのでしょうか? 例えば Aであれば1, Bであれば2・・・ Zであれば25 のようにしたいのです。

  • セルの範囲指定で、他のセルの値を参照

    たとえば、A2セルに =sum(A3~B10の範囲指定の設定) というような式が入っているとします。 でもそれはA1セルに、"A3"と、B1セルに"B10"と入力されているものを参照している為で A1、B1セルの値を変化させることでA2セルの範囲指定も連動させて変化させるようなA2の式の 書き方ってありますでしょうか? また、行だけ(数値の部分)や列だけ(AやB等)だけ変化させるなどの方法も知りたいです。 宜しくお願いいたします。

  • Excelで集計するセルの範囲を変更したい

        A    B    C 1  日付   気温  3 … 7   12/02  10 8   12/03  11 9   12/04  10 10  12/05  11 11  12/06  12 12  12/07  13 13  12/08  15   … 14  12/09  14   14 ← =average(C12:C14) 15  12/10  13   14 ← =average(C13:C15) 16  12/11  12   13 ← =average(C14:C16) 例えばこの例で、C1の数値にあわせて集計する範囲を変えることはできますか? (C1が5なら、C16の式は=average(C12:C16)としたい) 直近○日の平均気温の推移を調べる際、○の値をいろいろ変えたいのです。 わかりにくくて申し訳ありませんが、よろしくお願いします。

専門家に質問してみよう