Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


2189 / 13645 ツリー ←次へ | 前へ→

【69468】同じデータを連続させたくない oslo 11/7/17(日) 13:19 質問[未読]
【69469】Re:同じデータを連続させたくない 読解不能 11/7/17(日) 16:33 回答[未読]
【69470】Re:同じデータを連続させたくない ichinose 11/7/17(日) 19:49 発言[未読]
【69471】Re:同じデータを連続させたくない oslo 11/7/18(月) 11:35 質問[未読]
【69480】Re:同じデータを連続させたくない ichinose 11/7/20(水) 17:42 発言[未読]
【69483】Re:同じデータを連続させたくない oslo 11/7/21(木) 6:04 お礼[未読]
【69484】Re:同じデータを連続させたくない oslo 11/7/21(木) 13:30 お礼[未読]

【69468】同じデータを連続させたくない
質問  oslo  - 11/7/17(日) 13:19 -

引用なし
パスワード
    VBA初心者です。乱数を使って下のようなエントリー表をつくりたいと考えています。A校からG校まで、約40人います。各校3人以上出場しますが、同じ学校が連続して出場しないようにしたいのです。VBAで乱数関数を使い、並べ替えることまではできたのですが、同じ学校が連続してしまいます。A校の次もA校とならないように、抽選で各校ばらばらに出場できるようにできないでしょうか。
 よろしくお願いいたします。

No. 氏名 学校 採点 順位
1  aaa  A校
2  bbb  C校
3  ccc  F校
4  ddd  B校
  

【69469】Re:同じデータを連続させたくない
回答  読解不能  - 11/7/17(日) 16:33 -

引用なし
パスワード
   ▼oslo さん:
> VBA初心者です。乱数を使って下のようなエントリー表をつくりたいと考えています。A校からG校まで、約40人います。各校3人以上出場しますが、同じ学校が連続して出場しないようにしたいのです。VBAで乱数関数を使い、並べ替えることまではできたのですが、同じ学校が連続してしまいます。A校の次もA校とならないように、抽選で各校ばらばらに出場できるようにできないでしょうか。
> よろしくお願いいたします。
>
>No. 氏名 学校 採点 順位
>1  aaa  A校
>2  bbb  C校
>3  ccc  F校
>4  ddd  B校
>  

一つ前の学校を変数にメモっておいて、今回乱数で算出した学校と同じなら
もう一回乱数にかけたらいいと思います。

【69470】Re:同じデータを連続させたくない
発言  ichinose  - 11/7/17(日) 19:49 -

引用なし
パスワード
   こんばんは。

>>VBAで乱数関数を使い、並べ替えることまではできたのです
でしたら、出来ているコードは、提示してください。


>>A校からG校まで、約40人います。各校3人以上出場しますが、同じ学校が連続して出場しないようにしたいのです。

AからG校は、全て同じ人数なんですか?
例えば、3人なら全校3人 4人なら、全校4人?

そうなら、
>一つ前の学校を変数にメモっておいて、今回乱数で算出した学校と同じなら
>もう一回乱数にかけたらいいと思います。

これでも良さそうですが、学校によって人数が違う場合もあるなら、
もう少し工夫が必要ですねえ!!

例えば簡単な例で
 A校 3人
 B校 2人
 C校 1人
だとして(問題は3人以上ですが、例を簡単にすると)、

乱数で 
最初にC校、次にB校が選ばれてしまうと、
A校が連続してしまいますよね!!

この場合、
A校
B校
A校
B校
A校
C校

と連続しない組合せは確かにありますからねえ!!

人数が均等になるまでは別のアルゴリズムも必要ですね!!

【69471】Re:同じデータを連続させたくない
質問  oslo  - 11/7/18(月) 11:35 -

引用なし
パスワード
   おはようございます。返事が送れて申し訳ありません。


 >>AからG校は、全て同じ人数なんですか?
 例えば、3人なら全校3人 4人なら、全校4人?

 今職場に来て、確認してみると、
 A校2人、B校5人 C校3人 D校4人 E校3人 F校3人 G校10人の計30人でした。

>>出来ているコードは、提示してください。

 自分が理解できる範囲で、乱数関数を入れて昇順でならべかえました。
 

>>別のアルゴリズムも必要ですね!!
 
 どのように、考えていけばいいのかわからない状態です。
 教えていただけると、大変ありがたいです。
 よろしくお願いいたします。


Sub 乱数の発生()

