Как изменить глобальную переменную книги, активировав макрос из другой книги - PullRequest
3 голосов
/ 19 июня 2019

У меня есть два файла Excel: patcher.xlsm и file.xlsm .На file.xlsm есть кнопка, которая при щелчке выполняет процедуру на листе 1 с окном сообщения: Магическое число: 5 .

СейчасУ меня есть patcher.xlsm , который повторно импортирует пропатченный Лист 1 и Стандартный модуль с глобальной переменной и запускает макрос для file.xlsm , чтобы установить это число в7. Ожидаемый результат таков, что пользователи, нажимающие на file.xlsm , теперь увидят Магическое число: 7 .

По какой-то причине, всякий раз, когда я выполняю patcher.xlsm , магическое число всегда сбрасывается в 0, как будто память очищается или проект сбрасывается.

Есть ли способ назначить глобальную переменную из другой книги?

В прошлом я рассматривал несколько потоков stackoverflow, например, изменяя область действия переменной, private, public, global и т. Д., Активируя книгу, просматривая скрытое пространство имен Excel на данный момент.

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

Лист1 в файле .xlsm

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)

CopyModule of patcher.xlsm

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

GlobalModule of 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

Sheet1 of patcher.xlsm (перезаписывается в file.xlsm)

РЕДАКТИРОВАТЬ: Я изменил проблему.Похоже, что переменная MAGIC_NUMBER повторно инициализируется в «0», хотя строка «GlobalModule.setDefaultMagicNumber» выполнена успешно.

1 Ответ

1 голос
/ 19 июня 2019

Добро пожаловать в SO и Поздравляем с тем, что задали действительно хороший вопрос

Это только частичное решение, а не то, что близко к удовлетворению. Однако я публикую его, так как он каким-то образом послужит вашей цели кода, чтобы изменить Magic_Number на желаемое целое число.

Я испробовал несколько иную настройку с немного другой целью (которая не могла быть достигнута).

In File.Xlsm Workbook Open event

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

В листе 1 Событие изменения 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 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 заканчивается и SetMagic выполняется после задержки при активации File.xlsm. Magic_Number будет 100.

Но это все еще не служит моей предполагаемой цели, поскольку во время испытаний становится очевидным, что Magic_Number сбрасывается в 0, как только строка модуля кода VBE заменяется (т.е. перед выполнением Sub SetMagic). Но ваша цель будет решена, и Magic_Number получит любое значение, которое мы установим от Patch.xlsm.

Поскольку моя цель динамической установки Magic_Number = Magic_Number + 100 не может быть достигнута. Для достижения этой цели мне нужно обойти и сохранить последнее значение Magic_Number, хранящееся в некоторой ячейке и т. Д., И извлечь его оттуда (что приведет к потере истинного духа предназначенного кода)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...