ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 名课 - Power BI数据分析与可视化实战 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
Python自动化办公应用大全 Excel 2021函数公式学习大典 Kutools for Office 套件发布 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: dtdfex

运行这个宏好慢,远比公式来的慢,为什么?能不能加快处理速度?

[复制链接]

TA的精华主题

TA的得分主题

发表于 2011-12-18 23:04 | 显示全部楼层
本帖最后由 AVEL 于 2011-12-18 23:05 编辑


  1. Sub yy()
  2.     Dim Arr, i&, Arr1, r1, Arr2
  3.     Dim d As Object, d1 As Object
  4.     Dim j As Integer, m As Integer
  5.     Dim brr(1 To 10000, 1 To 64), crr(1 To 10000, 1 To 64)
  6.     Dim n As Integer
  7.     Dim r As Integer
  8.     Myr = Sheet3.[a65536].End(xlUp).Row
  9.     Arr = Sheet3.Range("a1:bo" & Myr)
  10.     Set d = CreateObject("scripting.dictionary")
  11.         Set d1 = CreateObject("scripting.dictionary")
  12.     For i = 2 To UBound(Arr)
  13.         d(Split(Arr(i, 2), "_")(1)) = i
  14.         d1(Arr(i, 2)) = i
  15.     Next
  16.     Arr1 = Sheet1.[c1].Resize(Sheet1.[c65536].End(3).Row)
  17.     Arr2 = Sheet2.[d1].Resize(Sheet2.[d65536].End(3).Row)
  18.     For i = 2 To UBound(Arr1)
  19.         n = n + 1
  20.         If d.exists(CStr(Arr1(i, 1))) Then
  21.             r = d(CStr(Arr1(i, 1)))
  22.             For j = 4 To Arr(r, 3) + 3
  23.                 brr(n, j - 3) = Arr(r, j)
  24.             Next
  25.         End If
  26.     Next
  27.     For i = 2 To UBound(Arr2)
  28.         m = m + 1
  29.         If d1.exists(CStr(Arr2(i, 1))) Then
  30.             r = d1(CStr(Arr2(i, 1)))
  31.             For j = 4 To Arr(r, 3) + 3
  32.                 crr(m, j - 3) = Arr(r, j)
  33.             Next
  34.         End If
  35.     Next
  36.     Sheet2.Range("e2").Resize(m, 64).Value = crr
  37.     Sheet1.Range("k2").Resize(n, 64).Value = brr
  38.     Set d = Nothing: Set d1 = Nothing
  39. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2011-12-18 23:07 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
复件 Book2 11-12-18 23-05.rar (17.52 KB, 下载次数: 35)

TA的精华主题

TA的得分主题

发表于 2011-12-18 23:11 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
{:soso_e120:}有点像邻区列表

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-12-18 23:33 | 显示全部楼层
AVEL 发表于 2011-12-18 23:07

老大,帮把这两个计算分开来吧,我有点晕了。如果我需要一个表一个表的提取呢?学习中,真比公式快很多了,谢谢

TA的精华主题

TA的得分主题

发表于 2011-12-18 23:45 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
  1. Sub tt()
  2.     Dim d As Object, i&, j&, ar, arr()
  3.     Dim s
  4.     Set d = CreateObject("scripting.dictionary")
  5.     ar = Sheet3.Range("b2:bo" & Sheet3.[b65536].End(3).Row)
  6.     For i = 1 To UBound(ar)
  7.         For j = 3 To 66
  8.             s = s & "," & ar(i, j)
  9.         Next
  10.         d(ar(i, 1)) = s
  11.         s = 0
  12.     Next
  13.     ar = Sheet2.Range("d2", Sheet2.[d65536].End(3))
  14.     ReDim arr(1 To UBound(ar), 1 To 64)
  15.     For i = 1 To UBound(ar)
  16.         For j = 1 To 64
  17.             arr(i, j) = Split(d(ar(i, 1)), ",")(j)
  18.         Next
  19.     Next
  20.     Sheet1.[k2].Resize(UBound(arr), 64) = arr
  21. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-12-19 00:38 | 显示全部楼层
