ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 432|回复: 5

For next ,循环上百万条记录,需要多长时间。

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-7-2 12:21 | 显示全部楼层 |阅读模式
image.png


           With Rs
             .MoveFirst
             For ii = 0 To Rs.RecordCount - 1
                ''Debug.Print .Fields(4)
                Set oRng = Sht.Cells(Rr + ii, "J")
                SqlStr = "Select oName,oPath " & SqlShtStr & "Where oName ='" & .Fields(4) & "'"
                Set oRs = SqlRetuRs(SqlStr)
                With oRs
                     .MoveFirst
                     For jj = 0 To .RecordCount - 1
                         oRng(, jj) = .Fields(1)
                         Debug.Print oRng(, jj).Address, Format(Time - T, "h:mm:ss")
                         'oRng.Hyperlinks.Add oRng(, jj), .Fields(1)
                         .MoveNext
                     Next jj
                End With
                .MoveNext
             Next ii
           End With


循环 oRng(, jj) = .Fields(1),写到单元格中与1秒左右。
循环34710个Rs, 单元格中=34710/60^2,至少在9小时左右。
''''
image.png


请问高手运行下面的代码。用了多长时间。几秒钟能完成上百万的记录。
'''


  1. Function SqlRetuRs(SqlStr)

  2.    Dim Cn As ADODB.Connection
  3.        Set Cn = New ADODB.Connection
  4.    Dim Rs As ADODB.Recordset
  5.        Set Rs = New ADODB.Recordset
  6.         '
  7.        If InStr(UCase(Application.Path), "WPS") > 0 Then
  8.            Cn.Open "Provider=Microsoft.JET.OLEDB.4.0;Extended Properties='Excel 8.0;HDR=yes';Data Source=" & ThisWorkbook.FullName
  9.        Else
  10.           Cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 12.0;HDR=yes';data source=" & ThisWorkbook.FullName
  11.        End If
  12.        Rs.Open SqlStr, Cn, adOpenKeyset, adLockOptimistic
  13.        Set SqlRetuRs = Rs
  14. End Function


  15. Function GroupYearMonthDay(SqlShtStr, Rng As Range, T As Date)
  16.     ''"oDate", "Year", "YearMonth", "YearMonthDay", "oName", "oSize", "oType", "oPath"
  17.     Dim Rs As ADODB.Recordset, oRs As ADODB.Recordset
  18.     Dim SqlStr
  19.         SqlStr = "Select  Year, YearMonth, YearMonthDay,oDate, oName, oSize, oType,Count(oName) "
  20.         'SqlStr = "Select oDate, Year "
  21.         SqlStr = SqlStr & SqlShtStr
  22.         SqlStr = SqlStr & " Where Not oName Is Null And oType = 'JPG 文件' "
  23.         SqlStr = SqlStr & "Group by oDate, Year, YearMonth, YearMonthDay, oName, oSize, oType "
  24.         
  25.         'SqlStr = SqlStr & "Group by oDate, Year "
  26.         SqlStr = SqlStr & " Order By oDate "
  27.         Debug.Print SqlStr
  28.    Dim tArr, Str, Rr
  29.    Dim ii, jj
  30.        tArr = Array("Year", "YearMonth", "YearMonthDay", "oDate", "oName", "oSize", "oType", "CountName", "oPath")
  31.        Rng.Resize(, UBound(tArr)) = tArr
  32.        Set Rs = SqlRetuRs(SqlStr)
  33.        'Debug.Print Rs.RecordCount, Rng(3, 1).Address
  34.        Rng(3, 1).CopyFromRecordset Rs
  35.    Dim Sht As Worksheet, oRng As Range
  36.        Set Sht = Rng.Parent
  37.        ''
  38.        Rr = Rng.Row + 2
  39.        With Sht
  40.            .Cells(4, 2) = "=" & Rng.Resize(Rs.RecordCount + 1, Rs.Fields.Count + 1).Address
  41.            Str = "=""Sql Gropy Date  "" & " & "Count( " & Rng(3, "F").Resize(Rs.RecordCount + 1, 1).Address(0, 0) & ")"
  42.            .Cells(2, "E") = Str & "&" & " "" ,Time:" & Format(Time - T, "h:mm:ss") & """"
  43.       
  44.            With Rs
  45.              .MoveFirst
  46.              For ii = 0 To Rs.RecordCount - 1
  47.                 ''Debug.Print .Fields(4)
  48.                 Set oRng = Sht.Cells(Rr + ii, "J")
  49.                 SqlStr = "Select oName,oPath " & SqlShtStr & "Where oName ='" & .Fields(4) & "'"
  50.                 Set oRs = SqlRetuRs(SqlStr)
  51.                 With oRs
  52.                      .MoveFirst
  53.                      For jj = 0 To .RecordCount - 1
  54.                          oRng(, jj) = .Fields(1)
  55.                          Debug.Print oRng(, jj).Address
  56.                          'oRng.Hyperlinks.Add oRng(, jj), .Fields(1)
  57.                          .MoveNext
  58.                      Next jj
  59.                 End With
  60.                 .MoveNext
  61.              Next ii
  62.            End With
  63.            Str = "=""Sql Gropy Date  "" & " & "Count( " & Rng(4, "F").Resize(Rs.RecordCount + 1, 1).Address(0, 0) & ")"
  64.            .Cells(3, "E") = Str & "&" & " "" ,Time:" & Format(Time - T, "h:mm:ss") & """"
  65.        End With
  66.       
  67.        Stop
  68.       
  69.        Stop
  70. End Function

  71. Sub del()
  72.    Dim Tt As Date: Tt = Time
  73.    Dim Rng As Range
  74.    Dim FolderRng As Range
  75.    Dim AllFileRng As Range
  76.    Dim Str
  77.    Dim Rr, Cc
  78.        Rr = 10
  79.        Cc = 20
  80.    Dim SqlShtStr
  81.        With Sheet3
  82.            SqlShtStr = " From [" & .Name & "$" & .Range(.Cells(4, 1).Formula).Address(0, 0) & "] "
  83.            Debug.Print SqlShtStr
  84.            GroupYearMonthDay " From [" & .Name & "$" & .Range(.Cells(4, 1).Formula).Address(0, 0) & "] ", .Cells(Rr, 1), Tt
  85.        End With
  86.        Stop

  87. End Sub
