ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[讨论] 开个贴讨论一下VBA怎样实现多核心处理大量数据(结论发表)

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2012-7-10 21:15 | 显示全部楼层
xiamen168 发表于 2012-7-10 21:13
不错不错,不愧是法师呀!学习了!

不过,另外还有一种方法让VBA也能多核处理,您听说过吗?

你挑逗法师呢?

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-10 21:17 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
liucqa 发表于 2012-7-10 21:15
你挑逗法师呢?

不敢不敢,
百家争鸣,百花齐放而已

TA的精华主题

TA的得分主题

发表于 2012-7-10 21:22 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
xiamen168 发表于 2012-7-10 21:17
不敢不敢,
百家争鸣,百花齐放而已

那你倒是先放一个呀

TA的精华主题

TA的得分主题

发表于 2012-7-10 22:41 | 显示全部楼层
xiamen168 发表于 2012-7-10 21:13
不错不错,不愧是法师呀!学习了!

不过,另外还有一种方法让VBA也能多核处理,您听说过吗?

要我猜的话,VBA里面使用本身可以多线程的控件?
不过我自己没用过。
你要能给个例子就再好不过了,貌似论坛还没有这样的教学帖。

TA的精华主题

TA的得分主题

发表于 2012-7-10 22:53 | 显示全部楼层
本帖最后由 liucqa 于 2012-7-10 22:59 编辑
灰袍法师 发表于 2012-7-10 22:41
要我猜的话,VBA里面使用本身可以多线程的控件?
不过我自己没用过。
你要能给个例子就再好不过了,貌似 ...

VB和VBA的多线程主要有:

1).Active EXE法:

2).创建线程API: APICreateThread


http://club.excelhome.net/thread-281173-1-1.html



TA的精华主题

TA的得分主题

发表于 2012-7-10 23:10 | 显示全部楼层
http://www.m5home.com/bak_blog/article/54.html

微软官方给出的方案在MSDN里面有说,就是使用ActiveX EXE那种"单元线程模型".

我也曾经试过,的确可以实现"多线程",只是由于要多一个EXE,比较麻烦,后来就没有深入了.

结果一次无意中在VBGOOD中看到一段代码,才打通了一个关节:为什么不直接使用ActiveX EXE写程序呢?!

那段代码里面,是直接使用这种工程类型,然后在工程内使用CreateObject来生成一个新对象,这样的话,新的对象就工作于一个单元线程内了.

其实这个我也知道,可是就没有想到在ActiveX EXE内部使用

看来思路真的不如人.....还要多多学习,多多积累.

ActiveX EXE工程设置为"独立启动"后,貌似只能从Sub Main里进行初始化.

而每个对象的建立,都会调用一次这个过程,因此这个过程需要一次性运行.

但是MSDN里说得很清楚,在单元线程模型里面,全局变量的范围只能是本单元,因此不能使用设置全局变量来完成这个过程的一次运行逻辑.

原代码里使用了GetProp等方式,感觉不是很好,于是作了一下改进,使用事件对象来完成此工作.

TA的精华主题

TA的得分主题

发表于 2012-7-10 23:19 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 liucqa 于 2012-7-10 23:20 编辑


http://blog.csdn.net/langkew/article/details/382280#386140

使用Visual Basic 6实现真正实用的多线程处理
分类: Visual Basic 使用技巧 2005-05-27 14:57 1622人阅读 评论(2) 收藏 举报

事实上使用Visual Basic的ActiveX exe技术可以轻松的实现多线程处理.

原理先不说了,先举个示例,有兴趣的话大家可以一起讨论

1.新建一个工程,类型选择ActiveX Exe,工程重命名为TestExe
在工程中添加一个Form,放上一个Timer控件.
将Class1改名为clsTest,注意其Instancing要设置为5-MultiUse, 以下是其代码:

Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private WithEvents oTimer As Timer
Private frmTmp As Form1
Private lTotalLoop As Long
Private bDoStop As Boolean
Private lInterval As Long

Public Event Progress(ByVal lProgress As Long)


Public Sub StartSub(ByVal lTotal As Long)
    lTotalLoop = lTotal
    oTimer.Enabled = True
End Sub

Public Sub StopSub()
    bDoStop = True
End Sub