本帖最后由 dtdfex 于 2011-12-19 09:53 编辑

{:soso_e181:}{:soso_e183:}
{:soso_e181:}{:soso_e183:}
{:soso_e181:}{:soso_e183:}
{:soso_e181:}{:soso_e183:}

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-12-19 00:42 | 显示全部楼层
本帖最后由 dtdfex 于 2011-12-19 09:52 编辑
AVEL 发表于 2011-12-18 23:07

复件 Book2.rar (6.43 KB, 下载次数: 22)

搞不明白,这个,再请教一下,并说明原因,谢谢!

    Dim r As Integer
    Myr = Sheet4.[a65536].End(xlUp).Row
    arr = Sheet4.Range("a1:bo" & Myr)
    Set d = CreateObject("scripting.dictionary")
        Set d1 = CreateObject("scripting.dictionary")

老大,"a1:bo"是第二行开始的吗?如果我是顶格,哪怎么样用?
提示下标越界。

TA的精华主题

TA的得分主题

发表于 2011-12-19 19:04 | 显示全部楼层
灰袍法师 发表于 2011-12-18 21:59
刚好相反
VBA必然比公式快成百上千倍
楼主的问题在于,写VBA,却调用公式,等于用手推着汽车跑,当然慢 ...

并非所有公式比不上VBA,如求一单元格区域的和:
  1. Sub test()
  2. t = Timer
  3. [b1] = Application.WorksheetFunction.Sum([a1:a1000000])
  4. [e1] = Timer - t
  5. t = Timer
  6. For Each c In Range("a1:a1000000").Value
  7. s = s + c
  8. Next
  9. [b2] = s
  10. [e2] = Timer - t
  11. End Sub
复制代码

一楼慢的原因在于Find、Index和Cells(i, 28).Resize(1, UBound(Arr, 2)) 都是循环操作对象,速度自然慢。同理也适应于工作式,之所以数组公式很慢,原因它是引用大量的单元格,实际上操作对象,而VBA可以尽量地减少操作对象,速度才得以提升。二楼可以说VBA根本未入门。{:soso_e120:}

TA的精华主题

TA的得分主题

发表于 2011-12-19 20:27 | 显示全部楼层
coolboy 发表于 2011-12-18 21:16
VBA必然会比公式慢很多的,能用公式解决的最好不用VBA,
公式的运算编译次数应该比VBA简洁很多,执行效率自 ...

VBA必然会比公式慢很多的,能用公式解决的最好不用VBA
不同意此看法

TA的精华主题

TA的得分主题

发表于 2011-12-19 23:58 | 显示全部楼层
本帖最后由 灰袍法师 于 2011-12-20 00:30 编辑
Zamyi 发表于 2011-12-19 19:04
并非所有公式比不上VBA,如求一单元格区域的和:
一楼慢的原因在于Find、Index和Cells(i, 28).Resize(1, ...

如果把VBA代码做到最优
先声明变量为long或者double,先把多行一列的两维数组转为一行多列的一维数组
VBA代码的速度会快10倍,变成跟调用 application.sum 一样快。
话说,公式也就在这么简单的问题能够跟VBA比一下速度,稍微复杂的问题,速度就差远了。
Option Explicit

Sub 按钮1_Click()
Dim t, c As Double, s As Double, arr, arr2() As Double, i As Long

t = Timer

[b1] = Application.WorksheetFunction.Sum([a1:a1000000])

[e1] = Timer - t

arr = Range("a1:a1000000").Value
ReDim arr2(1 To 1000000)
For i = 1 To 1000000
arr2(i) = arr(i, 1)
Next i
t = Timer

For i = 1 To 1000000

s = s + arr2(i)

Next

[b2] = s

[e2] = Timer - t

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

本版积分规则

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

GMT+8, 2025-12-22 22:36 , Processed in 0.030475 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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