Foxtable(狐表)用户栏目专家坐堂 → [求助] 这段代码运行时间太长了 足足3秒,怎么减少!


  共有10887人关注过本帖树形打印复制链接

主题:[求助] 这段代码运行时间太长了 足足3秒,怎么减少!

帅哥哟,离线,有人找我吗?
gaoyong30000
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:五尾狐 帖子:1165 积分:9032 威望:0 精华:1 注册:2011/5/25 16:33:00
[求助] 这段代码运行时间太长了 足足3秒,怎么减少!  发帖心情 Post By:2011/9/27 22:16:00 [只看该作者]

For Each r As Row In Tables("销售意向客户进度管制")
    If r.Isnull("客户名称") =True Then
        MessageBox.Show("客户名称未填写", "提示", MessageBoxButtons.ok, MessageBoxIcon.Information)
        Return
        Exit For
    End If
    If r.Isnull("意向级别") =True Then
        MessageBox.Show("意向级别未填写", "提示", MessageBoxButtons.ok, MessageBoxIcon.Information)
        Return
        Exit For
    End If
    If r.Isnull("建档日期") =True Then
        MessageBox.Show("建档日期未填写", "提示", MessageBoxButtons.ok, MessageBoxIcon.Information)
        Return
        Exit For
    End If
    If r.Isnull("最后联系日期") =True Then
        MessageBox.Show("最后联系日期未填写", "提示", MessageBoxButtons.ok, MessageBoxIcon.Information)
        Return
        Exit For
    End If
    If r.Isnull("最后一次回访情况") =True Then
        MessageBox.Show("最后一次回访情况未填写", "提示", MessageBoxButtons.ok, MessageBoxIcon.Information)
        Return
        Exit For
    End If

    For Each cl As Row In Tables("销售意向客户进度管制")
        If user.group = "销售部"
            If cl("业务员申请")= "驳回 修改申请" Or cl("业务员申请")= "驳回 删除申请" Or cl("业务员申请")= "驳回 战败申请" Or cl("业务员申请")= "驳回 战胜申请" Or cl("业务员申请")= "驳回 修改申请" Or cl("业务员申请")= "批准修改" Or cl("业务员申请")= "批准删除" Or cl("业务员申请")= "批准战胜" Or cl("业务员申请")= "批准战败"  Then
                cl("业务员申请")  =""
            End If
        End If
    Next
    
    If user.group <> "客服部" Then
        Dim f As New Filler
        f.SourceTable = DataTables("销售意向客户进度管制") '指定数据来源
        f.SourceCols = "编号,意向级别,最后联系日期,最后一次回访情况,备注" '指定数据来源列
        f.DataTable = DataTables("意向客户历史回访情况") '指定数据接收表
        f.DataCols = "编号,意向级别,最后联系日期,最后一次回访情况,备注" '指定数据接收列
        f.ExcludeExistValue =True
        f.ExcludeNullValue =False
        f.Distinct =True
        f.Append =True
        f.Fill()
    End If
    
    If user.group <> "客服部" Then
        DataTables("销售意向客户进度管制") .DeleteFor("[客户名称] Is Null and [联系地址] Is Null and [联系号码] Is Null And [欲购车型] Is Null and [意向级别] Is Null and [建档日期] Is Null and [最后联系日期] Is Null and [下次回访日期] Is Null and [最后一次回访情况] Is Null and [备注] Is Null and [客户来源] Is Null and [业务员申请] Is Null")
    End If
    
    If user.group <> "客服部" Then
        For Each dt As DataTable In DataTables
            For Each cl As Row In Tables("销售意向客户进度管制")
                If user.name <> "销售经理" AndAlso user.name <> "开发者"
                    cl("客户资料锁定") = True
                End If
            Next
            dt.save()
        Next
    End If
Next

