Background
I am developing a VBA module (call it "Greg
") for VBA developers of Excel UDFs. The purpose of Greg
is to enhance the experience for the end user, who uses those UDFs in Excel.
我正在为Excel UDF的可扩展性开发人员开发一个可扩展性模块(称之为“Greg”)。Greg的目的是增强在Excel中使用这些UDF的最终用户的体验。
The developer must simply copy a snippet into their own module (call it "Dev
"). If Greg
is loaded, the snippet enhances Dev
's behavior. Otherwise, it has no impact on behavior, but it does prompt the Excel user to import Greg.bas
.
开发人员只需将一个代码片段复制到他们自己的模块中(称为“Dev”)。如果加载了Greg,则代码片段将增强Dev的行为。否则,它不会影响行为,但会提示Excel用户导入Greg.bas。
Approach
Here is a simplified sketch of Greg.bas
...
这是Greg.bas的简化草图..。
Attribute VB_Name = "Greg"
' Keep these functions invisible to Excel users.
Option Private Module
' Enhancement function.
Public Function Enhancer(Optional x)
' ...
End Function
' Assert the 'Greg' module is loaded.
Public Function IsLoaded() As Boolean
IsLoaded = True
End Function
...and of Dev.bas
:
...关于Dev.bas:
Attribute VB_Name = "Dev"
' Some UDF by the dev.
Public Function DevRegular()
' ...
End Function
' #############
' ## Snippet ##
' #############
' Use the enhancer, if available via the 'Greg' module.
Public Function DevEnhanced(Optional x)
If Enhance_IsSupported() Then
DevEnhanced = Greg.Enhancer(x)
Else
DevEnhanced = DevRegular()
' Prompt the user to import the enhancer.
MsgBox "Import the 'Greg' module to enhance your experience."
End If
End Function
' Check if enhancement is supported via the 'Greg' module.
Private Function Enhance_IsSupported() As Boolean
On Error GoTo Fail
Enhance_IsSupported = Greg.IsLoaded()
Exit Function
Fail:
Enhance_IsSupported = False
End Function
Problem
While this has worked sporadically on Windows, it has often failed there and always on Mac. The crux seems to be Enhance_IsSupported()
within Dev
:
虽然这在Windows上偶尔奏效,但在Windows上经常失败,在Mac上总是失败。问题的关键似乎是开发环境中的Enhance_IsSupport():
Private Function Enhance_IsSupported() As Boolean
On Error GoTo Fail
Enhance_IsSupported = Greg.IsLoaded()
Exit Function
Fail:
Enhance_IsSupported = False
End Function
I assumed that the line Greg.IsLoaded()
would compile, even if there were no Greg
module present...and it does! It only fails when a Greg
module exists without a member called IsLoaded()
.
我假设Greg.IsLoaded()行可以编译,即使没有Greg模块.而且确实如此只有当Greg模块没有名为IsLoaded()的成员时,它才会失败。
Unfortunately, it seems that VBA does not reliably refresh its "awareness" of a Greg
module with an IsLoaded()
function.
不幸的是,VBA似乎不能可靠地用IsLoaded()函数刷新它对Greg模块的“感知”。
When I import Greg.bas
and Dev.bas
together, everything works as intended: Enhance_IsSupported()
returns True
, and it updates to False
if Greg
is removed.
当我同时导入Greg.bas和Dev.bas时,一切都按预期进行:Enhance_IsSupport()返回True,如果删除了Greg,则更新为False。
But when I first import Dev.bas
and run DevEnhanced()
, and only afterwards import Greg.bas
, then Enhance_IsSupported()
apparently returns False
despite the presence of Greg
.
但是,当我第一次导入Dev.bas并运行DevEnhanced(),然后才导入Greg.bas时,尽管存在Greg,但Enhance_IsSupport()显然返回FALSE。
Note
This latter workflow is absolutely essential: an Excel user must first run DevEnhanced()
and see the prompt, in order to know about Greg.bas
in the first place!
后一种工作流程是绝对必要的:Excel用户必须首先运行DevEnhanced()并查看提示,才能首先了解Greg.bas!
Failed Solutions
Unfortunately, no experimentation has availed. In Greg
itself, I have tried using a constant...
不幸的是,没有任何实验是有用的。在Greg本身中,我尝试使用一个常量...
Public Const IS_LOADED As Boolean = True
...and also a procedure:
...还有一个程序:
Public Function IsLoaded() As Boolean
IsLoaded = True
End Function
In the snippet for Dev
, I have implicitly tried Application.Evaluate()
...
在Dev的代码片段中,我隐式尝试了Application.Evalate()...
Private Function Enhance_IsSupported() As Boolean
On Error GoTo Fail
Enhance_IsSupported = [Greg.IsLoaded()]
' ^^^^^^^^^^^^^^^^^
' Application.Evaluate("Greg.IsLoaded()")
Exit Function
Fail:
Enhance_IsSupported = False
End Function
...but while this works for Enhance_IsSupported()
itself, the same error simply crops up elsewhere — like whack-a-mole at other instances of Greg.*
— and only a manual edit will "refresh" those procedures. I would also prefer to avoid unstable calls to any .Evaluate()
method, even in the Worksheet
scope.
但是,虽然这对Enhance_IsSupport()本身有效,但相同的错误只是在其他地方突然出现-就像在Greg.*的其他实例中打鼹鼠一样-并且只有手动编辑才会“刷新”这些过程。我还希望避免对任何.Evalate()方法进行不稳定的调用,即使在工作表范围内也是如此。
Questions
- What is the simplest way to "refresh" the
Dev
module, such that its procedures now recognize the calls to Greg.*
?
- Is this possible without resetting cached or
Static
variables in Dev
?
- Can this be done with an
IS_LOADED
constant rather than an IsLoaded()
procedure?
Bonus
- Can this refreshment be done by some
Sub
like Dev.Refresh()
, called automatically at the start of Enhance_IsSupported()
?
- Can this refreshment be done by some
Sub
like Greg.Refresh()
, as run manually by the user in the VBA editor?
This project represents a great investment of my time and energy, and it is otherwise operational, so your help is greatly appreciated in conquering this final obstacle!
这个项目代表了我时间和精力的巨大投入,而且它是可操作的,所以非常感谢您在克服这最后一个障碍方面的帮助!
更多回答
Maybe using a solution using the Microsoft VBA Extensibility 5.3 library. I.e. Use the Extensibity library to search if the module exists etc.
也许使用使用Microsoft VBA Extensive5.3库的解决方案。即使用Extensibity库搜索模块是否存在等。
@M.Johnstone Regarding the Extensibility library, I'd prefer to keep things terminally simple for the Excel user. Mind you, the Dev
UDFs are what they really want in Excel, so enhancing Dev
should require minimal effort and expertise in VBA.
@M.Johnstone关于可扩展性库,我更愿意让Excel用户的事情变得非常简单。请注意,开发人员的UDF才是他们在Excel中真正想要的,因此增强开发人员应该只需要最少的工作和VBA方面的专业知识。
Is simply adding it to project references not an option?
简单地将其添加到项目引用中不是一种选择吗?
@VictorK "Is simply adding it to project references not an option?" I've lightly explored this, and it would seem the most elegant and user-friendly solution. But when I go to Tools » References... » Browse... in the VBA editor, my only options are *.olb
and *.tlb*
and *.dll
. How would I make available a .bas
module like Greg.bas
?
@VictorK“只是将其添加到项目引用中,而不是一个选项吗?”我稍微研究了一下,它似乎是最优雅和用户友好的解决方案。但是当我转到工具和参考时...?浏览...在VBA编辑器中,我的唯一选项是*.olb、*.tlb*和*.dll。我如何提供像Greg.bas这样的.bas模块呢?
@Greg I would suggest the following approach ( I use it for all my projects): create an .xlam
file (Excel add-in) and add Greg.bas
to that file. Bonus points: save a read-only production version in a place that users can reach, for example on an network drive (read this answer for an example). Then go to Tools >> Reference >> Browse, change options to Microsoft Excel Files
, find you .xlam
file and click Open
. Once .xlam
file is added as a reference all of its Public
functions/classes will be available (with some caveats).
@Greg我会建议以下方法(我在我的所有项目中都使用它):创建一个.xlam文件(Excel加载项),并将Greg.bas添加到该文件中。加分:将只读生产版本保存在用户可以到达的地方,例如在网络驱动器上(请阅读此答案以获取示例)。然后转到工具>>参考>>浏览,将选项更改为Microsoft Excel文件,找到您的.xlam文件并单击打开。一旦将.xlam文件添加为引用,它的所有公共函数/类都将可用(但有一些警告)。
The issue here is that the reference to the other module is stale. To update it you need the module to recompile.
这里的问题是对另一个模块的引用是过时的。要更新它,您需要重新编译模块。
Based on my experimentations, the VBE won't recompile the code in the module if there were no changes since the last compilation. And as you noticed, importing a VBA module with the manual method (Menu Bar > File > Import File > *Select file in dialog window*), won't trigger a recompilation of the other modules in the project.
根据我的实验,如果自上次编译以来没有任何更改,则VBE不会重新编译模块中的代码。正如您注意到的,使用手动方法(菜单栏>文件>导入文件>*在对话框窗口中选择文件*)导入VBA模块不会触发项目中其他模块的重新编译。
Editing the line with the reference to the optional module (Greg
) will force a recompilation of that specific function/sub. The function Enhance_IsSupported()
should then return True
as expected.
编辑引用可选模块(Greg)的行将强制重新编译该特定函数/子函数。然后,函数Enhance_IsSupport()应该如预期那样返回True。
Adding or removing a member of the module
添加或删除模块的成员
Another way of doing it is to add/remove a sub or module level variable/constant which causes the whole module to recompile. Knowing that, you could have a private variable at the top that could be quickly deleted manually to achieve this. Eg.:
另一种方法是添加/删除子或模块级别的变量/常量,这会导致整个模块重新编译。知道这一点后,您可以在顶部设置一个私有变量,可以手动快速删除该变量来实现这一点。例如:
Private DELETE_ME_TO_COMPLETE_GREG_INSTALLATION As Boolean
Since your user will be using the VBE to import the module (Greg) manually anyway, it doesn't seem too much to ask them to delete a row at the top of the Dev module.
由于您的用户无论如何都将使用VBE手动导入模块(Greg),因此要求他们删除Dev模块顶部的一行似乎并不过分。
Exporting and re-importing the module with stale references
导出并重新导入带有过时引用的模块
Exporting the content of the Dev module to a .bas file and re-importing it is another was to force the recompilation and that can also be done manually with the VBE interface.
将Dev模块的内容导出到.bas文件并重新导入是另一种强制重新编译的做法,这也可以通过VBE接口手动完成。
My initial approach to make this more automated was to just export and re-import the Dev module with a VBA procedure. However this requires the user to have "Trust access to the VBA project object model" (VBOM access) enabled.
我最初的方法是使用VBA过程导出并重新导入开发人员模块,使其更加自动化。但是,这需要用户启用“信任访问VBA项目对象模型”(vbom访问)。
I saw in one of your comments that you cannot make the users enable that, so this won't solve your issue, but I'm just going to include the code here in case this is useful to someone.
我在您的一条评论中看到,您不能让用户启用它,所以这不会解决您的问题,但我将在这里包含代码,以防这对某人有用。
Sub ResetModule()
With ThisWorkbook.VBProject.VBComponents
'Optional: Delete all module copies (Dev1, Dev2, etc.)
On Error Resume Next
Dim i As Long
For i = 1 To 100
.Remove .Item("Dev" & i)
If Err.Number <> 0 Then
Exit For
End If
Next
On Error GoTo 0
Dim ModuleTempLocation As String
ModuleTempLocation = ThisWorkbook.Path & Application.PathSeparator & "Dev.bas"
'Export and remove module
Dim md As Object 'CodeModule
Set md = .Item("Dev")
md.Export ModuleTempLocation
'Change name to avoid potential naming conflicts
md.Name = md.Name & "_OLD"
.Remove md
'Re-import module
.Import ModuleTempLocation
Kill ModuleTempLocation
End With
End Sub
Using the Insert File feature
使用插入文件功能
It turns out that even if the regular Import file feature doesn't cause project-wide recompilation, the Insert File feature does. This feature can be used while a module is selected in the Project Explorer (make sure the module window is visible by double-clicking it). To use it, go Menu Bar > Insert > File... > *Select file in dialog window*.
事实证明,即使常规的导入文件功能不会导致项目范围的重新编译,插入文件功能也会。当在Project Explorer中选择一个模块时,可以使用该特性(确保通过双击该模块窗口是可见的)。要使用它,请转到菜单栏>插入>文件...>*在对话框窗口中选择文件*。
This feature can be used to load content from a .bas file to a module even if it already has some procedures in it. And for some reason, this forces a recompilation of the whole project.
此功能可用于将.bas文件中的内容加载到模块中,即使该模块中已包含一些过程。出于某种原因,这迫使重新编译整个项目。
Knowing that you could tell your users to insert a new module, select it and use the Insert File feature to insert the content of Greg. This way you'll be sure that Dev will recompile.
知道您可以告诉您的用户插入一个新模块后,选择它并使用Insert File特性来插入Greg的内容。这样,您就可以确保Dev将重新编译。
Otherwise, you can always let them add the module with the Import File method and add a TriggerRecompilation()
sub to recompile the project using the VBA equivalent of the Insert File method.
否则,您始终可以让他们使用导入文件方法添加模块,并添加TriggerRecompilation()SUB,以使用与Insert文件方法等效的VBA重新编译项目。
Basically, calling .InsertFile
on a Module object seems to be the same as inserting a file from the GUI. It also causes a recompilation of the project and to make use of this, we can create a fictitious .bas
file; import it; and delete it.
基本上,在模块对象上调用.InsertFile似乎与从图形用户界面插入文件相同。它还会导致重新编译项目,为了利用这一点,我们可以创建一个虚构的.bas文件;导入它;然后删除它。
For example:
例如:
Sub TriggerRecompilation()
'Create fictitious .bas file
Dim FilePath As String
FilePath = ThisWorkbook.Path & Application.PathSeparator & "ForceRecompilation.bas"
Open FilePath For Output As #1
Print #1, "Attribute VB_Name = ""ForceRecompilation"""
Close #1
'Import and delete module
Dim ThisModule As Module
Set ThisModule = ThisWorkbook.Modules.Add
ThisModule.InsertFile FilePath
Application.DisplayAlerts = False
ThisModule.Delete
Application.DisplayAlerts = True
Set ThisModule = Nothing
Kill FilePath
End Sub
There might be a simpler method with VBA to force a recompilation, but that's the only consistent approach I could find that doesn't involve having VBOM access enabled.
使用VBA可能有一种更简单的方法来强制重新编译,但这是我所能找到的唯一不涉及启用vbom访问的一致方法。
I've got to say, I don't understand how someone could include a reference to a module in their project and forget to include the module itself, so this whole problem doesn't make any sense to me. But here is a possible solution. The only problem that I can think of in using this is that it requires a reference to VBA Extensibility.
我不得不说,我不明白为什么有人会在他们的项目中包括对模块的引用,却忘记了包括模块本身,所以整个问题对我来说没有任何意义。但这里有一个可能的解决方案。我在使用它时能想到的唯一问题是,它需要引用VBA可扩展性。
Function ThisProjectIncludesModuleGreg() As Boolean
'This routine require a reference to "Microsoft Visual Basic for Applications Extensibility".
Dim n As Long
With ThisWorkbook.VBProject.VBComponents
For n = 1 To .Count
With .Item(n)
If .Type = 1 And .name = "Greg" Then
ThisProjectIncludesModuleGreg = True
Exit Function
End If
End With
Next
End With
End Function
You already mentioned a constant, why not:
你已经提到了一个常量,为什么不:
in module Greg:
Public Const GREG_IS_LOADED = True
在模块Greg中:公共常量Greg_is_Load=True
and in module dev:
在模块dev中:
' Use the enhancer, if available via the 'Greg' module.
Public Function DevEnhanced(Optional x)
#If GREG_IS_LOADED Then
'If Enhance_IsSupported() Then
DevEnhanced = Greg.Enhancer(x)
#Else
'Else
DevEnhanced = DevRegular()
' Prompt the user to import the enhancer.
MsgBox "Import the 'Greg' module to enhance your experience."
'End If
#End If
End Function
I expected the #If-lines to be recompiled after a module was added. Obviously that does not work correctly.
我原以为添加模块后会重新编译#if-line。显然,这并不能正常工作。
What Office tool are you using?
I've tested the code below in Excel.
您使用的是什么Office工具?我已经在Excel中测试了下面的代码。
Public Function IsGregLoaded() As Boolean
Dim o As Object
IsGregLoaded = False
For Each o In ActiveWorkbook.VBProject.VBComponents
'Debug.Print o.Type, o.Name
If o.Name = "Greg" And o.Type = 1 Then
IsGregLoaded = True
Exit Function
End If
Next
End Function
In msaccess it would be:
在MSAccess中,它将是:
For Each o In Application.CurrentProject.AllModules
If o.Name = "Greg" And o.Type = 5 Then
But in msaccess, both a code module and a class module have type 5
但在MSAccess中,代码模块和类模块都具有类型5
EDITED:
编辑:
Public Function IsGregLoaded()
IsGregLoaded = False
On Error Resume Next
Application.Run "Greg.IsLoaded()"
If Err.Number = 0 Then
MsgBox "'Greg' module is present."
IsGregLoaded = True
Else
MsgBox "'Greg' module is NOT present."
End If
End Function
更多回答
Thank you for all your work and effort on this! In particular, I appreciate you taking care to address the criteria in my question, and to do so in depth. I will test your TriggerRecompilation()
solution very soon, and in the meantime, the manual method is an acceptable fallback solution, whose GUI nature is manageable for even VBA laity: remove Dev
, and opt to export it as Dev.bas
; then import that Dev.bas
back into the workbook.
感谢您在这方面所做的所有工作和努力!我特别感谢你认真地回答了我问题中的标准,并深入地这样做。我将很快测试您的TriggerRecompilation()解决方案,同时,手动方法是一种可接受的后备解决方案,其图形用户界面性质即使对于VBA也是可管理的:删除Dev,并选择将其导出为Dev.bas;然后将该Dev.bas导入回工作簿。
But TriggerRecompilation()
does leave me with a burning question: if inserting a new module were enough to trigger recompilation, why doesn't it do so already, when one imports Greg.bas
itself? Or is that only when .InsertFile
specifically is used to import it?
但是TriggerRecompilation()确实给我留下了一个棘手的问题:如果插入一个新模块就足以触发重新编译,那么当您导入Greg.bas本身时,它为什么还没有这样做呢?或者只有在专门使用.InsertFile来导入它的情况下才这样做?
@Greg "why doesn't it do so already, when one imports Greg.bas itself?" -- that's a mystery for me as well.
@Greg“当一个人导入Greg.bas本身的时候,它为什么还没有这样做呢?”--这对我来说也是一个谜。
Good catch! Yeah, this explanation makes a lot of sense and it's consistent with the beginning of my answer regarding editing existing modules. I'll edit my answer to reflect this new information when I have the time.
接得好!是的,这个解释很有意义,它与我关于编辑现有模块的回答的开头是一致的。当我有时间时,我会编辑我的答案以反映这一新信息。
@Greg - Regarding the compatibility with Mac, you could always use ThisWorkbook.Path
instead of Environ("TEMP")
. But then you might also want to do Kill FilePath
at the end of TriggerRecompilation()
to delete the .bas file as well.
@Greg -关于与Mac的兼容性,您可以始终使用ThisWorkbook.Path而不是Environ(“TEMP”)。但是,您可能还希望在TriggerRecompilation()结束时执行Kill FilePath,以删除.bas文件。
You don't need the "VBA Extensibility". With ThisWorkbook.VBProject.VBComponents
is just fine.
您不需要“VBA可扩展性”。使用ThisWorkbook.VBProject.VBComponents就可以了。
@JohnWilliams "I don't understand how someone could include a reference to a module in their project and forget to include the module itself". It's possible I lack some understanding of project management in VBA. However, the idea is relatively straightforward, and I will set it out in the comment below:
@JohnWilliams“我不明白为什么有人会在他们的项目中包括对模块的引用,却忘记了包括模块本身”。可能我对VBA中的项目管理缺乏一些了解。然而,这个想法相对简单,我将在下面的评论中列出:
(1) The Excel user wishes to use some Dev
UDFs, so they import Dev.bas
into the project. As of now, they remain unaware of Greg
. (2) The Excel user runs DevEnhanced()
, which defaults to the DevRegular()
value, and sees the prompt "Import the 'Greg' module to enhance your experience.
". (3) The Excel user visits the "Greg" repo (on GitHub) to download Greg.bas
, and imports it into the project. (4) The Excel user runs DevEnhanced()
, which should now return the value from Greg.Enhancer()
. Alas, it errors instead.
(1)Excel用户希望使用一些Dev自定义项,因此将Dev.bas导入到工程中。到目前为止,他们仍然不知道格雷格。(2)Excel用户运行DevEnhanced(),默认为DevRegular()值,并看到“导入‘Greg’模块以增强您的体验”的提示。(3)Excel用户访问GitHub上的Greg资源库下载Greg.bas,并导入到工程中。(4)Excel用户运行DevEnhanced(),它现在应该从Greg.Enhancer()返回值。遗憾的是,它反而出错了。
Hi @hennep, thanks for suggesting an answer! But is this both dynamic and stable? I don't think the precompiled #If
will update to the #Else
once Greg
is imported. In fact, this seems less dynamic than my current solution, which at least updates at runtime when Greg
is removed. Furthermore, we cannot guarantee the nonexistence of a clashing GREG_IS_LOADED
constant in Dev
itself or in a different module entirely. By contrast, the syntax Greg.IsLoaded()
or Greg.IS_LOADED
is entirely unambiguous: a unique member of the Greg
module.
嗨@hennep,谢谢你的建议!但这是既动态又稳定的吗?我不认为一旦导入Greg,预编译的#if就不会更新为#Else。事实上,这似乎没有我目前的解决方案那么动态,我目前的解决方案至少在Greg被移除时在运行时更新。此外,我们不能保证在Dev本身或完全不同的模块中不存在冲突的Greg_is_Load常量。相比之下,语法Greg.IsLoaded()或Greg.IS_LOADED是完全明确的:它是Greg模块的唯一成员。
@Greg That my first idea as well using a compiler constant. Maybe using the a solution using the Microsoft VBA Extensibility 5.3 library.
@Greg,这也是我的第一个想法,使用编译器常量。也许可以使用使用Microsoft VBA Extensive5.3库的解决方案。
@M.Johnstone Is it really compilation that's the issue? In my experience, everything compiles just fine, even when Greg
is entirely absent as a module. My problem is that, when Greg.bas
is imported after running Dev.Enhance_IsSupported()
, then the Greg.*
references do not update. Nonetheless, when Greg
is initially present, then Dev.Enhance_IsSupported()
successfully returns True
, and after Greg
is removed it successfully returns False
. So the only issue is "updating" in one direction: when Greg
is initially absent and then imported later.
@M.Johnstone:这真的是编译的问题吗?根据我的经验,一切都编译得很好,即使Greg完全不是一个模块。我的问题是,当在运行Dev.Enhance_IsSupport()之后导入Greg.bas时,Greg.*引用不会更新。尽管如此,当Greg最初存在时,Dev.Enhance_IsSupport()会成功返回True,而在Greg被删除后,它会成功返回False。因此,唯一的问题是向一个方向“更新”:格雷格最初不在,后来又被导入。
@M.Johnstone Perhaps I should rework Greg
as a class, whose objects can be late-bound after construction: first Set grg = CreateObject("Greg")
and then grg.Enhancer()
. Then Enhance_IsSupported()
will simply test CreateObject("Greg")
and catch any error as False
.
@M.Johnstone也许我应该将Greg重新定义为一个类,它的对象可以在构造后后期绑定:首先设置GRG=CreateObject(“Greg”),然后设置grg.Enhenger()。然后,Enhance_IsSupport()将简单地测试CreateObject(“Greg”),并将任何错误捕获为False。
Apologies, I should have mentioned: this is for Excel. I did consider the VBProject
module in the past, but I cannot (and should not) force the user to fully trust the Dev
module, enough to grant it access to the VBProject
model. For a programmatic approach, my best bet is probably late-binding with a Greg
object, imported via Greg.cls
. But really, I'm just looking for an easy (manual?) trick in the VBA editor for Excel, which "refreshes" the project to recognize references to Greg.*
. Closing and reopening, perhaps?
抱歉,我应该提一下:这是给Excel的。我过去确实考虑过VBProject模块,但我不能(也不应该)强迫用户完全信任Dev模块,足以授予它对VBProject模型的访问权限。对于编程方法,我最好的选择可能是使用通过Greg.cls导入的Greg对象进行后期绑定。但说真的,我只是在找一本简单的(手册?)用于Excel的VBA编辑器中的技巧,它“刷新”项目以识别对Greg.*的引用。也许是关门再重新开张?
@Greg, With Application.Run there is no syntax check compile time. See the addition in my answer. Normally you'll get an error when the module does not exist.
@greg,with Application.Run没有语法检查编译时间。请看我答案中的加法。通常情况下,当模块不存在时会出现错误。
"With Application.Run there is no syntax check compile time. See the addition in my answer." I'm afraid I already tried this. See my Failed Solutions section. While Enhance_IsSupported()
itself now works, the DevEnhanced()
function fails. It fails specifically because Enhance_IsSupported()
succeeds and returns True
, and DevEnhanced()
flows to the conditional where Greg.Enhancer(x)
then fails—the Greg.*
syntax has not "refreshed" in DevEnhanced()
.
“使用Application.Run没有语法检查编译时间。请参阅我的答案中的加法。”恐怕我已经试过了。请参阅我失败的解决方案部分。虽然Enhance_IsSupport()本身现在可以工作,但DevEnhanced()函数失败了。它之所以失败,特别是因为Enhance_IsSupported()成功并返回True,并且DevEnhancedTM()流到条件函数,而Greg.Enhenger(X)随后失败--在DevEnhancedTM()中,greg.*语法没有“刷新”。
"Normally you'll get an error when the module does not exist." My original Enhance_IsSupported()
accounted for this—and indeed relied on it. Hence the On Error GoTo Fail
. My problem comes when the module does exist, specifically when imported only after DevEnhanced()
— and by extension Enhance_IsSupported()
— have already run.
“通常情况下,当模块不存在时,您会收到错误。”我最初的Enhance_IsSupport()说明了这一点--并且确实依赖于它。因此,On Error Goto Failure。当模块确实存在时,我的问题就出现了,特别是在DevEnhanced()--扩展到Enhance_IsSupported()--已经运行之后才导入的时候。
I see what you mean. Sometimes programs require a restart when settings are changed. I guess this is something similar. Does it resolve the situation when you run the "end" statement in the immediate pane? That clears all memory, unfortunately you cannot use it in a function or it will end the program as well.
我明白你的意思.有时程序在设置更改时需要重新启动。我想这是类似的东西。它是否解决了在即时窗格中运行“end”语句时的情况?这将清除所有内存,不幸的是,你不能在函数中使用它,否则它也会结束程序。
我是一名优秀的程序员,十分优秀!