【问题标题】:how to "sync" VB Project after dynamically adding a function?动态添加功能后如何“同步”VB项目?
【发布时间】:2017-07-09 06:30:42
【问题描述】:

我正在编写一个 Excel VBA 项目,该项目在代码执行期间创建新函数。

新增的功能需要能够立即执行。

虽然我确实看到添加了新功能,但我在第一次执行时收到“1004”运行时错误。

以下代码将新函数testMethod 添加到现有DynamicFunctions 模块中(如果该函数不存在)并执行它。

取自Dynamic Code Generate & Execute@VBAProgramming The VBA Editor 的代码sn-ps

错误信息: “运行时错误‘1004’: 无法运行宏“testMethod”。该工作簿中的宏可能不可用,或者所有宏都可能被禁用"

(注意第二次执行,该函数已经在模块中,所以代码只是执行它并弹出消息框)

Dim code As String
code = "Public Function testMethod()" & vbNewLine & _
            vbTab & "MsgBox """ & Time & """" & vbNewLine & _
            "End Function"

Dim methodExist As Boolean
methodExist = checkProcName("testMethod")

If (methodExist = False) Then
    Dim VBComp As VBIDE.VBComponent
    Set VBComp = ThisWorkbook.VBProject.VBComponents("DynamicFunctions")
    Call VBComp.CodeModule.AddFromString(code)
End If

Application.Run "testMethod"



Function checkProcName(sProcName As String) As Boolean
' ===========================================================================
' Found on http://www.cpearson.com at http://www.cpearson.com/excel/vbe.aspx
' then modified
'
' USAGE:
' to check if a procedure exists, call 'checkProcName' passing
' in the target workbook (which should be open), the Module,
' and the procedure name
'
' ===========================================================================
Dim oVBProj As VBIDE.VBProject
Dim VBComp As VBIDE.VBComponent
Dim CodeMod As VBIDE.CodeModule

Dim ProcName As String
Dim ProcKind As VBIDE.vbext_ProcKind

checkProcName = False

Set VBProj = ThisWorkbook.VBProject
Set VBComp = VBProj.VBComponents("DynamicFunctions")
Set CodeMod = VBComp.CodeModule

With CodeMod
    LineNum = .CountOfDeclarationLines + 1
    Do Until LineNum >= .CountOfLines
        ProcName = .ProcOfLine(LineNum, ProcKind)
        If ProcName = sProcName Then
            checkProcName = True
            Exit Do
        End If
        Debug.Print ProcName
        LineNum = .ProcStartLine(ProcName, ProcKind) + .ProcCountLines(ProcName, ProcKind) + 1
    Loop
End With


End Function

【问题讨论】:

  • 您上面的代码是在DynamicFunctions 模块中,还是在不同的模块中?
  • checkProcNameDynamicFunctions 内。其他人在不同的
  • 我做了一些测试,只要 DynamicFunctions 模块只为动态代码保留,它就对我有用:如果你从那里执行任何其他东西(或者甚至引用存储在那里的全局),那么你会看到你描述的错误。
  • @TimWilliams:谢谢蒂姆,这确实是问题所在。如果您想添加您的评论作为答案,我会批准它

标签: vba excel excel-2010


【解决方案1】:

除非有特定原因您需要在项目中使用 DynamicFunctions 模块,否则您可以随时创建一个、运行代码并在完成后删除。

Public Sub CreateModuleRunMethodAndDelete()
    Dim code As String
        code = "Public Function testMethod()" & vbNewLine & _
                vbTab & "MsgBox """ & Time & """" & vbNewLine & _
                "End Function"

    'Create and append code
    With ThisWorkbook.VBProject
        With .VBComponents.Add(vbext_ct_StdModule)
            .Name = "Temp"
            .CodeModule.AddFromString code
        End With
    End With

    'Run
    Application.Run "testMethod"

    'Delete module
    With ThisWorkbook.VBProject
        .VBComponents.Remove .VBComponents("Temp")
     End With
End Sub

编辑:

如果不存在则创建过程并运行。

Public Sub RunMethod()
    Dim code As String
        code = "Public Function testMethod()" & vbNewLine & _
                vbTab & "MsgBox """ & Time & """" & vbNewLine & _
                "End Function"

    If Not checkProcName("testMethod") Then
        ThisWorkbook.VBProject.VBComponents("DynamicFunctions").CodeModule.AddFromString code
    End If

    Application.Run "testMethod"

End Sub

【讨论】:

  • 动态代码正在从外部文件中提取 - 这是一个耗时的过程(通过网络,数十个外部文件......) - 我希望使“创建”阶段变得粘性...... .例如,只有1次打开文件并创建动态代码,第二次及以后,该函数已经存在......
  • 以上实际上是我在问题中发布的代码 - 它没有解决我的主要问题,即“在第一次执行代码时出现 1004 运行时错误” - @Kostas 你做到了吗尝试一下并设法在第一次运行它?
  • @NirMH 正确,执行没有错误。测试了无数次,每次都删除testMethod的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多