改进查询/ vba按链表分组 [英] Improve query/vba to group by linked list

查看:97
本文介绍了改进查询/ vba按链表分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我收到一些表格,其中有按链表分组的元素,我很难处理它。



该函数可以找到它,但我常常被问到自从任务调度程序启动以来它的宏在哪里或有一些内存问题。



我使用下面的代码来找出idGroup(翻译成英文),我想知道是否有方法来即兴表达它,特别是它的速度,因为它需要长达一个小时的30 000行和大约2500组。 ..(这就是我使用VBA看到进展的原因......)



 ' 简单示例 
' idGroup,id2,id1
' 6338546,14322882,13608969
' 6338546,13608969,13255 363
' 6338546,6338546,14322882
' 6338546,11837926,11316332
' 6338546,12297571,11837926
' 6338546, 13255363,12811071
' 6338546,12811071,12297571
< span class =code-comment>' 6338546,7610194,7343817
' 6338546,7935943,7610194
' 6338546,8531387,7935943
' 6338546,6944491,6611041
' 6338546,7343817,6944491
' 6338546,9968746,9632204
' 6338546,10381694,9968746
' 6338546,6611041,0
' 6338546,8920224,8531387
' 6338546,9632204,8920224
' 6338546,11316332,10941093
' 6338546,10941093,10381694


公共 函数 GetidGroup()
' 首先id1始终为0
sql = SELECT idGroup,id2,id1 F ROM TABLE_WITH_LINKED_LIST WHERE id1 ='0'ORDER BY id2 DESC
Dim rs As Recordset
Dim uidLikedList As String ,id2 作为 字符串,id1 As 字符串

设置 rs = CurrentDb.OpenRecordset(sql)
Dim 作为
Dim idGroup 作为 字符串
Dim incrément作为 ,进度作为 Double

total = rs.RecordCount $ b $bincrément= 1

