Foxtable(狐表)用户栏目专家坐堂 → 请教实现方案


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

主题:请教实现方案

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


加好友 发短信
等级:三尾狐 帖子:688 积分:4903 威望:0 精华:0 注册:2013/10/27 17:14:00
  发帖心情 Post By:2014/5/8 23:06:00 [只看该作者]

谢谢 这错误 犯得太低级了

 

 


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


加好友 发短信
等级:三尾狐 帖子:688 积分:4903 威望:0 精华:0 注册:2013/10/27 17:14:00
  发帖心情 Post By:2014/5/8 23:12:00 [只看该作者]

 

数据源   结果     序    有效序   合格数量

M197   合格      1         1        3
M197   合格      2         1        3
M197   合格      3         1        3
M197   不合格   4         2        2
M197    合格     5         2        2
M197    合格     6         2        2

现在数据变成上面这个样子 黑色部份

现在按 数据源 及有效序两列数据对 结果列的合格数量进行统计,统计结果写入 合格数量列

 

数据源 + 有效序组合 每组合均为3 条数据

[此贴子已经被作者于2014-5-8 23:12:47编辑过]

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


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2014/5/9 10:22:00 [只看该作者]

 回复32楼,简单做法,你循环所有的行,按条件统计一下合格数量就行。


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


加好友 发短信
等级:三尾狐 帖子:688 积分:4903 威望:0 精华:0 注册:2013/10/27 17:14:00
  发帖心情 Post By:2014/5/13 23:17:00 [只看该作者]

代码优化问题:

 

Dim Arys As List(Of String())
Arys = DataTables("试验临时数据").GetValues("来源|有效序") '列名用符号|分割
'注意循环变量是字符型数组,所以类型是String(),而不是String
For Each Ary As String() In Arys
    'Output.Show(Ary(0) & "|" & Ary(1))
    Dim cnt As Integer
    Dim ly As String
    Dim yx As Integer
    ly = Ary(0)
    yx = Ary(1)
    cnt = DataTables("试验临时数据").Compute("Count([编号])", "[来源] = '" & ly & "' And [有效序] = '" & yx & "'  And 结果 = '合格'")
    'Output.Show(Ary(0) & "|" & Ary(1) & "|" & cnt)
    Dim drs As List(Of DataRow)
    drs = DataTables("试验临时数据").Select("[来源] = '" & ly & "' And [有效序] = '" & yx & "'")
    For Each dr As DataRow In drs
        dr("合格数量") = cnt
    Next
Next

 

本段代码相当耗费时间 执行需要27秒(处理4000多条数据)

 

经查帮助:

是因为以下原因。

现在我总结一下,符合以下三个条件,会出现效率低下的情况:

1、用For语句遍历某个表。
2、遍历过程中会用Find或Select查询此表,或者用Compute方法统计此表。
3、遍历过程中会大量修改此表中某些行的值,被修改的行数越多,对于性能影响越大,如果被修改的行数很少,则几乎没有影响。

 

那么代码 该如何改造成类似的:

 

 

Dim Dic As new Dictionary(of DataRow, Integer)
Dim
v As Double
For Each
dr As DataRow In DataTables("表A").DataRows
v = DataTables("表A").Compute("Count(第二列 )", "第二列 = " & dr("第一列"))
dic
.Add(dr, v
)
Next
For Each
dr As DataRow In dic.Keys
dr("第四列") = dic(dr)
Next

 

 

另一个问题 既然编写帮助时以发现了这样的问题,为什么 后面的帮助 给出的代码示例,全部是没有规避该原则的代码示例呢?

既然已经发现问题,再给出代码示例时,最好符合该原则,代码使得上述2、3项不再出现在同一个遍历语句中,而是在不同的遍历语句中出现。


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


加好友 发短信
等级:三尾狐 帖子:688 积分:4903 威望:0 精华:0 注册:2013/10/27 17:14:00
  发帖心情 Post By:2014/5/13 23:46:00 [只看该作者]

我只能把代码优化成这样

Dim stst As Date = Date.Now '将开始时间保存在变量st中

