替换多个文件中VBA代码的最佳方法是什么?

3

我曾经使用类似这样的东西:

Dim vbaComponent As Variant
For Each vbaComponent In inputWorkbook.VBProject.VBComponents
    vbaComponent.CodeModule.DeleteLines 1, vbaComponent.CodeModule.CountOfLines
    vbaComponent.CodeModule.AddFromFile importComponentFileName
Next vbaComponent

这个方法一开始运行得很好,但现在当Excel文件保存时会崩溃。我猜文件可能太大了或者出了其他问题。

有更好的方法吗?

编辑:

问题似乎出在frmcls文件上。替换bas文件完美运行。

编辑2:

在一些机器上,甚至bas文件也无法运行。

编辑3(我的当前解决方案):所以我的当前解决方案是手动操作一次并记录所有鼠标和键盘输入,然后重复播放。

如果没有更好的解决方案,我计划创建一个AutoIt脚本来解决这个问题。


嗨,我不明白为什么这会被视为离题。如果没有本地的VBA方法可以实现这一点,但第三方解决方案可以,那么这将是一个可行的答案。 - DerSeegler
1
好的,我现在明白了。无论如何,我希望有一个本地解决方案。 - DerSeegler
2个回答

2

您需要导出/导入组件,因为并非所有行都暴露给CodeModule,以下是示例

Private Sub exportImportComponent(Project1 As VBIDE.VBProject, Project2 As VBIDE.VBProject)
    Dim i As Long, sFileName As String

    With Project1.VBComponents
        For i = 1 To .Count
            sFileName = "C:\Temp\" & .Item(i).Name
            Select Case .Item(i).Type
                Case vbext_ct_ClassModule
                    .Item(i).Export sFileName & ".cls"
                    Project2.VBComponents.Import sFileName & ".cls"

                Case vbext_ct_StdModule
                    .Item(i).Export sFileName & ".bas"
                    Project2.VBComponents.Import sFileName & ".bas"

                Case vbext_ct_MSForm
                    .Item(i).Export sFileName & ".frm"
                    Project2.VBComponents.Import sFileName & ".frm"

                Case Else
                    Debug.Print "Different Type"
            End Select
        Next
    End With
End Sub

我已经有了导出到.bas、.cls和.frm文件的内容。我的问题是如何以编程方式导入它们。我过去使用了问题中的代码,并将importComponentFileName作为相应的文件。但是就像所说的那样,由于某种原因,这不再起作用了。 - DerSeegler
如果您尝试导入的组件名称已经存在,则导入将失败,请确保在导入之前解决名称冲突。 - tsolina
请检查我在问题中编写的代码。我没有将导出的文件作为新模块导入。我是通过使用CodeModule.AddFromFile将其内容写入现有模块中的。 - DerSeegler
1
你确定没有命名冲突吗?因为addFromFile将会从数据中添加代码,并根据文件名更改模块名称,如果使用它时出现错误,可能会掩盖问题。 - tsolina
百分之百确定。代码以前可以运行,现在仍然能够正常执行。问题是,在代码更改完成后保存文件会导致Excel崩溃,原因不明。甚至没有VBA异常可以捕获。我有点怀疑是Windows更新的问题。 - DerSeegler

0

我可以向所有人保证,因为我已经在这个主题上工作了好几年(我曾经放弃过几次)。当代码在按行或我的首选方法1.重命名,2.删除已重命名的,3.从导出文件重新导入时进行编程修改,工作簿保存会崩溃,并提示Excel关闭工作簿。事实上,我的方法大多数情况下都能正常运行,但由于不可预测性,我学会了与之共存。在大多数情况下,代码更改已经成功完成。所以我只需重新打开工作簿并继续。

我使用的代码。我只是删除了所有执行跟踪和执行日志代码行,但有些行可能看起来有点神秘:

    With rn_wb.VBProject
    
    '~~ Find a free/unused temporary name and re-name the outdated component
    If mComp.Exists(wb:=rn_wb, comp_name:=rn_comp_name) Then
        sTempName = mComp.TempName(tn_wb:=rn_wb, tn_comp_name:=rn_comp_name)
        '~~ Rename the component when it already exists
        .VBComponents(rn_comp_name).Name = sTempName
        .VBComponents.Remove .VBComponents(sTempName) ' will not take place until process has ended!
    End If
   
    '~~ (Re-)import the component
    .VBComponents.Import rn_raw_exp_file_full_name
    
    '~~ Export the re-newed Used Common Component
    Set Comp = New clsComp ' class module provides the export files full name
    With Comp
        Set Comp.Wrkbk = rn_wb
        .CompName = rn_comp_name
    End With
    .VBComponents(rn_comp_name).Export Comp.ExpFileFullName
    
    '~~ When Excel closes the Workbook with the subsequent Workbook save it may be re-opened
    '~~ and the update process will continue with the next outdated Used Common Component.
    '~~ The (irregular) Workbook close however may leave the renamed components un-removed.
    '~~ When the Workbook is opened again these renamed component may cause duplicate declarations.
    '~~ To prevent this the code in the renamed component is dleted.
    ' EliminateCodeInRenamedComponent sTempName ' this had made it much less "reliablele" so I uncommented it
    
    SaveWbk rn_wb ' This "crahes" every now an then though I've tried a lot

End With

Private Sub SaveWbk(ByRef rs_wb As Workbook)

Application.EnableEvents = False
DoEvents ' no idea whether this helps. coded in desparation. at least it doesn't harm 
rs_wb.Save
DoEvents ' same as above, not executed when Excel crashes
Application.EnableEvents = True

结束子程序


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接