こんにちは!今回はExcelのVBAを使って、あらかじめ用意したワードリストからランダムに選択し、新しいデータリストを自動で作成する方法をご紹介します。手動でデータを作成するのは手間がかかるので、このコードを使えば自動でランダムなデータを生成できます。例えば、ブログ記事用のデータ作成や、検証データ、計算問題の作成にも活用できます。
前回はワード数が同じ場合のコードをご紹介しましたが、今回は属性ごとに異なるワード数に対応したロジックについて解説します。さまざまな状況に対応できる柔軟なVBAコードの作り方を一緒に学んでいきましょう!
使用するワードリスト
まず使用するワードリストについて解説します。
ワードリストの構成
ワードリストは「候補」のワークシート上に、「№」「品番」「工程」「開始時」「開始分」「終了時」「終了分」という構成となっており、今回はデータを列ごとに異なりますが、4~12行分作成しました。
作成するデータ数
ワードリストから作成するデータの数は下図の赤枠で指定しています。
VBAの実行結果
VBAを実行した結果下図のような結果を得る事が出来ます。この組合せは実行の都度ランダムで違う結果を得ることが出来ます。
コード解説★★★(コピーはここ)★★★
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
Private WordWs As Worksheet, ResultWs As Worksheet Private WordCell As String, Create_NoCell As String, ResultCell As String Private Word_Column As Long, Word_Row As Long, DataCount As Long Private Words() As Variant, Results() As Variant Private Word_C As Long, Word_R As Long Sub RANDAM() Call Setting Call Change Call Get_Info Call ReSize Call GetWord Call Lottery Call Paste End Sub Sub Setting() 'ユーザーごとに設定する項目 'ワードリストのワークシート名 Set WordWs = Worksheets("候補") 'ワードリストのセル開始位置 WordCell = "B4" '作成するデータリストのワークシート名 Set ResultWs = Worksheets("結果") '作成するデータリストのセル開始位置 ResultCell = "C3" '作成するデータ数情報 Create_NoCell = "D2" End Sub Sub Change() 'セル位置を数字に変換する Word_R = WordWs.Range(WordCell).Row Word_C = WordWs.Range(WordCell).Column End Sub Sub Get_Info() '作成するための情報を取得 'ワードリストの行数と列数を取得 Word_Column = WordWs.Range(WordCell).CurrentRegion.Columns.Count Word_Row = WordWs.Range(WordCell).CurrentRegion.Rows.Count '作成するデータ数の情報を取得 DataCount = WordWs.Range(Create_NoCell).Value End Sub Sub ReSize() ' 配列サイズの設定 ReDim Words(1 To Word_Row, 1 To Word_Column) As Variant ReDim Results(1 To DataCount, 1 To Word_Column) As Variant End Sub Sub GetWord() ' 候補のワードを配列へ格納 With WordWs Words = .Range(.Cells(Word_R, Word_C), .Cells(Word_R + Word_Row, Word_C + Word_Column)).Value End With End Sub Sub Lottery() ' 列ごとに抽選 For i = 1 To DataCount For j = 2 To Word_Column '一番左は№なので[2]から開始 Do RandIndex = Int(Rnd() * Word_Row) + 2 'ヘッダー分を除く Loop While IsEmpty(Words(RandIndex, j)) Results(i, j - 1) = Words(RandIndex, j) Next j Next i End Sub Sub Paste() ' 結果をシートに貼り付け ResultWs.Range(ResultCell).ReSize(DataCount, Word_Column).Value = Results End Sub |
解説
変数の宣言
1 2 3 4 5 |
Private WordWs As Worksheet, ResultWs As Worksheet Private WordCell As String, Create_NoCell As String, ResultCell As String Private Word_Column As Long, Word_Row As Long, DataCount As Long Private Words() As Variant, Results() As Variant Private Word_C As Long, Word_R As Long, Res_C As Long, Res_R As Long |
使用する変数やワークシートオブジェクト、配列を宣言しています。今回は複数のSUBで利用する事から「Private」で宣言を行っています。
メインコード
1 2 3 4 5 6 7 8 9 |
Sub RANDAM() Call Setting Call Change Call Get_Info Call ReSize Call GetWord Call Lottery Call Paste End Sub |
この「RANDAM」マクロは、各処理を順に呼び出して実行します。ボタンなどからこのマクロを指定することで、ワードリストから無作為にデータを抽出してデータリストを生成するプロセスが開始されます。
設定入力セクション
1 2 3 4 5 6 7 |
Sub Setting() Set WordWs = Worksheets("候補") WordCell = "B4" Set ResultWs = Worksheets("結果") ResultCell = "C3" Create_NoCell = "D2" End Sub |
この処理で使用するワークシート名やセル位置を指定します。コピーして使用する際は、自身のExcelに合わせて以下の項目を変更してください。
2行目:ワードリストのワークシート名 例:候補
3行目:ワードリストの開始セル 例:B4
4行目:作成したデータリストを出力するワークシート名 例:結果
5行目:作成したデータリスト開始セル 例:C3
6行目:データリストの作成行数を指定したセル 例:D2
セル情報の数値化
1 2 3 4 |
Sub Change() Word_R = WordWs.Range(WordCell).Row Word_C = WordWs.Range(WordCell).Column End Sub |
文字で指定したセルの位置を数値に変換しています。
2行目:ワードリストの開始セル「B4」の行数を変数に入力
3行目:ワードリストの開始セル「B4」の列数を変数に入力
データリスト作成に必要な情報の取得
1 2 3 4 5 |
Sub Get_Info() Word_Column = WordWs.Range(WordCell).CurrentRegion.Columns.Count Word_Row = WordWs.Range(WordCell).CurrentRegion.Rows.Count DataCount = WordWs.Range(Create_NoCell).Value End Sub |
ワードリストの行列数を取得しています。
2行目:「候補」シートの「B4」セルを含む表の行数を変数に格納する。
3行目:「候補」シートの「B4」セルを含む表の列数を変数に格納する。
4行目:作成するデータリストの行数を変数に格納する。
配列サイズの変更
1 2 3 4 |
Sub ReSize() ReDim Words(1 To Word_Row, 1 To Word_Column) As Variant ReDim Results(1 To DataCount, 1 To Word_Column) As Variant End Sub |
処理の中で使用する配列のサイズを変更します。
2行目:ワードを格納する配列サイズを表に合わせて変更
3行目:データリストへ入力する結果を格納する配列サイズを作成するデータ数に合わせて変更
ワードリストの候補を配列に格納
1 2 3 4 5 |
Sub GetWord() With WordWs Words = .Range(.Cells(Word_R, Word_C), .Cells(Word_R + Word_Row, Word_C + Word_Column)).Value End With End Sub |
Wordsという配列へワードリストのデータを一括取得しています。
2行目:3行目の処理はWordWsのワークシートが対象である。
3行目:ワードリストの内容を一括で配列に格納する。
4行目:2行目のシート指定はここまで。
ワードリストからランダムに選択しデータリストを作成
1 2 3 4 5 6 7 8 9 10 |
Sub Lottery() For i = 1 To DataCount For j = 2 To Word_Column Do RandIndex = Int(Rnd() * Word_Row) + 2 Loop While IsEmpty(Words(RandIndex, j)) Results(i, j - 1) = Words(RandIndex, j) Next j Next i End Sub |
配列に格納したワードリストから列ごとに無作為抽出してデータリストを作成します。
2行目:変数 i
を 1 から DataCount
まで増やしながら、3 ~ 7 行目を繰り返します。
3行目:変数 j
を 1 から Word_Column
まで増やしながら、4 ~ 6 行目を繰り返します。
4行目:Do
ループを開始し、45行目の処理を繰り返します。条件が満たされるまでループします。
5行目:変数 RandomIndex
に、2 から Word_Row
までの範囲でランダムな整数を設定します。【1はヘッダー情報】
6行目:配列 WORD
の randomIndex, j
に格納されている文字が空でないかを確認し、空の場合は 4行目に戻って再度ランダムなインデックスを選びます。
7行目:Results(i, j-1)
に WORD(randomIndex, j)
の値を格納します。
8行目:変数 j
を 1 増やし、3行目に戻って次の列を処理します。
9行目:変数 i
を 1 増やし、2行目に戻って次の行を処理します。
データリストの格納
1 2 3 |
Sub Paste() ResultWs.Range(ResultCell).ReSize(DataCount, Word_Column).Value = Results End Sub |
作成したデータリストを指定したシートのセルへ入力する。
使用している技術
基本:DO-LOOP、FOR-NEXT、二次元配列、配列、RND、ReDIM
コメント