怎么精简这段代码  我估计 是for each 运用太多导致
[此贴子已经被作者于2011-9-27 22:16:27编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
mr725
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:MVP荣誉狐 帖子:5154 积分:31434 威望:0 精华:8 注册:2008/9/8 12:27:00
  发帖心情 Post By:2011/9/27 22:20:00 [只看该作者]

所有表都保存一遍当然用时会长些哦···

 回到顶部
帅哥哟,离线,有人找我吗?
gaoyong30000
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:五尾狐 帖子:1165 积分:9032 威望:0 精华:1 注册:2011/5/25 16:33:00
  发帖心情 Post By:2011/9/28 0:31:00 [只看该作者]

就这个原因嘛?


 回到顶部
帅哥哟,离线,有人找我吗?
程兴刚
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:超级版主 帖子:7235 积分:40574 威望:0 精华:16 注册:2008/8/31 23:23:00
  发帖心情 Post By:2011/9/28 4:35:00 [只看该作者]

If user.group <> "客服部" Then
    DataTables("销售意向客户进度管制") .DeleteFor("[客户名称] Is Null and [联系地址] Is Null and [联系号码] Is Null And [欲购车型] Is Null and [意向级别] Is Null and [建档日期] Is Null and [最后联系日期] Is Null and [下次回访日期] Is Null and [最后一次回访情况] Is Null and [备注] Is Null and [客户来源] Is Null and [业务员申请] Is Null")
End If
For Each r As Row In Tables("销售意向客户进度管制")
    For Each cl As col In Tables("销售意向客户进度管制").Cols
        If "客户名称|意向级别|建档日期|最后联系日期|最后一次回访情况".IndexOf(cl.name) > -1
            If r.Isnull(cl.name) =True Then
                MessageBox.Show(cl.name & "未填写", "提示", MessageBoxButtons.ok, MessageBoxIcon.Information)
                Return
                Exit For
            End If
        End If
    Next
    If user.group = "销售部"
        If r("业务员申请")= "驳回 修改申请" Or r("业务员申请")= "驳回 删除申请" Or r("业务员申请")= "驳回 战败申请" Or r("业务员申请")= "驳回 战胜申请" Or r("业务员申请")= "驳回 修改申请" Or r("业务员申请")= "批准修改" Or r("业务员申请")= "批准删除" Or r("业务员申请")= "批准战胜" Or r("业务员申请")= "批准战败"  Then
            r("业务员申请")  =""
        End If
    End If
Next
If user.group <> "客服部" Then
    Dim f As New Filler
    f.SourceTable = DataTables("销售意向客户进度管制") '指定数据来源
    f.SourceCols = "编号,意向级别,最后联系日期,最后一次回访情况,备注" '指定数据来源列
    f.DataTable = DataTables("意向客户历史回访情况") '指定数据接收表
    f.DataCols = "编号,意向级别,最后联系日期,最后一次回访情况,备注" '指定数据接收列
    f.ExcludeExistValue =True
    f.ExcludeNullValue =False
    f.Distinct =True
    f.Append =True
    f.Fill()
    If user.name <> "销售经理" AndAlso user.name <> "开发者"
        For Each r As Row In Tables("销售意向客户进度管制")
            r("客户资料锁定") = True
        Next
    End If
End If
DataTables("销售意向客户进度管制").Save()

DataTables("意向客户历史回访情况").Save()

[此贴子已经被作者于2011-9-28 4:41:18编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
gaoyong30000
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:五尾狐 帖子:1165 积分:9032 威望:0 精华:1 注册:2011/5/25 16:33:00
  发帖心情 Post By:2011/9/28 8:47:00 [只看该作者]

多谢 程版  好多了!  但是我想知道 究竟是哪里的问题导致执行时间长?

以前记得 有个可以调试代码执行时间的  一句代码  找不到了!

 回到顶部
帅哥哟,离线,有人找我吗?
smileboy
  6楼 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 好心情 一级勋章
等级:超级版主 帖子:715 积分:5564 威望:0 精华:1 注册:2008/8/31 20:45:00
  发帖心情 Post By:2011/9/28 11:01:00 [只看该作者]

 

计算代码执行耗时

在编程的过程中,为了优化代码,提高效率,有时需要知道执行某段代码所耗费的时间

可以参考下面的结构,自动显示某段代码所耗费的时间

Dim st As Date = Date.Now
'要测试耗时的代码
MessageBox.Show("耗时: " & (Date.Now - st).TotalSeconds & "秒")

例如:

Dim st As Date = Date.Now '将开始时间保存在变量st中
Dim
nms As List(of String) = DataTables("表A").GetUniqueValues("","客户")
DataTables(
"表B").StopRedraw()
For Each
nm As String In nms
    Dim
dr As DataRow = DataTables("表B").AddNew()
    dr
("客户") =
nm
   
dr("付款合计") = DataTables("表A").Compute("Sum(金额)", "客户 = '" & nm & "' And tk = 1")
    dr
("欠款合计") = DataTables("表A").Compute("Sum(金额)", "客户 = '" & nm & "' And tk = 0"
)
Next
DataTables(
"表B").ResumeRedraw()
MessageBox.Show(
"耗时: " & (Date.Now - st).TotalSeconds & "秒") '计算并显示执行代码所花费的秒数


 回到顶部
帅哥哟,离线,有人找我吗?
程兴刚
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 一级勋章
等级:超级版主 帖子:7235 积分:40574 威望:0 精华:16 注册:2008/8/31 23:23:00
  发帖心情 Post By:2011/9/28 11:23:00 [只看该作者]

1、既然要删除空行,就应该放在最前面,可以让后面的循环语句少循环N次(N等于其后的循环语句个数乘以删除的空行数)也就是这一段放到最前面:

     If user.group <> "客服部" Then

DataTables("销售意向客户进度管制") .DeleteFor("[客户名称] Is Null and [联系地址] Is Null and [联系号码] Is Null And [欲购车型] Is Null and [意向级别] Is Null and [建档日期] Is Null and [最后联系日期] Is Null and [下次回访日期] Is Null and [最后一次回访情况] Is Null and [备注] Is Null and [客户来源] Is Null and [业务员申请] Is Null")
End If

这样的话,For Each r As Row In Tables("销售意向客户进度管制")……next就要少运行N次,n 等于删除的空行数,还有后面的遍历循环语句也跟着减少。

2、相同的循环语句可以合并,这样可以少循环N次(N等于该表的总行数):

    您原来的For Each r As Row In Tables("销售意向客户进度管制") ……next 和For Each cl As Row In Tables("销售意向客户进度管制")其实遍历的都是一个表【销售意向客户进度管制】的所有行,只需将上述两个循环语句内的代码合并到一起即可。

3、除非万不得已,循环语句中的判断尽可能嵌套在在循环语句外:

     当判断条件不成立时,无需循环,而放在循环内,不管是否成立,先循环(遍历)再判断,导致很多时候(条件不成立时),出现N(N等于遍历的总行数)次循环来浪费时间,看这里:

For Each cl As Row In Tables("销售意向客户进度管制")
    If user.name <> "销售经理" AndAlso user.name <> "开发者"
        cl("客户资料锁定") = True
    End If
Next
改成这样:
If user.name <> "销售经理" AndAlso user.name <> "开发者"
    For Each cl As Row In Tables("销售意向客户进度管制")
        cl("客户资料锁定") = True
    Next
End If

调整后,非销售经理或非开发者进入系统时,就无需遍历所有行了,您这种代码的写法应该是犯了循环语句的大忌

4、不必要的循环嵌套,导致系统重复执行某一个相同的动作,多浪费很多时间:

看您的这一段代码:

For Each dt As DataTable In DataTables

    For Each cl As Row In Tables("销售意向客户进度管制")
        If user.name <> "销售经理" AndAlso user.name <> "开发者"
            cl("客户资料锁定") = True
        End If
    Next
    dt.save()
Next

您的第一层遍历所有表的目的,是想对所有表进行保存,而您又将遍历【销售意向客户进度管制】表的所有行的循环语句嵌套到其中,这就导致每遍历一个表,就要遍历【销售意向客户进度管制】表的所有行并判断修改【改客户资料锁定】列的值,这样又多循环了N遍(N等于总表数减1后乘以【销售意向客户进度管制】的总行数,象这种代码,如果确实需要保存所有表,也应该将这两层循环嵌套剥离,正确写法也应该这样:

If user.name <> "销售经理" AndAlso user.name <> "开发者"
    For Each cl As Row In Tables("销售意向客户进度管制")
        cl("客户资料锁定") = True
    Next
    For Each dt As DataTable In DataTables
        dt.save()
    Next
End If
这时候需要注意一下两个循环的先后顺序即可。
5、仅仅修改个别表(或者将来遇到行的类似问题),不必要全部表都要保存,况且保存本来就是比较费时的:
您的这段代码中,可以看出,总共只修改了【销售意向客户进度管制】和经过fill后的数据接收表【意向客户历史回访情况】,那么您无需遍历所有表并保存,这样,少执行N次保存表的代码(N等于总表数减2)正确应该这样即可:
If user.group <> "客服部" Then
    DataTables("销售意向客户进度管制").Save()

    DataTables("意向客户历史回访情况").Save()

end if

分析到这里,发现我在4楼给的代码最后少了一个判断,昨晚看漏了,无文件也没有测试,等于是丢失了对【客服部】的权限限制,抱歉,自己加上吧。

6、针对您的第一个循环语句For Each r As Row In Tables("销售意向客户进度管制")……next的修改,仅仅是优化了代码,对速度没有什么优化或影响
      【注】:通过对您的代码的全部剖析,不难看出第1~5点都是影响进度的地方,尤其3、4、5点尤为严重,上述N个N的总和相信您自己都能算出来,呵呵!
[此贴子已经被作者于2011-9-28 19:01:20编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
gaoyong30000
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:五尾狐 帖子:1165 积分:9032 威望:0 精华:1 注册:2011/5/25 16:33:00
  发帖心情 Post By:2011/9/28 13:12:00 [只看该作者]

多谢各位了

程版分析得非常详细啊 简直是一个指南!!图片点击可在新窗口打开查看图片点击可在新窗口打开查看图片点击可在新窗口打开查看

我得好好去消化消化去~~~~~

 回到顶部