29089


今回やりたいことはタイトルの通りなのですが、For文の範囲の  
決め方でわからないことがあります。

`1 To 5`にした時は、入力した5つのセルのデータを5×5の範囲に  
重複なく転記してくれたのですが、

`1 to 25`にしたときは、なぜかフリーズしてしまいます。強制終了  
したところ、`1 To 5`にして実行した時と同じ結果が得られました。

[code]

    Sub Sample()
        Dim i As Integer
        Dim myNum_1 As Long '転記先列番号
        Dim myNum_2 As Long '転記先行番号
        Dim myFlag_1(1 To 5) As Boolean, myFlag_2(2 To 6) As Boolean
    
        '乱数系列を初期化
        Randomize
    
        For i = 1 To 25 'あらかじめデータを入力した25個のセルを参照する為
    
            Do　'転記先の列番号をランダムで重複なく作成する
                '乱数=Int((最大値 - 最小値 +1 ) * Rnd + 最小値)
                myNum_1 = Int((5 - 1 + 1) * Rnd + 1)
            Loop Until myFlag_1(myNum_1) = False
    
            Do　'転記先の行番号をランダムで重複なく作成する
                '乱数=Int((最大値 - 最小値 +1 ) * Rnd + 最小値)
                myNum_2 = Int((6 - 2 + 1) * Rnd + 2)
            Loop Until myFlag_2(myNum_2) = False
    
            Cells(myNum_1, myNum_2) = Cells(i, 1).Value
    
            myFlag_1(myNum_1) = True
            myFlag_2(myNum_2) = True
    
        Next i
    End Sub
    
[/code]

以上、どなたか原因を教えていただけないでしょうか。


CC BY-SA 3.0
2016-09-24T06:20:33.720
29086
2016-09-24T14:49:12.820
2016-09-24T14:49:12.820
5519
7470
question
excel vba
25個のセルに入力した各データを、5×5の別の範囲のセル群にランダムに重複なく転記したい


そのコードでは行と列を別々にマークしているので、どちらか一方でも重複するとスキップしてしまいます。そのため11個目のセルを探すことができず、無限ループに陥っています。

正しくは行・列の組み合わせすべてにフラグを用意する必要があります。下の例では5x5の二次元配列を使っています。

[code]

    Sub Sample()
        Dim i As Integer
        Dim row As Long '転記先行番号
        Dim col As Long '転記先列番号
        Dim myFlag(1 To 5, 2 To 6) As Boolean
    
        '乱数系列を初期化
        Randomize
    
        For i = 1 To 25 'あらかじめデータを入力した25ヶのセルを参照する為
    
            Do  '転記先の行・列番号をランダムで重複なく作成する
                '乱数=Int((最大値 - 最小値 +1 ) * Rnd + 最小値)
                row = Int((5 - 1 + 1) * Rnd + 1)
                col = Int((6 - 2 + 1) * Rnd + 2)
            Loop Until myFlag(row, col) = False
    
            Cells(row, col) = Cells(i, 1).Value
    
            myFlag(row, col) = True
    
        Next i
    End Sub
    
[/code]

なお座標を乱数で出す方法の場合、空きセルが少なくなるにつれ「はずれ」を引く確率が高くなります。100x100とかになると処理時間が気になるかもしれません。

* * *

例えば最初に B1 (1,2) が使われた場合、これに対応するフラグは `myFlag_1(1)` と `myFlag_2(2)` で、これらが True
になります。その後で B2 (2,2) を使おうとした場合、対応するフラグは `myFlag_1(2)` と `myFlag_2(2)` ですが、
`myFlag_2(2)` は既に True になっているため使えません。

10個の行のうちどの行が使用済みか、10個の列のうちどの列が使用済みか、という情報しか保持していないので、「列は違うけど行が同じ」「行は違うけど列は同じ」というセルが認められません。10行10列の範囲に行・列どちらも重ならないように配置したら、10個のセルしか使うことができません。

`Next i`
の行にブレークポイントを設定すると1つ転記するたびに実行を一時停止できますから、このタイミングで「ローカルウィンドウ」「ウォッチウィンドウ」を使い
`myFlag_1` `myFlag_2` がどのような状態になっているか確認してみると、わかりやすいのではないでしょうか。


CC BY-SA 3.0
2016-09-24T07:25:36.610
29089
2016-09-24T09:19:34.293
2016-09-24T09:19:34.293
8000
8000
29086
answer