我有多个Excel实例来计算问题的不同部分,我希望能够随着每个实例完成的迭代次数来跟踪总进度。如何在Excel实例之间共享变量?
我目前的想法是将这些数字存储在主工作簿的名称管理器中,并让主工作簿将每个名称的值汇总为迭代完成总数的总数。我还尝试通过引用Excel主实例中的隐藏命名空间来尝试相同的概念,如Chip Pearson在此处所述:http://www.cpearson.com/excel/hidden.htm。最终,我努力将跨实例的进度号保存在内存中。我不想写入主Excel实例引用的文件,因为那样会使事情放慢速度。
在Excel的工作实例内部将类似于以下代码,以将其当前进度传送回主工作簿的名称空间:
Dim xlApp As Excel.Application
Set xlApp = GetObject(MasterPath).Application
'The MasterPath is defined as the full path of the master instance: ActiveWorkbook.FullName
With xlApp
.Workbooks(MasterName).Activate
.ActiveWorkbook.Names("Thread_" & i & "_iter").RefersTo = "=" & CStr(i - seqFrom + 1)
End With
上面的代码是给我错误的。它陷入无限循环。当我删除它时,一切都会按预期执行。
在主工作簿中,将显示以下内容,以显示所有实例的总体进度:
For thread = 1 To cThreads
progress_Arr(thread) = CLng(Right(ThisWorkbook.Names("Thread_" & thread & "_iter").RefersTo, Len(ThisWorkbook.Names("Thread_" & thread & "_iter").RefersTo) - 1))
progress = progress + progress_Arr(thread)
Debug.Print "Thread " & thread & ": " & progress_Arr(thread)
Next thread
我最终希望能够在Excel的主实例中编译所有迭代。
答案 0 :(得分:1)
好吧,在我的评论中扩展这里是我准备的粗略测试代码:旋转几个“从属” Excel实例,加载“驱动程序”工作簿的副本(作为只读),然后为每个从属工作簿提供对主工作簿,他们可以用来在LogProgress
对象上调用公用的ThisWorkbook
方法。
在常规模块中:
Option Explicit
Dim col As Collection '<< In the master, stores references to slave application instances
' Not really used here though
'For "slave" workbooks - dummy "do some work" long-running
' routine which periodically reports back
Public Sub DoWork()
Dim n As Long
'kick something off...
For n = 1 To 20
Application.Wait Now + TimeSerial(0, 0, 1)
ThisWorkbook.ReportWork n '<< update master
Next n
End Sub
'Creates slave instances loaded with copies of this workbook
' and a reference to the master workbook, and loads them into "col"
Sub InitSlaves()
Dim x As Long, app
ThisWorkbook.Save
Debug.Print "Master instance", Application.Hwnd
Set col = New Collection
For x = 1 To 5
col.Add XlInstance(ThisWorkbook.FullName)
Next x
End Sub
'Set up and return a new Excel instance
Function XlInstance(wb As String)
Dim app, wkb
Set app = CreateObject("excel.application")
app.Visible = True
Debug.Print "Slave instance", app.Hwnd
Set wkb = app.Workbooks.Open(wb, ReadOnly:=True)
Set wkb.Master = ThisWorkbook
wkb.StartWork
Set XlInstance = app
End Function
在ThisWorkbook
模块中:
Option Explicit
Dim masterWb As Object '<< in a slave workbook, a reference to the master wb
'In a slave workbook, gets a reference to the master workbook
' Note: you *must* use 'As Object' here or you can't call the custom
' methods later (because a "WorkBook"-type doesn't have them)
Public Property Set Master(wb As Object)
Set masterWb = wb
End Property
'Gets called on the slave workbooks from the master
Public Sub StartWork()
Application.OnTime Now, "DoWork"
End Sub
'From a slave, send a message back to the master workbook
Public Sub ReportWork(msg)
masterWb.LogProgress Application.Hwnd, msg
End Sub
'In the master, get a message from a slave workbook
Public Sub LogProgress(id, msg)
Dim m
m = Application.Match(id, Sheet1.Columns(1), 0)
If IsError(m) Then
m = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row + 1
Sheet1.Cells(m, 1).Value = id
End If
Sheet1.Cells(m, 2).Value = msg
End Sub