Dim Dic As new Dictionary(of DataRow, Integer)
Dim v As Double

For Each dr As DataRow In DataTables("试验临时数据").DataRows
     Dim ly As String
Dim yx As Integer
     ly = dr("来源")
     yx = dr("有效序")

    v = DataTables("试验临时数据").Compute("Count([编号])", "[来源] = '" & ly & "' And [有效序] = '" & yx & "'  And 结果 = '合格'")
    dic.Add(dr, v)
Next
For Each dr As DataRow In dic.Keys
    dr("合格数量") = dic(dr)
Next
MessageBox.Show("耗时: " & (Date.Now - stst).TotalSeconds & "秒") '计算并显示执行代码所花费的秒数

 

处理4104条数据花费时间0.17秒

 改用上述代码后,整体代码为:

 

'删除临时数据表报有行
Dim stst As Date = Date.Now '将开始时间保存在变量st中
For i As Integer = Tables("试验临时数据").Rows.count-1 To 0 Step -1
    Tables("试验临时数据").Rows(i).Delete
Next

'生成表名
Dim st As Date = Date.Now
Dim d As Date = Date.Today
Dim dd As String
dd = Format(d, "yyMMdd")
dd = CStr(dd)
dd = "t" & dd

'合并外部数据源中的数据到临时数据表中
For Each cn As Connection In Connections
    Dim s As String = cn.ConnectionString
    If Connections.TryConnect(s) = True Then
        'MessageBox.Show("数据源无法连通!")
        If left(cn.Name,1) = "M" Then
           
            If cn.GetTableNames.Contains(dd) Then
                Dim mg As New Merger
                mg.ConnectionName = cn.Name '指定数据源名称
                mg.SourceTableName = dd '指定要合并的表
                mg.DataTableName = "试验临时数据" '指定接收数据的表
                mg.Merge() '开始合并
            End If
        End If
        For Each dr1 As DataRow In DataTables("试验临时数据").Select("来源 is null or 来源 = ''")
            dr1("来源") = cn.Name
            dr1("日期") = st
        Next
    End If
Next
'生成数据源序
For Each ly As String In DataTables("试验临时数据").GetValues("来源")
    Dim i As Integer = 1
    For Each dr As DataRow In DataTables("试验临时数据").Select("来源 = '" & ly & "'", "_Identify")
        dr("数据序") = i
        dr("有效序") = Math.Ceiling(i/3)
        i += 1
    Next
Next

For Each ly2 As String In DataTables("试验临时数据").GetValues("来源")
    Dim d1, d2, d3 As DataRow
    d1 = DataTables("试验临时数据").find("来源 = '" & ly2 & "'", "数据序 desc", 0)
    If d1("数据序") Mod 3 <> 0 Then
        d2 = DataTables("试验临时数据").find("来源 = '" & ly2 & "'", "数据序 desc", 1)
        If d2("数据序") Mod 3 <> 0 Then
            d2.Delete
        End If
        d1.Delete
    End If
Next


Dim Dic As new Dictionary(of DataRow, Integer)
Dim v As Double
For Each dr As DataRow In DataTables("试验临时数据").DataRows
    Dim ly As String
    Dim yx As Integer
    ly = dr("来源")
    yx = dr("有效序")
    v = DataTables("试验临时数据").Compute("Count([编号])", "[来源] = '" & ly & "' And [有效序] = '" & yx & "'  And 结果 = '合格'")
    dic.Add(dr, v)
Next
For Each dr As DataRow In dic.Keys
    dr("合格数量") = dic(dr)
Next
MessageBox.Show("耗时: " & (Date.Now - st).TotalSeconds & "秒") '计算并显示执行代码所花费的秒数

 

 

处理4104条数据,花费时间由原来的28秒减少到1.51秒,还能再优化不。

 

 

另将上述代码放在窗口 Afterload中 与命令窗口中(命令窗口中加上单元格暂停绘制)执行时间在命令窗口中明显有长于在窗口中执行时间。

 

如果是原未改进的代码 ,在窗口中需时间28秒左右,在命令窗口需要 51秒左右。为什么 ?

 


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


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2014/5/14 10:18:00 [只看该作者]

 回复35楼,1.5秒就不错了,将就用吧。

 

 如果要优化,请上传具体例子说明。


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


加好友 发短信
等级:三尾狐 帖子:688 积分:4903 威望:0 精华:0 注册:2013/10/27 17:14:00
  发帖心情 Post By:2014/5/14 13:17:00 [只看该作者]

Dim dta As DataTable = DataTables("试验结果")
 For Each dr As DataRow In DataTables("试验临时数据").Select("[数据序] Mod 3 = 0")
    If dta.Find("编号= '" & dr("编号") & "' and 来源='" & dr("来源") & "' and 数据序=" & dr("数据序")) Is Nothing Then
          dr("存在2")=1
    End If
Next

我只想对 其中 数据序 除以3 等于0的数据记录 进行遍历 如何写代码 (只对其中的1/3数据进行处理)

For Each dr As DataRow In DataTables("试验临时数据").Select("[数据序] Mod 3 = 0")  这句代码 不行 如何改造?


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


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2014/5/14 14:09:00 [只看该作者]

 做不到,需要加判断

 

Dim dta As DataTable = DataTables("试验结果")
For Each dr As DataRow In DataTables("试验临时数据").Select("")
    If dr("数据序") Mod 3 = 0 Then
        If dta.Find("编号= '" & dr("编号") & "' and 来源='" & dr("来源") & "' and 数据序=" & dr("数据序")) Is Nothing Then
            dr("存在2")=1
        End If
    End If
Next


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


加好友 发短信
等级:三尾狐 帖子:688 积分:4903 威望:0 精华:0 注册:2013/10/27 17:14:00
  发帖心情 Post By:2014/5/14 17:03:00 [只看该作者]

Dim dt As DataTable = DataTables("试验数据")
For Each dr As DataRow In DataTables("试验临时数据").DataRows
    If dt.Find("编号= '" & dr("编号") & "' and 来源='" & dr("来源") & "' and 数据序=" & dr("数据序")) Is Nothing Then
        dr("存在1")=1
    End If
Next

 

这代码 当DataTables("试验数据")无数据时,执行好像正常

当DataTables("试验数据") 有数据时,提示错误了。

 

提示信息 为:在 Range 对象中,Min (51)必须小于或等于 max (-1)。

 

另本代码本意是 验证在DataTables("试验数据") 中是否存在本行数据,如何改成 SQL后台数据验证代码。 每次验证时,DataTables("试验数据")
并不会完全加载。

 

恩 找到原因了

正确代码为:

Dim dt As DataTable = DataTables("试验数据")
For Each dr As DataRow In DataTables("试验临时数据").DataRows
    If dt.Find("编号 = '" & dr("编号") & "' and 来源 = '" & dr("来源") & "' and 数据序 ='" & dr("数据序") & "'") Is Nothing Then
        dr("存在1")=1
    End If
Next

 

 

但有一个地方不好理解: 我的 数据序 为数字型数据非字符型,

 

按量说 数据型:and 数据序 =" & dr("数据序") & "  不要单引号

但事实上必须 加上 单引号才行。

 

[此贴子已经被作者于2014-5-14 17:24:37编辑过]

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


加好友 发短信
等级:三尾狐 帖子:688 积分:4903 威望:0 精华:0 注册:2013/10/27 17:14:00
  发帖心情 Post By:2014/5/14 18:00:00 [只看该作者]

Dim dt As DataTable = DataTables("试验数据")
For Each dr As DataRow In DataTables("试验临时数据").DataRows
    If dt.Find("编号= '" & dr("编号") & "' and 来源='" & dr("来源") & "' and 数据序='" & dr("数据序") & "'") Is Nothing Then
        dr("存在1") = 1
    End If
Next

 

 

请问这代码 如何改成 使用SQL进行 后台数据验证

 

 


 回到顶部
总数 44 上一页 1 2 3 4 5 下一页