复制代码



del.rar

176.24 KB, 下载次数: 8

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-7-2 13:14 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
With Rs
             .MoveFirst
             For ii = 0 To Rs.RecordCount - 1
                ''Debug.Print .Fields(4)
                Set oRng = Sht.Cells(Rr + ii, "J")
                SqlStr = "Select oName,oPath " & SqlShtStr & "Where oName ='" & .Fields(4) & "'"
                Set oRs = SqlRetuRs(SqlStr)
                With oRs
                     .MoveFirst
                     For jj = 0 To .RecordCount - 1
                         oRng(, jj) = .Fields(1)
                         Debug.Print oRng(, jj).Address, Format(Time - T, "h:mm:ss")
                         'oRng.Hyperlinks.Add oRng(, jj), .Fields(1)
                         .MoveNext
                     Next jj
                End With
                .MoveNext
             Next ii
           End With
**************************************************

$I$2735       0:44:48
$I$2736       0:44:49
$I$2737       0:44:50
$I$2738       0:44:51
$I$2739       0:44:52
$I$2740       0:44:53
$I$2741       0:44:54
$I$2742       0:44:55
$I$2743       0:44:56
$I$2744       0:44:57
$I$2745       0:44:58
$I$2746       0:44:59
$I$2747       0:45:00
$I$2748       0:45:01
$I$2749       0:45:02
$I$2750       0:45:03
$I$2751       0:45:05
*****************************
for next 2751单元格


运行45分钟。





TA的精华主题

TA的得分主题

