出産前後の痔にはご注意!

エクセルのシートは操作シート、テストシート、解答シートの3つあります。
ボタンを押すと範囲を指定できるユーザーフォームが出てきて、範囲を指定した後決定すると、ランダムで100個選んでテストシートと解答シートに反映されるようにしたいです。
写真は自力でやってみたところです。
この先どうしたらいいのかわからないので教えてください!!

「VBAを使って単語テストを作りたいです」の質問画像

質問者からの補足コメント

  • 操作シートです

    「VBAを使って単語テストを作りたいです」の補足画像1
      補足日時:2019/08/13 13:29
  • テストシートです

    「VBAを使って単語テストを作りたいです」の補足画像2
      補足日時:2019/08/13 13:30
  • 解答シートです

    「VBAを使って単語テストを作りたいです」の補足画像3
      補足日時:2019/08/13 13:33
  • ユーザーフォームを使うのは難しいようなので操作シートのA1に範囲の始まりを、A2に範囲の終わりを入力することにしました。
    コードは文字数の制限をオーバーしてしまったので画像にて失礼します途中までしか書いていない上に、VBAは高校でやったことがあるレベルなので初歩的な欠陥が多いとは思いますが見ていただけると嬉しいです

    「VBAを使って単語テストを作りたいです」の補足画像4
      補足日時:2019/08/13 13:47
  • 1.テストシートのB行、E行はそれぞれ51行まであります。ちなみに、操作シートは1691行まであります。

    2.解答シートもテストシートと同様に51行まであります。D行の1はVLOOKUPが機能するか試しただけなので特に意味はありません。混乱させてしまって申し訳ないです。

    3.100個シャッフルされてテストシートには英単語のみが、解答シートにはテストシートと同じ英単語とそれに対応する訳が反映されるようにしたいです。
    A1=1、A2=300だったら、1から300の中から100個選んでシャッフルされるようにしたいです。

    No.4の回答に寄せられた補足コメントです。 補足日時:2019/08/13 17:06
  • ありがとうございます
    画像のとおりであっているでしょうか?
    コピぺさせていただいたのですが、ボタンを押しても実行されません、、
    また、コマンドボタンのコードは何も書かなくていいのですか?

    「VBAを使って単語テストを作りたいです」の補足画像6
    No.5の回答に寄せられた補足コメントです。 補足日時:2019/08/13 21:25
  • できました!ありがとうございます
    ただ、A1とA2の数値を変えるとそれが反映されないのですが、なにか別に設定しなければならないのでしょうか

    No.6の回答に寄せられた補足コメントです。 補足日時:2019/08/13 21:46

A 回答 (7件)

以下のマクロを標準モジュールに登録してください。


操作シートのA1=開始番号 A2=終了番号 として、その範囲内の番号をランダムに100ピックアップし、
テストシート、解答シートへ設定します。尚、設定するのは、A列とD列のみです。(テストシート、解答シートともに)
B,C列は関数でA列から作成する前提です。(E列、F列も同様)
不明点は補足してください。
---------------------------------
Option Explicit

Dim arr() As Long
Dim st_no As Long '開始番号
Dim en_no As Long '終了番号
Public Sub 単語テスト()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim sh3 As Worksheet
Dim maxrow As Long
Dim i As Long
Dim wrow As Long
Dim wcol As Long
Dim no As Long
Dim ix As Long
Set sh1 = Worksheets("操作シート")
Set sh2 = Worksheets("テスト")
Set sh3 = Worksheets("解答")
maxrow = sh1.Cells(Rows.Count, "C").End(xlUp).Row 'C列目の最終行を求める
If (maxrow - 6) < 100 Then
MsgBox ("操作シート単語数不足")
End If
st_no = sh1.Cells(1, "A").Value
en_no = sh1.Cells(2, "A").Value
If st_no < 1 Or (en_no > maxrow - 6) Then
MsgBox ("開始番号又は終了番号不正")
Exit Sub
End If
If (en_no - st_no + 1) < 100 Then
MsgBox ("開始番号~終了番号が100件に満たない")
Exit Sub
End If
ReDim arr(en_no - st_no) '配列の作成
'[0]:開始番号 [1]開始番号+1 .... [最後の要素]:終了番号 のように要素を設定する(但し最後)
For i = 0 To (en_no - st_no)
arr(i) = st_no + i
Next
'0~最後の要素の乱数を100回発生させ、その要素に対応する番号をテストシート及び解答シートへ設定する
Randomize '乱数の種を設定
For i = 1 To 100
ix = Int((en_no - st_no + 1) * Rnd)
'その要素が出現済みなら、次の未出現の要素を取得する
If arr(ix) = 0 Then
ix = get_next_index(ix)
End If
If arr(ix) = 0 Then
MsgBox ("重複添え字発生(バグ):" & ix)
Exit Sub
End If
no = arr(ix)
arr(ix) = 0 '出現済みに設定
'iからテストシートの行、列を決定する
If i < 51 Then
wrow = i + 1
wcol = 1
Else
wrow = i - 49
wcol = 4
End If
sh2.Cells(wrow, wcol).Value = no
sh3.Cells(wrow, wcol).Value = no
Next
MsgBox ("完了")
End Sub
'指定された要素rの次以降で空いている要素を取得する
Private Function get_next_index(ByVal ix As Long) As Long
Dim i As Long
For i = 1 To 100
ix = ix + 1
If ix > (en_no - st_no) Then
ix = 0
End If
If arr(ix) <> 0 Then
get_next_index = ix
Exit Function
End If
Next
get_next_index = -1 'あり得ない
End Function
この回答への補足あり
    • good
    • 0

