本帖最后由 xiepengyu 于 2012-01-17 02:07:41 编辑

解决方案 »

  1.   

    Do
        num = Int(660 * Rnd + 1)
        num4 = num
        num1 = num4 Mod 10  '个位
        num4 = Int(num4 / 10)
        num2 = num4 Mod 10  '十位
        num4 = Int(num4 / 10)
        num3 = num4 Mod 10  '百位
      Loop While tempnum(num) = 1'查看tempnum(num)是否永远不会等于1,tempnum的定义是否以0下标为第一个元素。
      

  2.   

    看了,抽中num一次tempnum(num)置1,tempnum的定义以0下标为第一个元素。
      

  3.   

      虽然俺是VB6初学者,但多少俺有asp的编程经验……
      个人感觉,整个程序就一个字:乱!什么都乱,算法思路乱,变量乱,代码排版乱,代码使用习惯乱。呵呵。
      建议楼主养成条理的编程习惯。  提个想法,没测试,就是:
      既然楼主使用 Timer 计时器控件,当成随机抽奖的“循环”过程来使用,那么 Timer 里面的Do Loop又有什么意义呢???
      总之感觉程序乱透了。感觉整个程序要重新来过。
      

  4.   

    里面的Do Loop是防止抽出的数字重复
      

  5.   

       偶明白了。原来所谓tempnum(num) = 1 就是个标志,表示已经抽中……晕,循环体似乎根本不起作用!看来程序要重新编写!你用循环的办法抽奖,实在效率奇低无比!而且很可能就是死循环。抽一次就得了嘛,为什么要循环呢?超级低效的算法。  给你个思路:
    一、dim temp(1 to 660),然后各元素顺序赋值为1至660
    二、做个循环体(或者干脆就让timer做循环过程,但注意要声明窗体级变量i,tempnum,变量数组temp数组什么的。)
    三、循环体。(可能把timer当循环体吧,自己看着办)
    第i次抽取,为tempNum = i + int(rnd()*660 + 1 - i),然后把temp(tempNum)与temp(i)交换。  循环体内的数据交换,保证了抽取的数字不会重复,一次完成。比你用循环,再比较是否已经抽过,那种算法真是糟糕透顶了。  以上只是算法上的考虑。界面设计就由自己发挥了。肯定的。
      

  6.   

    问题可能就是出在10楼所说的比较是否已经抽过的算法上,使得到抽奖数量已经很多(要抽100多名)的时候频繁比较是否抽出过,然后再生成随机数。但是我看不懂:第i次抽取,为tempNum = i + int(rnd()*660 + 1 - i),然后把temp(tempNum)与temp(i)交换。希望指点!
      

  7.   

    其实:第i次抽取,为tempNum = i + int(rnd()*660 + 1 - i),然后把temp(tempNum)与temp(i)交换。
    不能保证已经抽出的数字再次被抽中呢!比如:
    i=1 rnd=0.1  tempNum=67;tempNum=67和temp[1]即1交换
    i=2 rnd=0.1  tempNum=67;tempNum=67和temp[2]即2交换这样67被抽中两次了。
      

  8.   


    .....
    界面闪动什么滴,你不会是真得用程序跟踪每个随机数然后再"画"出来吧??
    给你个简单方法: 自己做十个GIF(动画也行),从快到慢滚动的数字, 每个GIF最后停下来的数字对应0到9. 然后你抽中那个数字就放哪个GIF, 反正无论是几位数都是一位一位抽的,所以三位数就放三个动画,两位数就放两个动画.像这种真正的内部抽取数字才是核心的计算,往往只占很少的代码量.速度也很快. 花力气的都是些个人机交互的东西.
      

  9.   

    cpu100%的问题解决了,多谢noah_ma。但是另一个问题来了:vb的label只能容纳下几十个数字,后面的数字显示不了了,难道是label能显示的字节是很少的吗?应该怎么扩大label显示的字节数呢?
      

  10.   

    noah_ma你好,用你的算法在每次抽出一名中奖号码的时候没有问题,但是结合timer一次产生10名中奖号码的时候就有问题了!
      

  11.   

    你的CPU占用100%的原因是前半段多了个:
    tempnum(num) = 1这样‘闪烁’一会儿,就全部标志成1了,你的前半段就成了死循环。
    这样就会把CPU占用100%了。
    另外,你的后半段‘连续抽10’的代码,我觉得也没什么问题。
    我添加必要的代码模仿随机抽奖,运行起来没觉得任何异常。但你应注意的是Next后面,据说不能跟变量名……
    (你用注释标明是哪个变量的Next不就行了?)
      

  12.   

      程序俺写好了。不是俺好心,真是因为俺是新手,也想练练手!!!哈哈。这个程序当前不通用。改成通用的话哪,似乎也不是很难。算啦,就这样了。
      
      另外,俺认为,14楼的说法,并不实用。俺还真的是用电脑,把真实要抽的数字给随机显示了,不是“弄个假样子”。为什么这样呢?设想个情形:
      年终啦,要发奖,领导发给员工的号,是1至660。结果,你百位上老是在闪动“7、8、9”这些个数字,实在不怎么好看……呵呵。
      还有啊,就是,
      俺的这个程序啊,稍微一改造(对应个数据库什么的),就成了“课堂随机提问”之类,到时候,闪动的,不是数字,而是名字!!!名字呀。  呵呵,不啰嗦了,代码如下:界面:label1,label2,text1,command1,timer1代码:Dim temp(1 To 10) As Integer      '抽10次好验证,您再另外改吧。呵呵。俺慵懒中……
    Dim tempNum As Integer
    Dim theOrder As IntegerPrivate Sub Form_Load()
      Timer1.Enabled = False
      Timer1.Interval = 10
      theOrder = 1
      Label1.Caption = "您马上要抽取的是顺序号是:"
      Label2.Caption = "1"
      Command1.Caption = "抽奖啦!"
      For i = 1 To 10                 '只抽10次
        temp(i) = i
      Next i
    End Sub
    '这个按钮要按两次,第一次,开抽,激活Timer;第二次,定奖,关闭Timer
    Private Sub Command1_Click()
      Dim a As Integer
      If theOrder > 10 Then          '若超过10次
        Text1.Text = "抽完啦!"
        Exit Sub
      End If
      
      If Timer1.Enabled = False Then  '若未抽状态,则开抽,进入timer循环体
        Timer1.Enabled = True
      Else               '否则,停止timer计时器,得到结果,并开始交换处理。
        Timer1.Enabled = False
        a = temp(theOrder)
        Debug.Print tempNum
        temp(theOrder) = temp(tempNum)
        temp(tempNum) = a
        theOrder = theOrder + 1
        Label2.Caption = Str(theOrder)  End If  
    End SubPrivate Sub Timer1_Timer()
      Randomize
      tempNum = theOrder + Int(Rnd() * (10 + 1 - theOrder)) '乘数有讲究,上帖俺少了括号。
      Text1.Text = temp(tempNum)
    End Sub
    此程序俺已成功实验过。俺也新手,也希望得到楼主以后的照顾。谢谢。
      

  13.   

    发完,发现代码那么难看啊……还不让编辑!!!再发一次试试:  程序俺写好了。不是俺好心,真是因为俺是新手,也想练练手!!!哈哈。这个程序当前不通用。改成通用的话哪,似乎也不是很难。算啦,就这样了。
      
      另外,俺认为,14楼的说法,并不实用。俺还真的是用电脑,把真实要抽的数字给随机显示了,不是“弄个假样子”。为什么这样呢?设想个情形:
      年终啦,要发奖,领导发给员工的号,是1至660。结果,你百位上老是在闪动“7、8、9”这些个数字,实在不怎么好看……呵呵。
      还有啊,就是,
      俺的这个程序啊,稍微一改造(对应个数据库什么的),就成了“课堂随机提问”之类,到时候,闪动的,不是数字,而是名字!!!名字呀。  呵呵,不啰嗦了,代码如下:界面:label1,label2,text1,command1,timer1代码:Dim temp(1 To 10) As Integer      '抽10次好验证,您再另外改吧。呵呵。俺慵懒中……
    Dim tempNum As Integer
    Dim theOrder As IntegerPrivate Sub Form_Load()
      Timer1.Enabled = False
      Timer1.Interval = 10
      theOrder = 1
      Label1.Caption = "您马上要抽取的是顺序号是:"
      Label2.Caption = "1"
      Command1.Caption = "抽奖啦!"
      For i = 1 To 10                 '只抽10次
        temp(i) = i
      Next i
    End Sub
    '这个按钮要按两次,第一次,开抽,激活Timer;第二次,定奖,关闭Timer
    Private Sub Command1_Click()
      Dim a As Integer
      If theOrder > 10 Then          '若超过10次
        Text1.Text = "抽完啦!"
        Exit Sub
      End If
      
      If Timer1.Enabled = False Then  '若未抽状态,则开抽,进入timer循环体
        Timer1.Enabled = True
      Else               '否则,停止timer计时器,得到结果,并开始交换处理。
        Timer1.Enabled = False
        a = temp(theOrder)
        Debug.Print tempNum
        temp(theOrder) = temp(tempNum)
        temp(tempNum) = a
        theOrder = theOrder + 1
        Label2.Caption = Str(theOrder)  End If  
    End SubPrivate Sub Timer1_Timer()
      Randomize
      tempNum = theOrder + Int(Rnd() * (10 + 1 - theOrder)) '乘数有讲究,上帖俺少了括号。
      Text1.Text = temp(tempNum)
    End Sub
    此程序俺已成功实验过。俺也新手,也希望得到楼主以后的照顾。谢谢。
      

  14.   

    试试这个吧,可能是你想要的。
    需要把Text1文本框拉得大一些,字体可以设置得大一些。要使它的尺寸能容纳下10行。
    然后将Text1.MultiLine设置为True,否则无法显示多行。
    需要三个按钮Command1、Command2、Command3,还有一个Timer1控件。
    使用方法是:先点“开始”按钮,然后你点“抓取”,直到抓够10个。最后点“停止”。
    Private priNumList() As Long
    Private priNumList_Index As Long
    Private priOutList() As StringPrivate Sub Form_Load()
      '需要设置Text1.MultiLine = True
      Timer1.Enabled = False
      Dim tNumCount As Long
      Dim tOutCount As Long
      tNumCount = 660 '可以把这个数字设置成10来测试它是否准确。
      tOutCount = 10
      ReDim priNumList(tNumCount - 1)
      ReDim priOutList(tOutCount - 1)
      
      For tIndex = 0 To tNumCount - 1
        priNumList(tIndex) = tIndex
      Next
      
      Command1.Caption = "开始"
      Command2.Caption = "停止"
      Command3.Caption = "抓取"
      Timer1.Interval = 10
    End SubPrivate Sub Command1_Click()
      '开始
      Timer1.Enabled = True
      Command1.Enabled = False
      Command2.Enabled = True
      Command3.Enabled = True
    End SubPrivate Sub Command2_Click()
      '停止
      Timer1.Enabled = False
      Command1.Enabled = True
      Command2.Enabled = False
      Command3.Enabled = False
    End SubPrivate Sub Command3_Click()
      '抓取
      Timer1.Enabled = False
      priNumList_Index = priNumList_Index + ((priNumList_Index < 9) And 1)
      Timer1.Enabled = True
    End SubPrivate Sub ListSwap(ByRef pList() As Long, ByRef pIndex As Long)
      '将pIndex指定的元素与后面的随机元素交换。
      Dim tDesIndex As Long
      tDesIndex = Int(Rnd * (UBound(pList()) - pIndex)) + pIndex
      ValueSwap pList(pIndex), pList(tDesIndex)
    End SubPrivate Sub ValueSwap(ByRef pA As Long, ByRef pB As Long)
      '交换两个Long的值。
      Dim tT As Long
      tT = pA: pA = pB: pB = tT
    End SubPrivate Sub Timer1_Timer()
      ListSwap priNumList(), priNumList_Index
      priOutList(priNumList_Index) = Format(priNumList_Index + 1, "00") & " " & Format(priNumList(priNumList_Index), "000")
      Text1.Text = Join(priOutList, vbCrLf)
    End Sub
      

  15.   

    如果你想让10个数字同时滚动,一次抓成,也可以。但没有上面这个办法好玩。
    你可以让老总或者经理之类的嘉宾点“抓取”。但最后一个要按“停止”。
    (如果你觉得最后一个按“停止”不好用,把priOutCount=10改成11就可以了。最后那个不算。)
      

  16.   

      哟哎,楼上小仙妹……你怎么不早出现!您的代码跟俺的算法,竟然如出一辙……早知道有您的代码,俺就不用那么用功练手啦……呵呵。    对比结果:俺的代码呢,按钮只有一个,比较简洁;22楼代码,用文本框的连接,实现了抓奖结果的记忆。俺觉得,可以相互借鉴改进得更好!  另外,俺想跟楼主一块谈谈体会(都新手嘛,说得不好,也不怕别人笑话)。相信楼主看了俺的代码跟22楼提供的代码,对 Timer 作为循环体,一定会有更加深刻的理解。  一、Timer本身作为循环体,内部千万不要嵌入复杂的循环!否则timer的时间间隔到了,循环还未结束……很可能会出现严重的意外现象。
      二、这是个特殊的循环体,特殊就特殊在,人家的循环,以计算出结果为停止条件,而timer却是固定时间间隔,至于你运算到哪儿,管你!……
      所以,个人感觉,使用Timer呢,是个学问。    感谢楼主,跟各位跟贴都给俺的启发。谢谢啦。
      

  17.   

    这是10个一起抓的代码。
    需要一个Command1按钮、一个Timer1控件、一个Text1文本框。
    Text1.MultiLine需要设置为True。
    Option ExplicitPrivate priNumList() As Long
    Private priOutList() As StringPrivate Sub Form_Load()
      '需要设置Text1.MultiLine = True
      Timer1.Enabled = False
      Dim tIndex As Long
      Dim tNumCount As Long
      Dim tOutCount As Long
      tNumCount = 660 '可以把这个数字设置成10来测试它是否准确。
      tOutCount = 10
      ReDim priNumList(tNumCount - 1)
      ReDim priOutList(tOutCount - 1)
      
      For tIndex = 0 To tNumCount - 1
        priNumList(tIndex) = tIndex
      Next
      
      Command1.Caption = "开始"
      Timer1.Interval = 10
    End SubPrivate Sub Command1_Click()
      '开始
      Timer1.Enabled = Not Timer1.Enabled
      Command1.Caption = Split("开始,停止", ",")(Timer1.Enabled And 1)
    End SubPrivate Sub ListSwap(ByRef pList() As Long, ByRef pIndex As Long)
      '将pIndex指定的元素与后面的随机元素交换。
      Dim tDesIndex As Long
      tDesIndex = Int(Rnd * (UBound(pList()) - pIndex)) + pIndex
      ValueSwap pList(pIndex), pList(tDesIndex)
    End SubPrivate Sub ValueSwap(ByRef pA As Long, ByRef pB As Long)
      '交换两个Long的值。
      Dim tT As Long
      tT = pA: pA = pB: pB = tT
    End SubPrivate Sub Timer1_Timer()
      Dim tIndex As Long
      For tIndex = 0 To 9
        ListSwap priNumList(), tIndex
        priOutList(tIndex) = Format(tIndex + 1, "00") & " " & Format(priNumList(tIndex), "000")
      Next
      Text1.Text = Join(priOutList, vbCrLf)
    End Sub
      

  18.   

    这个是网页版的。
    <html><head>
    <meta http-equiv="Content-Language" content="zh-cn">
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>抓奖</title>
    </head><body><p><a href="#" id="idButton">开始</a></p>
    <p id="idOutText">列表</p></body>
    <script language="VBScript">
      Dim priNumList()
      Dim priOutList()
      Dim priWorking
      Dim priTimer    tNumCount = 660
      tOutCount = 10
      ReDim priNumList(tNumCount - 1)
      ReDim priOutList(tOutCount - 1)
      
      For tIndex = 0 To tNumCount - 1
        priNumList(tIndex) = tIndex
      Next
      
      idButton.innerText = "开始"
      priWorking = False  Sub idButton_onClick()
        priWorking = Not priWorking
        idButton.innerText = Split("开始,停止", ",")(priWorking And 1)
        If priWorking Then Web_TimeLoop
      End Sub  Sub ListSwap(pList(), pIndex)
        tDesIndex = Int(Rnd * (UBound(pList) - pIndex)) + pIndex
        ValueSwap pList(pIndex), pList(tDesIndex)
      End Sub  Sub ValueSwap(pA, pB)
        tT = pA: pA = pB: pB = tT
      End Sub  Sub Web_TimeLoop()
        For tIndex = 0 To 9
          ListSwap priNumList, tIndex
          priOutList(tIndex) = tIndex + 1 & " " & priNumList(tIndex)
        Next
        idOutText.innerText = Join(priOutList, vbCrLf)
        If priWorking Then priTimer = window.setTimeout("Web_TimeLoop", 10)
      End Sub
    </script>
    </html>
      

  19.   

    好多年没看到这么热闹的帖子了,不容易啊!让人很是怀念当年的csdn,当年的vb...