【问题标题】:Is it better to use several SUBs or have all the code in one SUB使用多个 SUB 更好还是将所有代码放在一个 SUB 中更好
【发布时间】:2019-10-07 15:56:31
【问题描述】:

我一直在通过论坛和 YouTube 自学 VBA。我编写了一些使用If 语句的代码。如果该声明为真,我可以选择调用另一个 SUB 或仅在同一个 SUB 中编写代码。我的问题是,如果我调用 SUB 并且它使用 MS Word,如果代码使用循环,它是否相当于启动 MS Word 然后退出并一次又一次地重新启动它?属于第二个 SUB 的部分我评论了,下面没有包含。

Option Explicit

Sub CreateWordDocEarlyBinding()
    'Declared Variables for Sub.
    Dim sourceDoc As String
    Dim lastRow As Long
    Dim rowLoop As Long

    'Adding code for MS Word here
    Dim WdApp As Application
    Set WdApp = New Word.Application

'Not sure I need this for any reason.    
Dim columnLoop As Long

    'Find last row.
    lastRow = Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp).Row

    'Looping through column.
    For rowLoop = 2 To lastRow

         'Not sure I  need at this point for code.
         'columnLoop = Sheet1.Range(rowLoop, 1)

        'Checking cells for A Conditon.
        If Sheet1.Cells(rowLoop, 1).Value = "Test String 1" Then
            If Sheet1.Cells(rowLoop, 1).Offset(0, 1).Value >= 0.1 Then
                If Sheet1.Cells(rowLoop, 1).Offset(0, 1).Value < 1 Then
                    sourceDoc = "Test1.docx"
                    Call CreateNewSourceDoc(sourceDoc, WdApp)
                Else
                    sourceDoc = "Test2.docx"
                    Call CreateNewSourceDoc(sourceDoc, WdApp)
                End If

            End If

        'Checking cells for B condition.
        ElseIf Sheet1.Cells(rowLoop, 1).Value = "Test String 2" Then
            If Sheet1.Cells(rowLoop, 1).Offset(0, 1).Value >= 0.5 Then
                If Sheet1.Cells(rowLoop, 1).Offset(0, 1).Value < 5 Then
                    sourceDoc = "Test3.docx"
                    Call CreateNewSourceDoc(sourceDoc, WdApp)
                Else
                    sourceDoc = "Test4.docx"
                    Call CreateNewSourceDoc(sourceDoc, WdApp)
                End If
            End If



        End If

    'Checking next row.
    Next

    WdApp.Quit
    Set WdApp = Nothing
End Sub

我在这里添加了第二个 SUB 的代码以进行澄清。这段代码每次循环时都会创建一个新的 word 实例吗?如果是这样,我最好去掉下面的SUB。

Sub CreateNewSourceDoc(sourceDoc As String, WdApp As Application)

    'Declaring variables
    Dim newFolderName As String
    Dim newFilePath As String
    'Source folder
     filePath = ThisWorkbook.Path & "\"

     'New Folder
      newFolderName = Sheet1.Cells(rowLoop, 1) & " " & Sheet1.Cells(rowLoop, 2)
      MkDir filePath & newFolderName

      'New file path
            newFilePath = filePath & newFolderName & "\"

     'I commented the below code out to see if it is correct.
    'Set WdApp = New Word.Application

    With WdApp

              .Visible = False

              '.Activate

              .Documents.Open filePath & sourceDoc

              .ActiveDocument.SaveAs2 Filename:=newFilePath & Sheet1.Cells(rowLoop, 1) & " " & Sheet1.Cells(rowLoop, 2) & ".docx"


          End With

          sourceDoc = vbNullString

End Sub

【问题讨论】:

  • 如果您将WdApp 传递给子,它可以使用它。否则它将不得不启动一个新实例,是的。
  • @GSerg ,不确定您的意思。我将代码添加到合并两个 SUB 的帖子中。当它们分开时,第一个 SUB 将“sourceDoc”传递给第二个 SUB,第二个 SUB 打开并保存单词 doc。为了避免新实例,我将在哪里传递“wdApp”。抱歉,我是新手。
  • New Word.Application 每次执行 Word 时都会启动一个新实例,正如阅读代码所表明的那样。如果您想重用一个实例,那么除了您现在要传递的sourceDoc 之外,您还必须将WdApp 传递给第二个SUB;它将作为附加参数传递给第二个SUB.. 不过我不知道WdApp 来自哪里;您在第一个 SUB 中使用它,但它不在该代码中的任何位置,除了单行 WdApp.Quit
  • @KenWhite ,我编辑了第一个 SUB 代码,并认为我将 WdApp 和 sourceDoc 传递给了第二个 sub。现在怎么样了?
  • @KenWhite ,我只看到一个单词实例,它在 sub.Thanks 的末尾消失了。

标签: vba ms-word


【解决方案1】:

问题中的代码是正确的。

Word.Application (WdApp) 在“主”子 CreateWordDocEarlyBinding 中启动,并在那里退出并清理。

WdApp 连同使用的文档一起被传递给第二个 Sub 进行处理。

我注意到还有一件事可以在第二个过程(Sub)中进行优化:

我将为正在打开的文档声明并实例化一个 Word.Document 对象,然后保存,而不是“匿名”打开文档,然后依靠 ActiveDocument 成为正确的文档。所以...

Sub CreateNewSourceDoc(sourceDoc As String, WdApp As Application)

    'Declaring variables
    Dim newFolderName As String
    Dim newFilePath As String
    Dim wdDoc as Word.Document

     'New Folder
      newFolderName = Sheet1.Cells(rowLoop, 1) & " " & Sheet1.Cells(rowLoop, 2)
      MkDir filePath & newFolderName

     'New file path
     newFilePath = filePath & newFolderName & "\"

     With WdApp   
          .Visible = False
          Set wdDoc = .Documents.Open(filePath & sourceDoc)
          wdDoc.SaveAs2 Filename:=newFilePath & Sheet1.Cells(rowLoop, 1) & _
                        " " & Sheet1.Cells(rowLoop, 2) & ".docx"  
     End With

     sourceDoc = vbNullString
     Set wdDoc = Nothing
End Sub

【讨论】:

  • 我会将它添加到代码中,感谢您的解释,我知道这样会更好。我很感激。你还会做什么来优化代码?我计划添加另一个从工作表创建的 SUB。将“newFilePath”传递给 Sub PDFMaker 是否理想?我希望为 Sub CreateNewSourceDoc 和 Sub PDFMaker 的每个循环生成的文件放在同一个文件中。
  • 在 Stack Overflow 上讨论优化是困难的(而且是题外话),更多的是针对特定问题。您可以查看 Code Review 站点(请务必阅读他们的帮助以了解主题内容以及如何在那里提问),看看这对于直接优化讨论是否会更好。当然,将文件路径传递给两个子过程。
  • 请注意不要更改任一过程中的路径。阅读参数/参数的“By Ref”与“By Value”。默认情况下,String 将是 By Ref,这意味着任何更改都将传递回调用过程。如果需要进行本地更改,请将参数指定为“按值”。
  • 当代码循环返回时,我确实使用默认的 By Ref 得到了错误。当我将其更改为按值时,效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 2012-08-25
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 2016-06-27
相关资源
最近更新 更多