>ただ、A1とA2の数値を変えるとそれが反映されないのですが、なにか別に設定しなければならないのでしょうか


変えた場合は、再度マクロを実行してください。
    • good
    • 0
この回答へのお礼

できました。本当にありがとうございました。

お礼日時:2019/08/13 21:51

>画像のとおりであっているでしょうか?


>コピぺさせていただいたのですが、ボタンを押しても実行されません、、
>また、コマンドボタンのコードは何も書かなくていいのですか?
コピペしたものを標準モジュールに登録して、直接マクロ(単語テスト)を実行してください。

さもなくば、ボタンを「単語テスト」に割り当ててください。
この回答への補足あり
    • good
    • 0

No3です。


補足ありがとうございました。
1.テストシートのレイアウトですが、
B2,B3,...E2,E3と並んでいるのですか。
そうだとすると、B列の最後の行はいくつですか。(B??→E2となる??はいくつですか?)

2.回答シートも同様に、B2,B3,...E2,E3と並んでいるのですか。
そうであれば、B??→E2となる??はいくつですか。
回答シートのD列に1がありますが、この意味はなんでしょうか?

3.
操作シートのA1=1
操作シートのA2=100
上記の値が設定され、コマンドボタンがクリックされたとき、マクロが実行されますが、
そのとき、テストシート及び回答シートには、どのような内容が設定されればよいのでしょうか。
この回答への補足あり
    • good
    • 0

1.操作シート、テストシート、解答シートのレイアウトはどうなっていますか。


画像で提示してください。
2.ユーザーフォームのレイアウトはどうなっていますか。
画像で提示してください。
3.マクロのソースは画像ではなく、テキストをコピペして貼り付けてください。
そうすれば、それをこちらで確認するときに、それをコピペして確認できます。
4.画像はスマホでとったものではなく、アクセサリの中にSnipping Toolがあるので、
それを使用してください。私がサンプルで提示した画像もsnipping Toolで切りとったものです。
「VBAを使って単語テストを作りたいです」の回答画像3
    • good
    • 0
この回答へのお礼

解答ありがとうございます。質問に補足させていただきました。見ていただけると嬉しいです。

お礼日時:2019/08/13 13:48

何度か同じようなものを作ったり、作らされたりしています。


コードは読みましたが、細かいミスもあるけれども、まだ最初の入り口にも立っていない状態です。

>この先どうしたらいいのかわからないので教えてください!!

一応、内容の正誤は別として通過儀礼として、「疑似乱数生成」が越えられないと次に続かないのです。

Debug.Print Int((maxInt - minInt + 1) * Rnd + minInt)
ここで、ランダムの数字を取るわけですね。だから、それを順番とするのではありませんか?
100単語があれば、100語の順番を決めるわけです。どのように単語の順番を確保するのか、ということです。(分かっている人は、ここの部分に口に挟まないでほしいです。必ずしも、それが正解ではないからです)

ところが、その足かせとなるのが、ユーザーフォームを使うスタイルです。ユーザーフォームは、直接のオブジェクトはユーザーフォームだけです。だから、その単語リストを、メモリに入れるか、シートを代用するかです。それを一過性にするなら、メモリだけでもよいけれども、単語の暗記ですと、そういうわけにもいきません。それらを扱うだけの技術はお持ちでしょうか。

最初は、ユーザーフォームなしで製作することをお勧めします。まず、できるところから始めましょう。
    • good
    • 1
この回答へのお礼

回答ありがとうございます。ユーザーフォームを使うとややこしくなってしまうんですね、、
ユーザーフォームは使わずに作ろうと思います。
何度も申し訳ないのですが、ランダムの数字を取ったあと、シャッフルして別シートに反映させたいのですが、やり方を教えていただけるでしょうか

お礼日時:2019/08/13 11:48

最近は画像と言っても画面のプリントスクリーンではなく写真撮影で載せてきますが、正直見づらく感じるのは私だけなのかな?



これで3つのシートやユーザーフォームの状態まで推測可能なのかと考えちゃいます。
何故範囲指定にユーザーフォームが必要なのか?
どこから範囲を指定するのか?
など、画像からはサッパリ?と思いますけど。
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング