Foxtable(狐表)用户栏目专家坐堂 → 修改后的getvalues方法肯定有Bug


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

主题:修改后的getvalues方法肯定有Bug

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


加好友 发短信
等级:小狐 帖子:302 积分:2069 威望:0 精华:0 注册:2017/11/19 9:46:00
修改后的getvalues方法肯定有Bug  发帖心情 Post By:2021/6/24 6:13:00 [显示全部帖子]


图片点击可在新窗口打开查看此主题相关图片如下:新版foxtable之结果.jpg
图片点击可在新窗口打开查看


图片点击可在新窗口打开查看此主题相关图片如下:旧版foxtable结果.jpg
图片点击可在新窗口打开查看

偶然的原因发现2021.5.29版本当中datatable.getvalues方法有bug,有时候不能区分大小写,导致提取的值有重复的,以至于据此生成的报表也产生了错误。
我比较了旧的2020.5.1版本的计算结果,用同样的代码,链接同样的数据库(sql server),报表结果是不一样的。旧版的结果是对的。

诡异之处似乎并不是所有的大小写单词都不能区分,只有个别情况有问题。请仔细查查吧,估计你们不会很容易复现的,但请不要轻易放过了。这个bug带来的后果挺严重,会计年报都给做错了。
我把我的报表结果源代码附上,问题肯定出在Dim CustomerIDs  As List (of String) = DTB.GetValues("CustomerID", , "CustomerID asc") 的代码上。

另外我手工读了数据库,把customerID="Wyatt"名下的记录都看了个遍,并没有发现有小写字母开头的记录。所以这个报表结果就更诡异了一些。

 
 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:02.txt


[此贴子已经被作者于2021/6/24 6:15:45编辑过]

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


加好友 发短信
等级:小狐 帖子:302 积分:2069 威望:0 精华:0 注册:2017/11/19 9:46:00
  发帖心情 Post By:2021/6/24 17:07:00 [显示全部帖子]

你们要是实在测不出来,能不能求求你们改成老版的算法, 我们不要求性能了行不行啊? 最近升版的几次大bug实在让我心力憔悴, 感觉这次升级引进的bug负面作用远远超过改进的这点性能. 再这么搞下去都不知道怎么办了, 整天提心吊胆的.

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


加好友 发短信
等级:小狐 帖子:302 积分:2069 威望:0 精华:0 注册:2017/11/19 9:46:00
  发帖心情 Post By:2021/6/25 5:36:00 [显示全部帖子]

我打算自己研究一个算法试试。 
按Foxtable这个趋势,还是尽量把算法多掌握在自己手里更踏实一些。

两个思路,具体效率可能需要大量的测试才能知道:

1. 利用List集合,(前提是.net内置的list查找算法效率够高,姑且信任他们), 依次从datatable的指定列取值,每个值转换大写(这个地方可能损失效率),存入List2, 判断List2.contains,false的话则把没转换大小写的值存入List1,一直遍历到最后一行,之后取出List1的值就是唯一值了。

这个或许用字典更快些?还没仔细研究二者区别。


2. 这个纯粹是自己玩了,效率不好说。先建立一维数组arr1 ,数组维度等于datatable的行数,将该列所有行的值全部写入数组,对数组进行排序,之后对每个数组元素循环,利用二分法在其中查找(数组下标不同作为约束条件),用“="号进行比较运算(这个可以自动忽略大小写),找到重复则跳过该值,找不到重复则保存该值到一个集合。最后得到的集合就是不重复值集合了。

这些算法只用于代替前台的getvalues方法,后台的getvalues方法可以用sql语句的distinct代替,那个是数据库内置的算法,效率肯定没得说。
前台加载数据量一般不会很大,所以也许效率上损失点,但换来了更好的稳定性,估计可以接受. 

我对算法不精通,这个两个思路肯定比较low,哪位同道若有更好的算法欢迎指导
[此贴子已经被作者于2021/6/25 6:38:44编辑过]

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


加好友 发短信
等级:小狐 帖子:302 积分:2069 威望:0 精华:0 注册:2017/11/19 9:46:00
  发帖心情 Post By:2021/6/25 8:30:00 [显示全部帖子]

我研究了一下,据说还是内置字典的查找算法更快,下面用字典做了一个自定义的代替datatable.getvalues的函数。
我测试了一下,结果是正确的,在需要保证可靠性胜过效率的场合建议采用这个函数代替getvalues方法,我的测试是几千行数据的级别,没感觉速度和foxtable getvalues方法有差距,具体耗时希望大家帮忙测试,结果反馈在这里。

函数代码如下,大家可以直接套用。
另外datatable.sqlgetvalues算法的在多列排序的情况下也有bug,上次反馈后还没有修正。
我准备把所有的这些算法都改成自定义函数,避免受到升级的干扰。 
' used to replace the datatable.getvalues method, because foxtable has bugs

Dim DT As DataTable = args(0)
Dim ColName As String = args(1)

Dim FilterStr As String =""
Dim SortStr As String=""

If args.count >2 Then
   FilterStr  =  args(2)
End If

If args.count>3 Then
    SortStr  = args(3)
End If


If DT Is Nothing OrElse ColName=Nothing Then
    Return Nothing
End If

If dt.DataRows.count = 0 Then Return Nothing
'***************************************************************************************************
If SortStr  = ""  Then SortStr = ColName & " asc"  ' default sort ascending
'***************************************************************************************************
'先排序datatable

Dim NDT As system.data.DataTable  = DT.basetable
 

Dim dv = ndt.DefaultView
dv.Rowfilter = filterStr
dv.Sort = sortstr
 
Dim dtCopy As system.data.DataTable = dv.ToTable
'***************************************************************************************************
try
    
    Dim dic As  new Dictionary (of String, Integer) (StringComparer.OrdinalIgnoreCase)  ' ignore case
    
    
    For i As Integer =0 To dtCopy.Rows.count-1
        
        Dim str As String = dtCopy.Rows(i)(ColName)
        If dic.ContainsKey(str) =False Then
            dic.add(str,i)
        End If
        
    Next
    
    Dim Ks As new List  (of String)
    
    For Each kk As String In dic.keys
        ks.add(kk)
    Next
    
    Return ks
    
catch ex As exception
    Return  False  '在上一层触发错误,以便上层catch可以捕捉到
    
End try

[此贴子已经被作者于2021/6/25 9:38:09编辑过]

 回到顶部