Application.ScreenUpdating = False
    
  '名簿最終行の確認
  Dim i As Integer
  i = 3
  Do While Cells(i, 3) <> ""
  i = i + 1
  Loop
  
  '乱数の発生
  Range("K3").Formula = "=RAND()"
  Range("K3").Copy
  Range(Cells(4, 11), Cells(i - 1, 11)).PasteSpecial
  
  '関数を値のみ貼り付けて、値を固定する
  Range(Cells(3, 11), Cells(i - 1, 11)).Copy
  Range("K3").PasteSpecial Paste:=xlValues
  
  
  '乱数の昇順で並べ替え
  Range(Cells(3, 2), Cells(i - 1, 11)).Select
  Range(Cells(3, 2), Cells(i - 1, 11)).Sort _
  key1:=Range("K3"), order1:=xlAscending
  
  '乱数関数の列のクリア
  Range("K3:K32").ClearContents
  Range("A1").Select
  
  ' スクロール列の設定
  ActiveWindow.ScrollColumn = 2
  ' スクロール行の設定
  ActiveWindow.ScrollRow = 1
  
Application.ScreenUpdating = True
  
End Sub

【69480】Re:同じデータを連続させたくない
発言  ichinose  - 11/7/20(水) 17:42 -

引用なし
パスワード
   こんにちは。
仕事で投稿できませんでした。
まず、訂正から・・・・。


>例えば簡単な例で
> A校 3人
> B校 2人
> C校 1人
>だとして(問題は3人以上ですが、例を簡単にすると)、
>乱数で 
>最初にC校、次にB校が選ばれてしまうと、
>A校が連続してしまいますよね!!

これ、最初にB校、次にC校、その次にB校が選ばれてしまうと、
>A校が連続してしまいますよね!!
でした。


で、・・・・。

>>>出来ているコードは、提示してください。
私は、当初Collectionオブジェクトを使っているのかなあ なんて想像していましたが、
Excelらしい方法ですねえ!!


>
> 今職場に来て、確認してみると、
> A校2人、B校5人 C校3人 D校4人 E校3人 F校3人 G校10人の計30人でした。

では、サンプルデータを↑に倣って作成してみましょう。

新規ブックにて、標準モジュールに

