我运行一段程序的时候,数据量大就显得特别的慢,又不知道要等多久,有没有什么办法可以显示即时需要等待的时间?比如我要完成一个循环,这个循环完成需要多少时间,开始倒计时,就像我们复制文件倒计时那样
还有一个问题是,我一运行我的那个程序,如果还没算完,他就在任务管理器的应用程序一栏里显示未响应,直到它算完了才变成正在运行,请问这正常吗?会不会是我的程序写的不好才这样?

解决方案 »

  1.   

    用timer控件,根据计算的实际进度定时刷新进度条。
      

  2.   

    用timer 函数返回从午夜开始到现在的时间
    到循环计算结束的时候再用一次,两次的差就是了
      

  3.   

    循环里加Doevents
    例如:
    for i=0 to 1000000000
        x=x+1'假设为你的语句
         doevents'这句加哪无所谓,在你的循环里就行.
    next i
    这样就不会象死掉一样了.
         
      

  4.   

    Option ExplicitPrivate Sub Command1_Click()
        Dim i As Long
        Dim s As String
        Dim rStart As Single
        Dim rTimePass As Single
        Dim rTimeTotal As Single
        
        rStart = Timer()
        For i = 1 To 10000000
            s = CStr(i)
            
            '不必每个循环都刷新,只要每秒几十帧的频率即可'
            If (i Mod 50000) = 0 Then
                rTimePass = Timer() - rStart
                rTimeTotal = rTimePass * 10000000 / i
                Label1 = Format$(rTimeTotal - rTimePass, "0.000")
                DoEvents
            End If
        Next
    End Sub
      

  5.   

    Private Sub Command1_Click()
        Dim t1 As New clsTimeCount
        t1.Mark
        
        Dim i&
        For i = 0 To 100000
            DoEvents
        Next
        
        MsgBox t1.TimeCount
    End Sub
    clsTimeCount.cls
    Option ExplicitPrivate Declare Function GetTickCount Lib "kernel32" () As Long
    Private lngCurrent As LongProperty Get TimeCount() As Long
        TimeCount = GetTickCount() - lngCurrent
    End PropertyPublic Sub Mark()
        lngCurrent = GetTickCount()
    End Sub
      

  6.   

    Private Sub Pause(i As Date)
        t1 = DateAdd("s", i, Now)
        While t1 > Now
        DoEvents
        Wend
    End Sub如果要等10秒,那么代码就是
    Pause 10
      

  7.   

    给你写了个用进度条显示计算进度的例子,改编自MSDN。这个例子会实时显示计算进度,并处理在计算中用户二次点击计算按钮(Command1)可能带来的重复计算的问题。以下代码放在Form1模块里。记得在Form1上放一个进度条控件,并命名为prg1。Private Sub Form_Load()
        prg1.Visible = False
        prg1.Max = 100
    End SubPrivate Sub Command1_Click()
        ' Static variables are shared by all instances of a procedure.
        Static blnProcessing As Boolean
        Dim i As Long, lngCt As Long, dblDummy As Double    ' Show the ProgressBar control.
        prg1.Visible = True
        prg1.Value = 0
        
        ' When the button is clicked, test whether it's already processing.
        If blnProcessing Then
            ' If processing is in progress, cancel it.
            blnProcessing = False
        Else
            Command1.Caption = "Cancel"
            blnProcessing = True
        
            ' Perform a hundred million floating-point multiplications.
            ' After every thousand, update the progress bar and the commondbutton's caption.
            Do While blnProcessing And (lngCt < 100000000)
                For i = 1 To 1000
                   lngCt = lngCt + 1
                   dblDummy = lngCt * 3.14159
                Next i
                ' The DoEvents statement allows other events to occur, including pressing this
                ' button a second time.
                prg1.Value = lngCt / 1000000
                If prg1.Value = 100 Then prg1.Visible = False
                DoEvents
            Loop
            
            blnProcessing = False
            Command1.Caption = "Process"
            MsgBox lngCt & " multiplications were performed"
        End IfEnd Sub
      

  8.   

    你的问题其实分两部分。第一部分是显示倒计时的进度,这个简单,就是你自己设置一下每循环多少次(比如1000次),你就改一下进度条的value(像11楼的代码),或者改一下Label的Caption(像8楼的代码)。这个不需要DoEvents。第二部分时解决计算过程中不响应用户操作的问题。这个需要用DoEvents. 这个函数的作用就是在冗长的计算过程中把控制转给操作系统,让操作系统把其他需要处理的任务处理一番(包括你提到的任务管理器),然后再把控制转回给原过程的下一个语句。PS1 MSDN里的VB《部件工具指南》的“使用ActiveX 控件”那一章里讲ProgressBar里专门有一小节讲关于倒计时进度条的显示。可以看看。PS2 MSDN里的VB《程序员指南》的“第十一章 响应鼠标和键盘事件”里“中断后台处理”这一节就是专门讲你提到的这种问题,也可以看看。
      

  9.   

    总的来说,中断后台处理有两种方式,一种是用Timer、一种是用DoEvents。它们的实质都是把冗长的处理“打碎”分成小段,每次执行其中一小段,然后让其他任务执行。不同在于“打碎”的方式不同:用Timer的话,是相当于定时执行任务,有点计划任务的意思,好似长工隔一段时间就被“唤醒”起来干活;用DoEvents的话,相当于长工每隔一段时间就睡一会儿,把劳动工具和资源让给别人。达到的效果貌似却是一样的。注意,我这里说的Timer不是8楼那种用法,那是纯拿Timer当个计时工具了。