rs.EOF
progress = Math.Round( 100 *incrément/ total, 2

' 打印以便冻结
Debug.Print progress

如果 rs.Fields( idGroup)= 然后
id2 = rs。字段( id2

idGroup = precedentUid(id2)

rs.Edit
rs.Fields( idGroup)= idGroup
rs 。更新
结束 如果
$ b $bincrément=incrément+ 1
rs.MoveNext
Wend

rs.Close
设置 rs = 没什么
GetidGroup =总计
结束 功能

' 递归函数
' 目前最深的是62次调用
公共 功能 precedentUid(id2 作为 String as String
sql = SELECT idGroup,id2 FROM TABLE_WITH_LINKED_LIST WHERE id1 ='& id2& '
Dim rs As Recordset
Dim precedentid2 As 字符串
Dim idGroup As 字符串
Dim ret As 字符串

设置 rs = CurrentDb.OpenRecordset(sql)
如果 rs.EOF 那么
rs.Close
设置 rs = Nothing
precedentUid = id2
Else
' 某些记录有多个引用
' 56个受影响的记录:
' TODO:将min id2提供给组
ret = - 1
rs.EOF
如果 rs.Fields( idGroup)= 然后
precedentid2 = rs.Fields( id2
idGroup = precedentUid(precedentid2)

如果 re t = - 1 < span class =code-keyword> CLng (ret)> CLng (idGroup)然后
ret = idGroup
结束 如果

' Debug.Print id2& &先行者2& & idGroup

rs.Edit
rs.Fields( idGroup )= idGroup
rs.Update
结束 如果
rs.MoveNext
Wend
rs.Close
Set rs = 没什么
precedentUid = ret
结束 如果
结束 功能





提前感谢任何提示。



Guillaume。

解决方案

如果我理解你,你试图将 idGroup 更新为 MIN(id2)如果 idGroup =并且id1 =0

如果以上是真的,你不需要任何VBA代码,你只需 UPDATE [ ^ ]查询基于同一张表。



它可能是这样的:

 更新 LINKED_LISTS  AS  LL 
INNER JOIN
SELECT MIN(id2) AS idGroup
FROM LINKED_LISTS
WHERE idGroup = AND id1 = 0 AS T1 ON LL.id2 = T1.id2
SET idGroup = T1.idGroup





例如:

http://www.fmsinc.com/microsoftaccess/query/snytax/update-query.html [ ^ ]

http://msdn.microsoft.com/en-us/library/office/bb221186%28v=office.12%29.aspx [< a href =http://msdn.microsoft.com/en-us/library/office/bb221186%28v=office.12%29.aspxtarget =_ blanktitle =New Window> ^ ]

http://www.techonthenet.com/access/queries/update2。 php [ ^ ]

http://stackoverflow.com/questions/871905/use-select-inside-an-update-query [< a href =http://stackoverflow.com/questions/871905/use-select-inside-an-update-querytarget =_ blanktitle =新窗口> ^ ]



顺便说一句:我想知道为什么id'的字段是文本字段?


我自己并没有解决这个问题,但是我已经获得了更好的回复范德加斯特的MSDN [ ^ ]

Hi,

I receive some tables where there are elements grouped by linked lists and I have trouble to deal with it.

The function works find as it but I''m often asked where is its macro when launched since task scheduler or have some memory issues.

I use the following code to find out the idGroup (translated to English) and I''m wondering if there would by ways to improvise it especially its speed because it takes up to an hour for 30 000 rows and about 2500 groups... (It''s why I had used VBA to see progress...)

'Simple example
'idGroup,id2,id1
'6338546,14322882,13608969
'6338546,13608969,13255363
'6338546,6338546,14322882
'6338546,11837926,11316332
'6338546,12297571,11837926
'6338546,13255363,12811071
'6338546,12811071,12297571
'6338546,7610194,7343817
'6338546,7935943,7610194
'6338546,8531387,7935943
'6338546,6944491,6611041
'6338546,7343817,6944491
'6338546,9968746,9632204
'6338546,10381694,9968746
'6338546,6611041,0
'6338546,8920224,8531387
'6338546,9632204,8920224
'6338546,11316332,10941093
'6338546,10941093,10381694


Public Function GetidGroup()
    'first id1 is always 0
    sql = "SELECT idGroup, id2, id1 FROM TABLE_WITH_LINKED_LIST WHERE id1='0' ORDER BY id2 DESC"
    Dim rs As Recordset
    Dim uidLikedList As String, id2 As String, id1 As String
   
    Set rs = CurrentDb.OpenRecordset(sql)
    Dim total As Long
    Dim idGroup As String
    Dim incrément As Long, progress As Double
       
    total = rs.RecordCount
    incrément = 1
   
    While Not rs.EOF
        progress = Math.Round(100 * incrément / total, 2)
       
        'Print in order to avoir freezing
        Debug.Print progress
       
        If rs.Fields("idGroup") = "" Then
            id2 = rs.Fields("id2")
                   
            idGroup = precedentUid(id2)
           
            rs.Edit
            rs.Fields("idGroup") = idGroup
            rs.Update
        End If
       
        incrément = incrément + 1
        rs.MoveNext
    Wend
   
    rs.Close
    Set rs = Nothing
    GetidGroup = total
End Function

'Recursive function
'Deepest so far is about 62 calls
Public Function precedentUid(id2 As String) As String
    sql = "SELECT idGroup, id2 FROM TABLE_WITH_LINKED_LIST WHERE id1 = '" & id2 & "'"
    Dim rs As Recordset
    Dim precedentid2 As String
    Dim idGroup As String
    Dim ret As String
   
    Set rs = CurrentDb.OpenRecordset(sql)
    If rs.EOF Then
        rs.Close
        Set rs = Nothing
        precedentUid = id2
    Else
        'Some records have several references
        '56 impacted records  :
        'TODO : Give the min id2 to the group
        ret = "-1"
        While Not rs.EOF           
            If rs.Fields("idGroup") = "" Then
                precedentid2 = rs.Fields("id2")
                idGroup = precedentUid(precedentid2)
               
                If ret = "-1" Or CLng(ret) > CLng(idGroup) Then
                    ret = idGroup
                End If
               
                'Debug.Print id2 & " " & precedentid2 & " " & idGroup
               
                rs.Edit
                    rs.Fields("idGroup") = idGroup
                rs.Update
            End If
            rs.MoveNext
        Wend
        rs.Close
        Set rs = Nothing
        precedentUid = ret
    End If
End Function



Thanks in advance for any hint.

Guillaume.

解决方案

If i understand you well, you''re trying to update idGroup to MIN(id2) if idGroup="" And id1="0".
If above is true, you don''t need any VBA code, you need only UPDATE[^] query based on the same table.

It could be something like this:

UPDATE LINKED_LISTS AS LL
INNER JOIN (
            SELECT MIN(id2) AS idGroup
            FROM LINKED_LISTS
            WHERE idGroup="" AND id1="0") AS T1 ON LL.id2 = T1.id2
SET  idGroup = T1.idGroup



Examples:
http://www.fmsinc.com/microsoftaccess/query/snytax/update-query.html[^]
http://msdn.microsoft.com/en-us/library/office/bb221186%28v=office.12%29.aspx[^]
http://www.techonthenet.com/access/queries/update2.php[^]
http://stackoverflow.com/questions/871905/use-select-inside-an-update-query[^]

BTW: I''m wondering why id''s fields are text fields?


I didn''t solve this myself but I had been given the better reply on MSDN by Vanderghast[^]


这篇关于改进查询/ vba按链表分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