以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  [求助]关于数据分拣的函数如何编写  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=73771)

--  作者:loongtai
--  发布时间:2015/8/26 11:45:00
--  [求助]关于数据分拣的函数如何编写
分拣记录表见附件。
 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:数据分拣.zip

分拣参数:参数1范围值:880,参数2范围值600
分组数量:13
分拣目的:按要求进行分组,每组内的记录数量为13,每组内的max(参数1)-min(参数1)<=880,且每组内的max(参数2)-min(参数2)<=600
我的分拣步骤如下:
1.按参数1 desc 排序,以drs(0)的参数1值为基准,筛选出参数1>=(dr(0)(参数1)-880)的记录
2.如果筛选记录数量<分组数量(13),则drs(0)被剔除--此为永久剔除,标记为-100;否则进行下一步
3.对drs 内的记录进行参数2的筛选,统计drs内前13行(分组数量)记录的参数2极值=max(参数2)-min(参数2),如果参数2极值<=600,则符合条件的第一个分组已找出,对drs内前13行的新组号进行标记,标记为1,对分拣表中其它记录继续从步骤1进行分拣;如果参数2极值不符合要求,则需找出需剔除的行
剔除行筛选方法:计算drs内前13行的avg(参数2)、max(参数2)、min(参数2),如果avg(参数2)<(max(参数2)+min(参数2))/2,则将max(参数2)行为剔除行,反之,min(参数2)行为剔除行,但此时剔除只是临时剔除,标记为-10,一旦参数1重新排序后,此时临时剔除行的标记清除,临时剔除行再次进行筛选。
如此重复1-3,直至不能分组为止。
我自己写的分拣函数如下,老是出错,还请前辈们能给出更好的方法:

图片点击可在新窗口打开查看此主题相关图片如下:qq截图20150826114421.png
图片点击可在新窗口打开查看

图片点击可在新窗口打开查看此主题相关图片如下:qq截图20150826114447.png
图片点击可在新窗口打开查看




--  作者:loongtai
--  发布时间:2015/8/26 11:46:00
--  
函数还差一张图片

图片点击可在新窗口打开查看此主题相关图片如下:qq截图20150826114511.png
图片点击可在新窗口打开查看


--  作者:大红袍
--  发布时间:2015/8/26 12:11:00
--  
Dim num1 As Integer = 880
Dim num2 As Integer = 600
Dim count As Integer = 13
Dim idx As Integer = 1
Dim dt As DataTable = DataTables("分拣数据")
Dim drs As List(Of DataRow) = dt.Select("", "参数1 desc")
dt.ReplaceFor("新组号", Nothing)
dt.ReplaceFor("组内序号", Nothing)
For Each dr As DataRow In drs
    If dr.Isnull("新组号") Then
        Dim filter As String = "新组号 is null and 参数1 >= " & dr("参数1") - num1 & " And 参数2 >= " & dr("参数2") - num2
        Dim gdrs As List(Of DataRow) = dt.Select(filter, "参数1 desc")
        If gdrs.Count >= count Then
            For i As Integer = 0 To count - 1
                gdrs(i)("新组号") = idx
                gdrs(i)("组内序号") = i + 1
            Next
            idx += 1
        End If
    End If
Next

--  作者:loongtai
--  发布时间:2015/8/26 13:58:00
--  
版主,参数1与参数2并不是对应的,参数1反向排序后,对应的参数2并一定是反向排序,同组内参数1最大的行,其参数2并不一定是组内最大的。 
所以对参数2用这样的判断应该不行:参数2 >= " & dr("参数2") - num2
参数2是否符合条件应该用极值:drs内前13行(分组数量)记录的参数2极值=max(参数2)-min(参数2),
[此贴子已经被作者于2015/8/26 14:03:34编辑过]

--  作者:大红袍
--  发布时间:2015/8/26 14:07:00
--  
无语,代码执行没问题。
--  作者:loongtai
--  发布时间:2015/8/26 14:13:00
--  
代码本身语法肯定是没问题的,但我觉得可能会出现有可能是把本该符合条件的记录给排除在分组外了。
--  作者:大红袍
--  发布时间:2015/8/26 14:21:00
--  

 

[此贴子已经被作者于2015/8/26 14:21:53编辑过]

--  作者:大红袍
--  发布时间:2015/8/26 14:24:00
--  
逻辑上没有问题,循环了每一行,只要满足条件就形成了分组
--  作者:loongtai
--  发布时间:2015/8/26 14:36:00
--  
我试了下,怎么参数1有超出范围的

图片点击可在新窗口打开查看此主题相关图片如下:qq截图20150826143636.png
图片点击可在新窗口打开查看


--  作者:大红袍
--  发布时间:2015/8/26 15:28:00
--  

 

Dim num1 As Integer = 880
Dim num2 As Integer = 600
Dim count As Integer = 13
Dim idx As Integer = 1
Dim dt As DataTable = DataTables("分拣数据")
Dim drs As List(Of DataRow) = dt.Select("", "参数1 desc")
dt.ReplaceFor("新组号", Nothing)
dt.ReplaceFor("组内序号", Nothing)
For Each dr As DataRow In drs
    If dr.Isnull("新组号") Then
        Dim filter As String = "新组号 is null and  参数1 <= " & dr("参数1") & " and 参数1 >= " & dr("参数1") - num1
        Dim gdrs As List(Of DataRow) = dt.Select(filter, "参数2 desc")
        If gdrs.Count >= count Then
            Dim pos As Integer
            For i As Integer = 0 To gdrs.count - 1
                If gdrs(i)("_Identify") = dr("_Identify")
                    pos = i
                    Exit For
                End If
            Next

            For i As Integer = 0 To gdrs.Count - count
                If i<=pos AndAlso i+count>pos Then
                    If gdrs(i)("参数2") - gdrs(i+count-1)("参数2") <= num2 Then
                        For j As Integer = i To i+count - 1
                            gdrs(j)("新组号") = idx
                            gdrs(j)("组内序号") = j-i+1
                        Next
                        idx += 1
                        Exit For
                    End If
                End If
            Next
        End If
    End If
Next

[此贴子已经被作者于2015/8/26 16:18:31编辑过]