200件から30個全て違う数字を選ぶには…?


竜言語魔法  2005-12-22 05:52:00  No: 129174

VB6を使用しているのですが数字がかぶりまくりで困ってます…。
For i = 1 To 29
  aaa(i) = Int(Rnd * 200)
  For j = 0 To 29
  if aaa(i) = aaa(j) and a <> b then
     i = i - 1
  next
next

考えた挙句に出来上がってミスしまくりなコードです。
良く考えるとなんか違うような気がしてなりません…。
ADOでMDBにつないで200件ぐらいのデータの中から30件調度手に入れたいです。
今は検査中なので50件のデータから30件をやっているのですがかぶりまくりなので…。

なんか簡単なコードというか、テクニックのようなものがありましたら教えていただきたいです。
VBは初心者なのでよろしくお願いします…。


魔界の仮面弁士  2005-12-22 06:23:51  No: 129175

mdb に 約200件のデータがあり、そこから 30件抽出したい、という事ですよね。

特定の並び順に対する先頭30件でしょうか?
もしそうなら、SELECT 時に ORDER BY句と TOP句を指定すれば良いでしょう。

それとも、ランダムに(重複無しで)30件ですか? もしそうだとすれば、

  Set C = New Collection
  Do Until RS.EOF
    C.Add RS.Bookmark
    RS.MoveNext
  Loop

  For R = 1 To 30
    N = (最小値1、最大値C.Countな乱数)
    RS.Bookmark = C(N)
    {RSデータの取得}
    C.Remove N
  Next
  Set C = Nothing
  RS.Close

という感じでどうでしょう。


竜言語魔法  2005-12-22 07:19:53  No: 129176

えっと…。使用方法がいまいち分かりませぬ…。
本当に初心者で申し訳ないとは思うのですが…。

魔界の仮面弁士さんが2つ目に仰っているとおり
mdb に200件のデータ(ID, 名前, 子供1, 子供2)があり、
重複なしでIDをランダムに抽出したいのです…。

ほんっとうに申し訳ないとは思いますが、
再度解説の程よろしくお願いできませんでしょうか…。
お願いいたします…。


通ってみた  2005-12-22 10:34:40  No: 129177

カードのシャッフルと同じ方法で考えてみると、

Dim dt(199) As Long
Dim i As Long
Dim dammy As Long
Dim r1 As Long
Dim r2 As Long

For i = 0 to 199
    dt(i) = i
Next

For i=0 to 99
    r1 = Int(Rnd(1) * 200)
    r2 = Int(Rnd(1) * 200)
    dammy = dt(r1)
    dt(r1) = dt(r2)
    dt(r2) = dammy
Next

とかするといいのではないかと
これでdt(0)〜dt(29)に0〜199の数字がランダムに入るので、それを使ってみてください


通ってみた  2005-12-22 10:35:42  No: 129178

あ、最初にRandomizeで乱数を初期化してくださいね・・・


魔界の仮面弁士  2005-12-22 11:00:23  No: 129179

> mdb に200件のデータ(ID, 名前, 子供1, 子供2)があり、

'ブックマークの一覧を取得。
Dim C As Collection
Set C = New Collection
Do Until RS.EOF
  C.Add RS.Bookmark
  RS.MoveNext
Loop

'30件抽出
Randomize
Dim R As Integer, N As Integer
For R = 1 To 30
  N = Int(C.Count * Rnd() + 1)
  RS.Bookmark = C(N)  'ランダムに選んだ行に移動
  Debug.Print RS.Fields("ID").Value,
  Debug.Print RS.Fields("名前").Value,
  Debug.Print RS.Fields("子供1").Value,
  Debug.Print RS.Fields("子供2").Value
  C.Remove N  '一度選んだ行のブックマークは除去
Next
Set C = Nothing
RS.Close

==============

> 重複なしでIDをランダムに抽出したいのです…。
あれ? IDだけで、名前、子供1/2は不要なのですか。
であればもっと短く書けそう。

'IDの一覧を取得。
Dim C As Collection
Set C = New Collection
Do Until RS.EOF
  C.Add RS.Fields("ID").Value
  RS.MoveNext
Loop

'取得したID一覧が、30件になるまで削除を続ける
Randomize
Dim N As Integer
Do While C.Count > 30
  C.Remove Int(C.Count * Rnd() + 1)
Loop

'(確認用)
Dim ID As Variant
For Each ID In C
  Debug.Print ID
Next


竜言語魔法  2005-12-25 03:01:36  No: 129180

すいません・・・。遅れました。
魔界の仮面弁士さんの方法を取らせてもらいましたところ
「現在のRecordsetはブックマークをサポートしてない」
とでました。なぜだと思いつつ考えたところVB5だったようです。鬱…。
書き方が間違えてるのかアプリが逝ってるのかだと思いつつもかなりきついです。
書き方が間違えてるなら自分の挿入が糞なんですが…。

そしてカードシャッフル法の「通ってみた」さんの方法でやってみたところ
200件は固定ではないと駄目なご様子。配列のなかに最大値をSQLで参照して入れてみましたところ(レコードは増える&減る事があるので)
固定値じゃないと駄目ですよ!って言われたのでここの部分が解消できたら使えるかも…。

Webはやった事あるんですがVBはかなり痛いです。
助言をお願いします。
本当に申し訳ないです…。


通ってみた  2005-12-25 16:24:37  No: 129181

ReDimとUboundを使えばできると思います


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加