'================================================================
Sub sample1()
  With ActiveSheet
    .Range("a1:c1").Value = Array("NO", "氏名", "校名")
    With .Range("a2:a31")
     .Formula = "=row()-1"
     .Value = .Value
    End With
    With .Range("b2:b26")
     .Formula = "=rept(char(63+row()),3)"
     .Value = .Value
    End With
    With Range("b27:b31")
     .Formula = "=char(38+row())&char(38+row()+1)&char(38+row()+2)"
     .Value = .Value
    End With
    With .Range("c2:c31")
     .FormulaArray = Evaluate("{""A校"";""A校"";""B校"";""B校"";""B校"";""B校"";""B校"";" & _
           """C校"";""C校"";""C校"";""D校"";""D校"";""D校"";""D校"";""E校"";""E校"";" & _
           """E校"";""F校"";""F校"";""F校"";""G校"";""G校"";""G校"";""G校"";""G校"";" & _
           """G校"";""G校"";""G校"";""G校"";""G校""}")
     .Value = .Value
    End With
  End With
End Sub

上記のsample1を実行してみてください。
A列からC列に サンプルデータが作成されます。

このサンプルデータに対して、同じ学校が連続しないように並べ替えます。

別の標準モジュールに

'=====================================================================
Sub test1()
  Dim rng1 As Range
  Dim rng2 As Range
  With ActiveSheet
    Set rng1 = .Range("a2", .Cells(.Rows.Count, "a").End(xlUp))
    With rng1
     If .Row > 1 Then
       Set rng2 = .Offset(0, 2)
      
       With .Offset(0, 3).Resize(, 2)
        .Offset(-1, 0).Rows(1).Value = Array("t1", "t2")
        .Formula = Array("=RAND()", "=COUNTIF(" & rng2.Address & ",c2)")
        .Value = .Value
       End With
       .Parent.Range("a1").Sort Key1:=Range("E2"), Order1:=xlDescending, Key2:=Range("C2") _
           , Order2:=xlAscending, Key3:=Range("D2"), Order3:=xlAscending, Header:= _
            xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
            SortMethod:=xlPinYin, DataOption1:=xlSortNormal, DataOption2:= _
            xlSortNormal, DataOption3:=xlSortNormal
       Set rng2 = .Offset(0, 4)
       With .Offset(0, 5)
        .Offset(-1, 0).Cells(1).Value = "t4"
       
        .Formula = "=mod(row(),max(" & rng2.Address & "))"
        .Value = .Value
       End With
       .Parent.Range("a1").Sort Key1:=Range("F2"), Order1:=xlAscending, Header:=xlGuess, _
         OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
         :=xlPinYin, DataOption1:=xlSortNormal
        
     End If
    End With
    .Range("d:f").ClearContents
  End With
  Set rng1 = Nothing
  Set rng2 = Nothing
End Sub

上記test1を実行してみてください。
同じ学校は、連続しないように並べられると思います。

尚、D,E,F列は、作業列として、プログラムが使っています。
実際には、D,E列にもデータが入っているとしたら、作業列を移動しなければ
なりませんが、それはご自分で考えてみてください。


>
> 自分が理解できる範囲で、乱数関数を入れて昇順でならべかえました。
> 
>
>>>別のアルゴリズムも必要ですね!!
> 
> どのように、考えていけばいいのかわからない状態です。
> 教えていただけると、大変ありがたいです。
> よろしくお願いいたします。
>
>
>Sub 乱数の発生()
>
>Application.ScreenUpdating = False
>    
>  '名簿最終行の確認
>  Dim i As Integer
>  i = 3
>  Do While Cells(i, 3) <> ""
>  i = i + 1
>  Loop
>  
>  '乱数の発生
>  Range("K3").Formula = "=RAND()"
>  Range("K3").Copy
>  Range(Cells(4, 11), Cells(i - 1, 11)).PasteSpecial
>  
>  '関数を値のみ貼り付けて、値を固定する
>  Range(Cells(3, 11), Cells(i - 1, 11)).Copy
>  Range("K3").PasteSpecial Paste:=xlValues
>  
>  
>  '乱数の昇順で並べ替え
>  Range(Cells(3, 2), Cells(i - 1, 11)).Select
>  Range(Cells(3, 2), Cells(i - 1, 11)).Sort _
>  key1:=Range("K3"), order1:=xlAscending
>  
>  '乱数関数の列のクリア
>  Range("K3:K32").ClearContents
>  Range("A1").Select
>  
>  ' スクロール列の設定
>  ActiveWindow.ScrollColumn = 2
>  ' スクロール行の設定
>  ActiveWindow.ScrollRow = 1
>  
>Application.ScreenUpdating = True
>  
>End Sub

【69483】Re:同じデータを連続させたくない
お礼  oslo  - 11/7/21(木) 6:04 -

引用なし
パスワード
   おはようございます。
ご連絡が遅れてすみません。
こんなに丁寧に回答をいただけるなんて、思ってもいませんでした。とても感謝しています。
 ですが、私の力ではこのコードがどのようなアルゴリズムを使っているのか、すぐにはわからない状態です。自分で入力してみてよく考えて、改めてご連絡をしようと思います。また、どうしてもわからないときはまた、お尋ねしてもいいでしょうか。
 
 お忙しい中、本当にありがとうございます。

【69484】Re:同じデータを連続させたくない
お礼  oslo  - 11/7/21(木) 13:30 -

引用なし
パスワード
   なんとか完成することができました!!。


>私は、当初Collectionオブジェクトを使っているのかなあ なんて想像していましたが、>Excelらしい方法ですねえ!!


 Collectionオブジェクトというものがどういうものなのかわからないのですが、
私の理解できるコードにそって作っていただいて、ありがとうございます。
また、サンプルファイルまで作っていただいて、理解がすすみした。

 以下、常識的なことなのでしょうが、私にとって「目からウロコ」のようなことを書きます。
 「.Value = .Value」というのは形式を選択して値の貼り付けと同じ意味になるんですね。最初、意味がわからなかったのですが、とても便利だということに気がつきました。これから使わせていただきます。
 rept関数というのも初めて見ました。
.Formula = "=char(38+row())&char(38+row()+1)&char(38+row()+2)"は、頭がクラクラしそうですが、文字列をこれで入れられるということがわかりました。
 まだ十分理解できていないのが、Addressの使い方で、式のコピー、貼り付けをしなくてすむのでとても便利ですが、まだ使いこなせるほどわかっていません。
これから勉強していきます。
 modを使って連続させないという考え方も、自分1人では、絶対に思いつきもしない方法でした。いろいろな、技が散りばめられていて、凄いものだなーとつくずく思いました。 
 お忙しい中、本当にありがとうございました。

2189 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free