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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (33)

我有两个excel文件,一个patcher.xlsm和一个file.xlsmfile.xlsm上有一个按钮,当它点击它时会在Sheet 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的GlobalModule

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”。

提问于
用户回答回答于

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

这只是一个部分解决方案,而不是任何接近满意的地方。但是我发布它,因为它会以某种方式服务于你的代码目的,将Magic_Number更改为某个所需的整数。

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

File.XlsmWorkbook Open事件中

Private Sub Workbook_Open()
SetMagic
End Sub

在模块1中 File.Xlsm

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.xlsmModule1中

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的最新值存储在某些单元格等中并从那里检索(这将松散真正的代码精神)

扫码关注云+社区

领取腾讯云代金券