如何通过激活另一个工作簿中的宏来更改工作簿的全局变量

时间:2019-06-19 08:01:39

标签: excel vba

我有两个Excel文件,一个 patcher.xlsm 和一个 file.xlsm 。在 file.xlsm 上有一个按钮,单击该按钮会在工作表1上执行以下过程,并显示以下消息框:幻数是:5

现在,我有一个 patcher.xlsm ,它将重新导入修补程序的Sheet 1和带有全局变量的Standard模块,并在 file.xlsm 上运行宏>将此数字设置为7。预期结果是,用户单击 file.xlsm 时,现在会看到魔术数字是:7

由于某种原因,每当我执行 patcher.xlsm 时,幻数始终会重置为0,就像内存已清除或项目重置一样。

是否可以从其他工作簿中分配全局变量?

过去,我查看了几个stackoverflow线程,例如,更改变量的范围,私有,公共,全局等,激活工作簿,查看Excel当前隐藏的名称空间。

Sub Proc()
  MsgBox "The magic number is: 5"
End Sub

file.xlsm中的Sheet1

Call CopyModule("patcher_b_progress_bar.xlsm", "file_b.xlsm", "Sheet1", True)
Call CopyModule("patcher_b_progress_bar.xlsm", "file_b.xlsm", "GlobalModule", True)
Application.Run ("'file_b.xlsm'!GlobalModule.setDefaultMagicNumber")

patcher.xlsm“修补”工作表1并通过模块设置幻数

CopyModule 
' export "patched GlobalModule" from patcher.xlsm as temp.bas
' remove GlobalModule from file.xlsm
' re-import "patched GlobalModule" to file.xlsm
(too lengthy to post here, referenced from http://www.cpearson.com/excel/vbe.aspx)

patcher.xlsm的CopyModule

Option Explicit

Private MAGIC_NUMBER As Integer

Public Function getMagicNumber() As Integer
    getMagicNumber = MAGIC_NUMBER 
End Function

Public Function setDefaultMagicNumber() As Integer
    MAGIC_NUMBER = 7
    setDefaultMagicNumber= getMagicNumber()
End Function

patcher.xlsm的全局模块

Sub Proc()
  If GlobalModule.getMagicNumber= 7 Then
    MsgBox "Magic number is correct: " & GlobalModule.getMagicNumber
  Else
    MsgBox "Magic number is wrong: " & GlobalModule.getMagicNumber
  End If
End Sub

patcher.xlsm的Sheet1(将被覆盖到file.xlsm)

编辑:我已经修改了该问题。即使成功执行了“ GlobalModule.setDefaultMagicNumber”行,变量MAGIC_NUMBER似乎仍重新初始化为“ 0”。

1 个答案:

答案 0 :(得分:1)

欢迎来到SO,并祝贺您提出了一个真正的好问题

这仅是部分解决方案,根本不满足。但是,我将其发布,因为它将以某种方式满足您将Magic_Number更改为所需整数的代码的目的。

我尝试了一些目的稍有不同的设置(无法实现)。

File.Xlsm工作簿打开事件中

Private Sub Workbook_Open()
SetMagic
End Sub

File.Xlsm的Module1中

Global Magic_Number As Integer
Sub Test_Magic()
MsgBox Magic_Number
End Sub

Sub SetMagic()
Magic_Number = 5
ThisWorkbook.Sheets(1).Range("F1").Value = Magic_Number
End Sub

在Sheet1的File.Xlsm更改事件中

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Range("A1:E20"), Target) Is Nothing Then
    Magic_Number = Magic_Number + 1
    Range("F1").Value = Magic_Number
    End If
End Sub

最后进入Patch.xlsm模块1

Sub ChangeMagic()
Dim wb As Workbook, Opn As Boolean , Ln as Long
    Onp = False
    For Each wb In Application.Workbooks
    If wb.Name = "File.xlsm" Then
    Opn = True
    Exit For
    End If
    Next

    If Opn = False Then
    Set wb = Workbooks.Open(ThisWorkbook.Path & "\File.xlsm")
    End If


    With wb.VBProject.VBComponents("Module1").CodeModule
    Ln = .ProcBodyLine("SetMagic", vbext_pk_Proc)
    .ReplaceLine Ln + 1, "Magic_number =  100"
    End With

    Application.OnTime Now + TimeValue("00:00:03"), "'File.xlsm'!Module1.SetMagic"
    wb.Activate
End Sub

Application.OnTime Now + TimeValue("00:00:03"), "'File.xlsm'!Module1.SetMagic"

绝招。替换了VBE中的所需代码行后,Patch.xlsm中的宏结束,并且SetMagic在激活File.xlsm之后经过延迟后被执行。 Magic_Number将为100。

但是它仍然没有达到我的预期目的,因为在试用期间,很明显,一旦替换了VBE代码模块行(即在执行Sub SetMagic之前),Magic_Number就会重置为0。但是您的目的将得到解决,Magic_Number将获得我们从Patch.xlsm设置的任何值。

出于我的目标,无法动态设置Magic_Number = Magic_Number + 100。为了实现该目的,我必须变通解决,并将Magic_Number的最新值存储在某些单元格等中,然后从那里进行检索(这将使所设计代码的真实精神丧失)