質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

3544閲覧

Excel vbaの振り分けについての質問

qwerty123

総合スコア26

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2015/08/30 22:43

編集2015/08/31 02:15

excelのvbaに関しての質問です。
以下は、A列の要素を4つに適当に分け、B列〜E列に表示するプログラムです。

このプログラムを、
・B10〜Cells(Rows.Count, 1).End(xlUp).Rowの範囲の要素を
・B10〜B17までの要素をそれぞれ8つに振り分け、次にB18〜B25までの要素をそれぞれ8つに振り分け…
・C列〜J列に表示する
という形にしたいのですが、どのようにすればよいでしょうか。

また、do loopの処理がよくわからないです。

よろしくお願いします。

Sub sample()
Dim Total As Integer
Dim TmCnt As Integer
Dim Data1 As Variant
Dim Data2() As String
Dim i As Integer, j As Integer, k As Integer

Total = (Rows.Count, 1).End(xlUp).Row
TmCnt = 4
Data1 = Range("A1:A" & Total).Value
ReDim Data2(1 To Total)
Randomize
For i = Total To 1 Step -1
j = Int(Rnd * i) + 1
Data2(i) = Data1(j, 1)
Data1(j, 1) = Data1(i, 1)
Next i
i = 1
Do
For j = 1 To TmCnt
k = k + 1
Cells(i, j + 1).Value = Data2(k)
If k = Total Then Exit Sub
Next j
i = i + 1
Loop
End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2015/08/31 00:56

TotalがInteger型なのに"た"という文字が入ってるのはどういうことでしょうか?
guest

回答1

0

ベストアンサー

まずDo~Loopですが、この使い方だとループ内でブレイク(ExitDo)されるまで無限に繰り返すループ処理となります。

Do (処理) ・・・ (条件を満たした場合) Exit Do Loop

というように使うことが多いです。
提示いただいたソースではLoop以降に処理がないため、ExitSubでsample関数を抜けることでブレイクとしているようです。

さて、本題ですが、まず元ソースにコメントをつけてみました。

VBA

1Sub sample() 2 Dim Total As Integer 3 Dim TmCnt As Integer 4 Dim Data1 As Variant 5 Dim Data2() As String 6 Dim i As Integer, j As Integer, k As Integer 7 8 Total = (Rows.Count, 1).End(xlUp).Row 'Data1のセル範囲の終端。 9 TmCnt = 4 'Data2の内容をシートに出力する際の横に並べる項目数。 10 11 Data1 = Range("A1:A" & Total).Value 'Data1に抽出対象となるセル範囲を格納 12 ReDim Data2(1 To Total) 'Data1の中からランダムに抽出したセル内容を格納する配列 13 14 Randomize 15 For i = Total To 1 Step -1 16 j = Int(Rnd * i) + 1 'ランダムで行番号を決定 17 Data2(i) = Data1(j, 1) 'Data2配列のi番目にData1のj行目のセル内容を格納 18 Data1(j, 1) = Data1(i, 1) 'Data1のj行目のセル内容をData1のi行目の内容で上書き(質問内容からは目的が読み取れない) 19 Next i 20 21 '変数iはここから再利用。Data2の内容をシートに出力する際の行番号として使用。 22 i = 1 23 Do 24 '変数jは出力する際の列番号。1~4でループしているがj+1に出力するため(B列~E列)となる。 25 For j = 1 To TmCnt 26 'kは明示的に初期化されていないが、初期値は0。 27 'この処理ではData2配列の要素を1~Totalまで取得するカウンタとして使用。 28 k = k + 1 29 Cells(i, j + 1).Value = Data2(k) 'Data2の内容をシートに出力。 30 If k = Total Then Exit Sub 'k=Totalの条件を満たしたら処理終了 31 Next j 32 i = i + 1 33 Loop 'ブレイクするまでDo~Loopを繰り返す 34End Sub

このソースを希望の動きに改修するにあたり、一番異なる部分が要素の取得方法だと思います。

まず元ソースでは特定された範囲(Data1)から値を取得していましたが、この範囲を順次変えていく必要がありそうです。

次に、元ソースではData1からランダムに値を抽出(使用されない要素もあるし、同じ要素が複数回使用される場合もある)していましたが、今回は「B10〜B17までの(8個の)要素を8つに振り分ける」ということです。
振り分けるということなので何かしらルールがあるのだと思いますが、その部分が質問内容の説明からは掴みきれません。
元ソースにようにランダムでよいのでしょうか?

まずはベースソースをしっかり把握し、次にやりたいことを整理して、説明に不足があれば追記をお願いします。

投稿2015/08/31 03:54

jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jawa

2015/08/31 05:38

すみません。 元ソースではランダム値の発生範囲を変えながら、「目的が読み取れない」と記載した部分で使用済み項目をランダム値の範囲外に移すことで重複しないように制御していますね。 改修後の動きもこれと同じような制御でいいのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問