Private Sub Class_Initialize()
    Set frmTmp = New Form1
    Load frmTmp
    Set oTimer = frmTmp.Timer1
    oTimer.Enabled = False
    bDoStop = False
    lInterval = 1
End Sub

Private Sub DoLoop()
    Dim i As Long
    For i = 0 To lTotalLoop
        Sleep (lInterval)
        RaiseEvent Progress(i)
      
        If bDoStop = True Then
            Exit Sub
        End If
      
    Next
End Sub

Private Sub Class_Terminate()
    Unload frmTmp
    Set frmTmp = Nothing
    Set oTimer = Nothing
End Sub

Private Sub oTimer_Timer()
    oTimer.Enabled = False
    DoLoop
End Sub

Public Property Get lMillisecs() As Long
    lMillisecs = lInterval
End Property

Public Property Let lMillisecs(ByVal vNewValue As Long)
    lInterval = vNewValue
End Property

在TestExe Property(工程属性)的Threading Model中,设置Thread per Object,或者选择Thread pool中设置大于1的数值.如把Thread pool设置为2, 则调用此ActiveX Exe最多能同时有两个线程, 更多的请求将放置于队列中.
编译TestExe

下面来测试我们的多线程程序:

新建一个Standard Exe工程,在Reference中选择刚刚做好的TestExe.exe
在Form1中添加两个ListBox,两个CommandButton,Command1为开始,Command2为停止
以下是Project1.Form1的代码:

Option Explicit
Private WithEvents oTest1 As TestEXE.clsTest
Private WithEvents oTest2 As TestEXE.clsTest

Private Sub Command1_Click()
    Set oTest1 = New TestEXE.clsTest
    oTest1.lMillisecs = 100
    oTest1.StartSub (1000)
   
    Set oTest2 = New TestEXE.clsTest
    oTest2.lMillisecs = 100
    oTest2.StartSub (1000)
End Sub

Private Sub Command2_Click()
    oTest1.StopSub
    oTest2.StopSub
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set oTest1 = Nothing
    Set oTest2 = Nothing
End Sub

Private Sub oTest1_Progress(ByVal lProgress As Long)
    List1.AddItem lProgress
    List1.ListIndex = List1.ListCount - 1
End Sub

Private Sub oTest2_Progress(ByVal lProgress As Long)
    List2.AddItem lProgress
    List2.ListIndex = List2.ListCount - 1
End Sub

启动Project1,点击Command1,怎么样,看见来效果了吗? 试着把TestExe的Thread pool改成1看看会怎么样? 这是我认为最简单且稳固的多线程实现方法了,大家有什么好的想法欢迎留言.

TA的精华主题

TA的得分主题

发表于 2012-7-10 23:25 | 显示全部楼层
本帖最后由 liucqa 于 2012-7-10 23:25 编辑

http://download.csdn.net/download/y369258147/2267598  谁有积分的话,帮下一个

EXCEL VBA多线程研究 DEMO

TA的精华主题

TA的得分主题

发表于 2012-7-11 01:29 | 显示全部楼层
本帖最后由 灰袍法师 于 2012-7-11 01:46 编辑
liucqa 发表于 2012-7-10 23:25 http://download.csdn.net/download/y369258147/2267598  谁有积分的话,帮下一个

EXCEL VBA多线程研究  ...

敬如命
EXCEL VBA多线程研究 DEMO.rar (34.96 KB, 下载次数: 56)
不过这个附件其实就是以下链接的附件( liucqa 在上面的回帖已经发过这个链接了), Stanley Pan 的作品,被转到CSDN而已。。。。。。
http://club.excelhome.net/thread-281173-1-1.html

点评

要是能解决在2007下报错退出的问题就好了  发表于 2012-7-11 07:26

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-11 09:02 | 显示全部楼层
灰袍法师 发表于 2012-7-11 01:29
敬如命

不过这个附件其实就是以下链接的附件( liucqa 在上面的回帖已经发过这个链接了), Stanley Pan ...

高手如云呐!
不过,还有一个思路,那就是EXCEL的内置函数,据说能利用多线程的资源,
这样,把部分VBA关键代码改造成调用内置函数,就可以适当解决问题了。
道听途说没有验证,供大家参考~
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2025-1-9 00:20 , Processed in 0.026461 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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