VBA在运行时更改excel代码并执行它

VBA在运行时更改excel代码并执行它,excel,vba,dynamic,runtime,Excel,Vba,Dynamic,Runtime,我想在Excel中更改VBA代码模块并执行新代码。 在启动程序之前: SUB1() msgbox "O L D" ENDSUB Main program: Delete_SUB1 Create_NewSUB1 CALL SUB1 Remark: Create_SUB1 creates the follow code: SUB1() msgbox "N E W" ENDSUB 问题:代码已更改,但Excel仍执行旧版本。我试过: A.A

我想在Excel中更改VBA代码模块并执行新代码。 在启动程序之前:

SUB1()
  msgbox "O L D"
ENDSUB
Main program:
  Delete_SUB1
  Create_NewSUB1
  CALL SUB1
Remark: Create_SUB1 creates the follow code:
SUB1()
  msgbox "N E W"
ENDSUB
问题:代码已更改,但Excel仍执行旧版本。我试过:

A.ActiveCodePane B在两个工作簿之间切换 C打开/关闭解决了该问题,但耗时太长。我需要它在一个循环中1000次用于AI应用程序。
有什么想法吗?

我正要写下这是不可能的,但是在玩了一会之后,我找到了一种方法来做你想做的事

基本思想是将动态部分放在单独的工作簿中,并通过Application.Run调用它。这样做,编译器似乎完成了它的工作,但只在具有动态代码的工作簿上进行

如果代码位于同一工作簿中,并且您可以找到编译代码的方法,那么它将重置全局变量,丢失继续执行的位置信息,并且迟早会自动停止执行或崩溃

我并不是说这是一个好主意,也不是说这在长时间运行时会起作用,我认为神经元网络经常运行,直到它们得到结果。特别是您需要确保动态代码永远不会有任何语法错误,否则整个过程将被一条语法错误消息中断,并且这不能用任何On error…-处理程序处理,因为它不是运行时错误

这是我用于测试的代码:

Global GlobalCount As Long ' Using a global to prove that it is not reset by compiler

Sub test()
    Dim i As Integer
    For i = 1 To 100
        CreateAndRunProc
    Next
End Sub

Sub CreateAndRunProc()
    GlobalCount = GlobalCount + 1
    
    Dim code(1 To 3) As String
    code(1) = "Sub testOnTheFly()"
    code(2) = "    Debug.print " & """Hello " & GlobalCount & " at " & Time & """"
    code(3) = "End Sub"
    
    ' Write the Sub "testOnTheFly" into module "modTest" of Workbook "OnTheFlyChild.xlsm"
    WriteSub Workbooks("OnTheFlyChild.xlsm"), "modTest", code
    ' Call the newly created Sub
    Application.Run "'OnTheFlyChild.xlsm'!testOnTheFly"
End Sub

' Replace the complete code of module with the provided code
Sub WriteSub(CodeWB As Workbook, moduleName As String, code As Variant)
    Dim project As VBProject, component As VBComponent
    Set project = CodeWB.VBProject
    Set component = project.VBComponents(moduleName)
    
    component.CodeModule.DeleteLines 1, component.CodeModule.CountOfLines
    Dim i As Integer
    For i = LBound(code) To UBound(code)
        component.CodeModule.InsertLines i, code(i)
    Next
End Sub

玩得开心

我正要写下这是不可能的,但是在玩过之后,我找到了一种方法来做你想做的事

基本思想是将动态部分放在单独的工作簿中,并通过Application.Run调用它。这样做,编译器似乎完成了它的工作,但只在具有动态代码的工作簿上进行

如果代码位于同一工作簿中,并且您可以找到编译代码的方法,那么它将重置全局变量,丢失继续执行的位置信息,并且迟早会自动停止执行或崩溃

我并不是说这是一个好主意,也不是说这在长时间运行时会起作用,我认为神经元网络经常运行,直到它们得到结果。特别是您需要确保动态代码永远不会有任何语法错误,否则整个过程将被一条语法错误消息中断,并且这不能用任何On error…-处理程序处理,因为它不是运行时错误

这是我用于测试的代码:

Global GlobalCount As Long ' Using a global to prove that it is not reset by compiler

Sub test()
    Dim i As Integer
    For i = 1 To 100
        CreateAndRunProc
    Next
End Sub

Sub CreateAndRunProc()
    GlobalCount = GlobalCount + 1
    
    Dim code(1 To 3) As String
    code(1) = "Sub testOnTheFly()"
    code(2) = "    Debug.print " & """Hello " & GlobalCount & " at " & Time & """"
    code(3) = "End Sub"
    
    ' Write the Sub "testOnTheFly" into module "modTest" of Workbook "OnTheFlyChild.xlsm"
    WriteSub Workbooks("OnTheFlyChild.xlsm"), "modTest", code
    ' Call the newly created Sub
    Application.Run "'OnTheFlyChild.xlsm'!testOnTheFly"
End Sub

' Replace the complete code of module with the provided code
Sub WriteSub(CodeWB As Workbook, moduleName As String, code As Variant)
    Dim project As VBProject, component As VBComponent
    Set project = CodeWB.VBProject
    Set component = project.VBComponents(moduleName)
    
    component.CodeModule.DeleteLines 1, component.CodeModule.CountOfLines
    Dim i As Integer
    For i = LBound(code) To UBound(code)
        component.CodeModule.InsertLines i, code(i)
    Next
End Sub

玩得开心

你为什么要这样做?为什么不能使用Sub1和Sub2?这是一个人工智能项目。代码将由神经元网络生成。这只是一个简单的借口。人工智能应生成用于求解非线性方程的函数。但问题是。Excel无法运行在运行时创建的代码。如果上述问题得到解决,我们可以继续创建神经元网络函数来创建函数。我们想要:一个相互操纵的函数[函数a更新B,B更新C,C更新a]b我们想知道人工智能是否能得到与数学相同的解c我们想创建一个神经网络如果最终生成的代码能被人类从机器中学习的人理解。你为什么要这样做?为什么不能使用Sub1和Sub2?这是一个人工智能项目。代码将由神经元网络生成。这只是一个简单的借口。人工智能应生成用于求解非线性方程的函数。但问题是。Excel无法运行在运行时创建的代码。如果上述问题得到解决,我们可以继续创建神经元网络函数来创建函数。我们想要:一个相互操纵的函数[函数a更新B,B更新C,C更新a]b我们想知道人工智能是否能得到与数学相同的解c我们想创建一个神经网络如果最终生成的代码能被人类从机器中学习的人理解的话。这个想法听起来不错。我会尝试,我很好奇,如果第二个工作簿代码可以更新第一个工作簿中的代码。让我测试一下,投票通过了!我在我的项目中就是这么做的。如果在现有组件之间找不到moduleName,也可以插入模块。但是,在这种情况下,有必要将testOnTheFly过程命名为稍微不同的名称。使其包含新插入的模块名的一部分。为了避免在另一个模块中运行具有相同名称的过程,这是必要的……这个想法听起来不错。我会尝试,我很好奇,如果第二个工作簿代码可以更新第一个工作簿中的代码。让我测试一下,投票通过了!我在我的项目中就是这么做的。如果在现有组件之间找不到moduleName,也可以插入模块。但是,在这种情况下,有必要将testOnTheFly过程命名为稍微不同的名称。使其包含新插入的模块名的一部分。这是必要的,以避免尝试在中运行具有相同名称的过程 另一个模块。。。