在多个Excel实例之间共享变量

在多个Excel实例之间共享变量,excel,vba,Excel,Vba,我有多个Excel实例来计算问题的不同部分,我希望能够跟踪总进度,作为每个实例完成的迭代次数。如何在Excel实例之间共享变量 我目前的想法是将这些数字存储在主工作簿的名称管理器中,并让主工作簿将每个名称的值汇总为完成迭代的总次数。我还尝试了相同的概念,引用了Chip Pearson在这里描述的Excel主实例中的隐藏名称空间:。最终,我在努力将各个实例的进度数字保存在内存中。我不想写入一个主Excel实例引用的文件,因为这样会大大降低速度 Excel工作实例的内部类似于以下代码,用于将其当前进

我有多个Excel实例来计算问题的不同部分,我希望能够跟踪总进度,作为每个实例完成的迭代次数。如何在Excel实例之间共享变量

我目前的想法是将这些数字存储在主工作簿的名称管理器中,并让主工作簿将每个名称的值汇总为完成迭代的总次数。我还尝试了相同的概念,引用了Chip Pearson在这里描述的Excel主实例中的隐藏名称空间:。最终,我在努力将各个实例的进度数字保存在内存中。我不想写入一个主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的主实例中编译所有迭代。

好的,根据我的评论,这里是我的粗略测试代码:启动几个“从属”Excel实例,加载“驱动程序”工作簿的副本(只读),然后给每个从属工作簿一个主工作簿的引用,他们可以使用它调用
ThisWorkbook
对象上的公共
LogProgress
方法

在常规模块中:

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

无论进度条显示的数据来源如何,进度条的机制(如各种教程中所示)都应该是相同的。为什么不在最后一个循环中累积迭代计数的总和,然后更新条呢?还有——纯素狼吃什么?这不是我所关注的进度条。它收集所有Excel实例的进度。我将在帖子中澄清这一点。素食狼吃豆腐。很难想象写入一个文件(或每个实例一个文件)会真的减慢速度,除非你计划非常频繁地更新。每次迭代都会在1000-5000次之间写入一个文件并保存,以便主人可以读取。我想减少这个数字的一种方法是说,每5次迭代只写一次,但即使这样,似乎还是要写很多文件,不是吗?写一个文件相当快。。。但是,如果使用CreateObject创建其他实例,则可以使用工作簿对象上的公共方法传递消息,只要在每个“从属”工作簿中放置对主工作簿的引用。
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