【问题标题】:How to change a global variable of a workbook by activating a macro from another workbook如何通过激活另一个工作簿中的宏来更改工作簿的全局变量
【发布时间】:2019-06-19 08:01:39
【问题描述】:

我有两个 excel 文件,一个 patcher.xlsm 和一个 file.xlsmfile.xlsm 上有一个按钮,当它单击时,它会在工作表 1 上执行一个带有消息框的过程:幻数是:5

现在,我有一个 patcher.xlsm,它将重新导入已修补的 Sheet 1 和一个带有全局变量的标准模块,并在 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”。

【问题讨论】:

  • 将幻数放在外部文件中,而不是尝试在运行中重写 VBA 模块不是更简单吗?
  • @Freeflow 代码的目的是用来修补过时的宏。碰巧某些版本的宏没有特定的模块。外部文件不是一个可行的选择。它肯定会更简单并且开箱即用,但我正在寻找更多的 vba 解决方案。
  • 我的猜测是,如果您更改源代码,那么模块将被重新编译,因此原始代码中设置的任何值都将丢失。据我所见,您在修补代码后没有执行 setmagicnumber 过程,因此您的 getmagicnumber 过程将返回未初始化整数的默认值,即 0。
  • @Freeflow setMagicNumber 在修补模块后调用。我想你提到的内容是有道理的,因为清除内存空间是合乎逻辑的,但是我试图在补丁之后重新分配全局变量但它仍然没有注册,这让我很头疼。

标签: excel vba


【解决方案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

File.Xlsm的Sheet1更改事件中

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 Module1

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 中的宏结束,SetMagicFile.xlsm 激活后延迟执行。 Magic_Number 将为 100。

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

我无法实现动态设置Magic_Number = Magic_Number + 100 的目标。为了达到这个目的,我必须解决并将 Magic_Number 的最新值存储在某个单元格等中并从那里检索(这将失去预期代码的真正精神)

【讨论】:

  • 谢谢@Ahmed!我观察到一件有趣的事情!当我将代码从Application.Run... 修改为Application.OnTime... 时,魔数已成功修改。如果我把它切换回来,幻数会再次重置为 0。不确定这两个 API 有什么区别;绝对不是时间延迟,因为我在Call CopyModule 之后尝试使用Application.Wait...,但它确实有效。
  • Application.wait 应用程序在继续执行下一行代码之前只需等待,而Application.OnTime 计划在未来时间运行目标宏并继续执行剩余代码(在这种情况下它激活@987654342 @and 结束宏在Patch.xlsm)的执行
猜你喜欢
  • 1970-01-01
  • 2019-11-19
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-18
  • 2015-03-15
相关资源
最近更新 更多