软件界面有text控件数组49个,即从text4(0 to 48)。要实现的功能就是用户输入一个值 user,然后软件根据一定的条件求出控件数组的总值sum,最后从i=1到控件数组中的最大值maxvalue开始循环,如果 i * 23 - sum + sum * 1.2 > user,则最后的值 result = i - 1。以上出现的问题是当用户输入大于百万的值后,软件不能马上算出结果。请问大家,有没有更好的算法使这段简单的循环语句执行得更快?以下是本段代码。因为是自学VB的初学者,很多代码的效率都不怎么高,很多地方还要学习,还请大家指点一二。谢谢!
For i = 0 To 47 '控件数组text4总共49个
   If Val(Form1.Text4(i).Text) >= Val(Form1.Text4(i + 1).Text) Then'这个if语句是求数组中的最大值maxvalue
      If Val(Form1.Text4(i).Text) > maxvalue Then
         maxvalue = Val(Form1.Text4(i).Text)
      End If
   Else
      If Val(Form1.Text4(i).Text) > maxvalue Then
         maxvalue = Val(Form1.Text4(i + 1).Text)
      End If
   End If
Next
For i = 1 To maxvalue'从1 到 最大值 循环
   sum = 0 
   For n = 0 To 48 '这个循环是用来统计在以下IF条件下的控件数组的总值
      DoEvents
      If i > Val(Form1.Text4(n).Text) Then'取总值的条件
         sum  = sum  + Val(Form1.Text4(n).Text) 
      Else
         sum  = sum  + i
      End If
   Next
   If i * 23 - sum+ sum * 1.2 > user Then '如果循环到这里的值大于用户输入的数,则结果取 result=i-1
      result = i - 1
      Exit For
   End If
Next

解决方案 »

  1.   

    老实说,我没仔细看你的代码。
    textbox50个,换个想法,用什么editable grid么?
      

  2.   

    优化方案:1. 不要反复 读取/设置 对象属性。
      建议声明一个 Double 类型的数组,其下标与 text4 的下标分别对应,先用一个循环一次性读取完控件对象的属性值到数组内,后面访问数组。  其实更好的是:Form_Load() 时把 text4 的值读取到数组内,运行时在 text4 的 Change() 事件中更新对应的数组元素。
    2. i * 23 - sum + sum * 1.2 应该改为:
      i * 23 + sum * 0.2
      

  3.   

    先不讨论代码逻辑,先看看代码中大量的对象属性的调用,这是比较费时间的。其实你可以在程序的最前面定义一个数组,把控件数组全部转换为数值
    dim aryVal(0 to 48) as long 
    For i = 0 To 48
      aryVal(i) = Val(Form1.Text4(i).Text)
    next 接下来代码中所有 Val(Form1.Text4(i).Text) 全部 替换成 aryVal(i)。多少会快一点。
      

  4.   

    接下来我们看看你的逻辑
    第一个循环懒得看了,就算写法效率不高,总共也就几十次循环影响不大。
    关键在第二个循环。 maxvalue如果大了循环是很恐怖的一件事情。但是你在每一次循环中只是和那49个值发生关系,那么这个从1~maxvalue的循环是否每次都是必要的?
    举一个例子 如果maxvalue= 100 其中一个Form1.Text4(0).Text = 5
    那么按照目前的逻辑要循环100次, 但是 i=1~5的时候i > Val(Form1.Text4(0).Text)是不会成立的 因此注定走sum  = sum  + i 的 分支,i= 6~100的时候 i > Val(Form1.Text4(0).Text) 因此 一共有 95次的Val(Form1.Text4(0).Text)的累加 也就是说 100次循环后 和 Text4(0)相关的循环对sum的贡献为
    1+2+3+4+5+95*5 。前面的那一串加号用等差数列公式替换 (1+5)*5/2 + 95*5用我上帖中的建议,所有Val(Form1.Text4(i).Text)的转换成aryValue(i)
    那么sum的最终计算结果中 text4(i)所贡献的数值就是
    (1+aryValue(i)) * aryValue(i)/2 + (maxvalue-aryvalue(i)) * aryvalue(i)
    把i从 0~48循环一次就可以很快的算出sum值了。
      

  5.   

    另外根据你的文字描述需要先算出sum值 然后再循环做i * 23 - sum + sum * 1.2 > user的判断。但是从你的代码中貌似不是这样,确认你的代码的计算结果是正确的吗?
      

  6.   

        For i = 0 To 48 '既然是49个,序号应该是0-48
            If Val(Form1.Text4(i).Text) > maxvalue Then
               maxvalue = Val(Form1.Text4(i).Text)
            End If
        Next
        For i = 1 To maxvalue '耗时主要取决于这个maxvalue的值,与后面输入的user无关
           Sum = 0
           DoEvents
           For n = 0 To 48
              If i > Val(Form1.Text4(n).Text) Then
                 Sum = Sum + Val(Form1.Text4(n).Text)
              Else
                 Sum = Sum + i
              End If
           Next
           If i * 23 - Sum + Sum * 1.2 > user Then
              result = i - 1
              Exit For
           End If
        Next