发表于 2024-7-2 14:15 | 显示全部楼层
range操作太多了,不如说目的,别人重新帮你写写看

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-7-2 20:18 | 显示全部楼层
本帖最后由 ning84 于 2024-7-2 22:49 编辑
kevinchengcw 发表于 2024-7-2 14:15
range操作太多了,不如说目的,别人重新帮你写写看

谢谢回复。同意你的太多Range操作的表述。
循环34710,For   oRng(, jj) = .Fields(1)  Next 方法肯定有问题。


  1. Function GroupYearMonthDay(SqlShtStr, Rng As Range, T As Date, RootName)
  2.     ''"oDate", "Year", "YearMonth", "YearMonthDay", "oName", "oSize", "oType", "oPath"
  3.     Dim Rs As ADODB.Recordset, oRs As ADODB.Recordset
  4.     Dim SqlStr
  5.         SqlStr = "Select  Year, YearMonth, YearMonthDay,oDate, oName, oSize, oType,Count(oName),"
  6.         SqlStr = SqlStr & "'" & RootName & "\' + Format(oDate, 'yyyy年') + '\' + Format(oDate, 'yyyy年mm月') + '\' + Format(oDate, 'yyyy年mm月dd日') + '\' + oName ,"
  7.         SqlStr = SqlStr & " IIf(COUNT(oName) > 0, MAX(IIf(oPath LIKE '%\%\%', oPath, NULL)), NULL), "
  8.         SqlStr = SqlStr & " IIf(COUNT(oName) > 1, MAX(IIf(oPath LIKE 'F:\JPG\StreetSnap\%\%\%\%', oPath, NULL)), NULL) "
  9.         'SqlStr = "Select oDate, Year "
  10.         SqlStr = SqlStr & SqlShtStr
  11.         SqlStr = SqlStr & " Where Not oName Is Null And oType = 'JPG 文件' "
  12.         SqlStr = SqlStr & "Group by oDate, Year, YearMonth, YearMonthDay, oName, oSize, oType "
  13.         
  14.         'SqlStr = SqlStr & 6"Group by oDate, Year "
  15.         SqlStr = SqlStr & " Order By oDate "
  16.         Debug.Print SqlStr
  17.    Dim tArr, Str, Rr
  18.    Dim ii, jj
  19.        tArr = Array("Year", "YearMonth", "YearMonthDay", "oDate", "oName", "oSize", "oType", "CountName", "oPath")
  20.        Rng.Resize(, UBound(tArr)) = tArr
  21.        Set Rs = SqlRetuRs(SqlStr)
  22.        'Debug.Print Rs.RecordCount, Rng(3, 1).Address
  23.        Rng(3, 1).CopyFromRecordset Rs
  24.    Dim Sht As Worksheet, oRng As Range
  25.        Set Sht = Rng.Parent
  26.        ''
  27.        Rr = Rng.Row + 2
  28.        With Sht
  29.            .Cells(4, 2) = "=" & Rng.Resize(Rs.RecordCount + 1, Rs.Fields.Count + 1).Address
  30.            Str = "=""Sql Gropy Date  "" & " & "Count( " & Rng(3, "F").Resize(Rs.RecordCount + 1, 1).Address(0, 0) & ")"
  31.            .Cells(2, "E") = Str & "&" & " "" ,Time:" & Format(Time - T, "h:mm:ss") & """"
  32.        End With
  33.        Stop
  34.        Stop
  35.        Stop
  36. End Function
复制代码




del.rar

1.5 MB, 下载次数: 3

TA的精华主题

TA的得分主题

发表于 2024-7-3 09:30 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
这个试一下,结果写到AC10开始的位置
  1. Sub test()
  2. Dim Dic, Arr, Arrt, Arrk, N&, I&, R&, S$, OK As Boolean, T#
  3. T = Timer
  4. Set Dic = CreateObject("scripting.dictionary")
  5. With ThisWorkbook.Worksheets("TraverseFolderAndFile11")
  6.   Arrt = Split("Year,YearMonth,YearMonthDay,oDate,oName,oSize,oType,CountName,oPath", ",")
  7.   Arrk = Arrt: R = 1
  8.   Arr = .Range("t10:t" & .Cells(.Rows.Count, "t").End(3).Row).Resize(, UBound(Arrt) + 1).Value
  9.   For N = LBound(Arrk) To UBound(Arrk)
  10.     For I = LBound(Arr, 2) To UBound(Arr, 2)
  11.       If Arr(1, I) = Arrk(N) Then Arrk(N) = I: Exit For
  12.     Next I
  13.   Next N
  14.   Arrk(7) = ""
  15.   For I = LBound(Arr, 2) To UBound(Arr, 2)
  16.     Arr(1, I) = Arrt(I - 1)
  17.   Next I
  18.   For N = LBound(Arr) + 1 To UBound(Arr)
  19.     If Arr(N, 5) <> "" Then
  20.       If Arr(N, 7) = "JPG 文件" Then
  21.         S = ""
  22.         For I = LBound(Arr, 2) To LBound(Arr, 2) + 6
  23.           S = S & vbTab & Arr(N, I)
  24.         Next I
  25.         If Dic.exists(S) Then
  26.           Arr(Dic(S), 8) = Arr(Dic(S), 8) + 1
  27.         Else
  28.           R = R + 1: Dic(S) = R
  29.           If R = N Then
  30.             For I = LBound(Arrk) To UBound(Arrk)
  31.               If Arrk(I) = "" Then Arrt(I + 1) = 1 Else Arrt(I + 1) = Arr(N, Arrk(I))
  32.             Next I
  33.             For I = LBound(Arrt) To UBound(Arrt)
  34.               Arr(R, I + 1) = Arrt(I)
  35.             Next I
  36.           Else
  37.             For I = LBound(Arrk) To UBound(Arrk)
  38.               If Arrk(I) = "" Then Arr(R, I + 1) = 1 Else Arr(R, I + 1) = Arr(N, Arrk(I))
  39.             Next I
  40.           End If
  41.         End If
  42.       End If
  43.     End If
  44.   Next N
  45.   .[ac10].Resize(R, UBound(Arr, 2)).Value = Arr
  46. End With
  47. Set Dic = Nothing
  48. Debug.Print Timer - T
  49. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-7-3 13:33 | 显示全部楼层
kevinchengcw 发表于 2024-7-3 09:30
这个试一下,结果写到AC10开始的位置

非常感谢你的帮助For  rang next一个一个效率特别低。

遍历数组,效率很高。使用数组灵活方便。


  1.   For N = LBound(Arr) + 1 To UBound(Arr)
  2.     If Arr(N, 5) <> "" Then
  3.       If Arr(N, 7) = "JPG 文件" Then
  4.         S = ""
  5.         For I = LBound(Arr, 2) To LBound(Arr, 2) + 6
  6.           S = S & vbTab & Arr(N, I)
  7.         Next I
  8.         If Dic.Exists(S) Then
  9.           Stop
  10.           Arr(Dic(S), 8) = Arr(Dic(S), 8) + 1
  11.          
  12.         Else
  13.           R = R + 1: Dic(S) = R
  14.           If R = N Then
  15.             For I = LBound(Arrk) To UBound(Arrk)
  16.               If Arrk(I) = "" Then Arrt(I + 1) = 1 Else Arrt(I + 1) = Arr(N, Arrk(I))
  17.             Next I
  18.             For I = LBound(Arrt) To UBound(Arrt)
  19.               Arr(R, I + 1) = Arrt(I)
  20.             Next I
  21.           Else
  22.             For I = LBound(Arrk) To UBound(Arrk)
  23.               If Arrk(I) = "" Then Arr(R, I + 1) = 1 Else Arr(R, I + 1) = Arr(N, Arrk(I))
  24.             Next I
  25.           End If
  26.         End If
  27.       End If
  28.     End If
  29.   Next N
复制代码





image.png

学习dictonary统计重复数。

image.png

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-17 22:36 , Processed in 0.051489 second(s), 17 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表