简体   繁体   English

从Excel MailMerge-不稳定的宏行为

[英]MailMerge from Excel - Erratic macro behaviour

Good Afternoon, 下午好,

I have set up a macro to generate individual certificates based on this thread ( Automating Mail Merge using Excel VBA ). 我已经设置了一个宏来基于此线程生成单独的证书( 使用Excel VBA自动化邮件合并 )。 But the macro has always behaved erratically, working one day, throwing errors at me the next. 但是宏总是表现不正常,一天工作,第二天向我抛出错误。

The most frequent error I get is that Excel is waiting for another application (Word) to perform an OLE action. 我得到的最常见的错误是Excel正在等待另一个应用程序(Word)执行OLE操作。 But at times there are runtime errors where it doesn't want to know the objects. 但是有时会出现运行时错误,它不想知道对象。

I have reworked the macro, hoping to sort the issues once and for all but the current error doesn't like the "End With" before I close the Word. 我重新设计了宏,希望一劳永逸地对问题进行排序,但是在关闭Word之前,当前错误不喜欢“ End With”。 I have 3 "Withs", so why doesn't it like 3 "End Withs". 我有3个“ Withs”,所以为什么不像3个“ End Withs”。 - I don't just want to take out the "End With" because I it makes sense to me that one doesn't open Word for each certificate and close it again. -我不只是想删除“结尾为”,因为我认为不会为每个证书打开Word并再次将其关闭。 That is asking for problems. 那是在问问题。

The macro is set to go through the Excel sheet, evaluate column K (r, 11) and if it's empty (meaning the certificate hasn't been generated yet), perform the mailmerge and save the document as a pdf into the defined folder. 将该宏设置为通过Excel工作表,评估列K(r,11),如果该列为空(表示尚未生成证书),请执行mailmerge并将文档以pdf格式保存到定义的文件夹中。

This is the code. 这是代码。 Can anybody see why VBA has a problem with it? 谁能看到VBA为什么有问题吗? Thanks! 谢谢!

Public Sub MailMergeCert()

Dim bCreatedWordInstance As Boolean
Dim objWord As Word.Application
Dim objMMMD As Word.Document

Dim FirstName As String
Dim LastName As String
Dim Training As String
Dim SeminarDate As String
Dim HoursComp As String
Dim Location As String
Dim Objectives As String
Dim Trainer As String

Dim cDir As String
Dim r As Long
Dim ThisFileName As String

FirstName = sh1.Cells(r, 1).Value
LastName = sh1.Cells(r, 2).Value
Training = sh1.Cells(r, 3).Value
SeminarDate = Format(sh1.Cells(r, 4).Value, "d mmmm YYYY")
HoursComp = sh1.Cells(r, 5).Value
Location = sh1.Cells(r, 6).Value
Objectives = sh1.Cells(r, 7).Value
Trainer = sh1.Cells(r, 8).Value

'Your Sheet names need to be correct in here
Set sh1 = ActiveWorkbook.Sheets("Ultrasound")


'Setup filenames
Const WTempName = "Certificate_Ultrasound_2017.docx" 'Template name

'Data Source Location
cDir = ActiveWorkbook.Path + "\" 'Change if required
ThisFileName = ThisWorkbook.Name

On Error Resume Next

'Create Word instance
bCreatedWordInstance = False
Set objWord = CreateObject("Word.Application")

If objWord Is Nothing Then
  Err.Clear
  Set objWord = CreateObject("Word.Application")
  bCreatedWordInstance = True
  End If

If objWord Is Nothing Then
    MsgBox "Could not start Word"
    Err.Clear
    On Error GoTo 0
    Exit Sub
End If

' Let Word trap the errors
On Error GoTo 0

' Set to True if you want to see the Word Doc flash past during construction
objWord.Visible = False

'Open Word Template
Set objMMMD = objWord.Documents.Open(cDir + WTempName)
objMMMD.Activate

'Merge the data
With objMMMD
.MailMerge.OpenDataSource Name:=cDir + ThisFileName, _
    sqlstatement:="SELECT *  FROM `Ultrasound$`"   ' Set this as required

lastrow = Sheets("Ultrasound").Range("A" & Rows.Count).End(xlUp).Row
r = 2

For r = 2 To lastrow
    If IsEmpty(Cells(r, 11).Value) = False Then GoTo nextrow

With objMMMD.MailMerge  'With ActiveDocument.MailMerge
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
With .DataSource
  .FirstRecord = r - 1
  .LastRecord = r - 1
  .ActiveRecord = r - 1
End With
.Execute Pause:=False
End With

'Save new file PDF
Dim UltrasoundCertPath As String
UltrasoundCertPath = "C:\Users\305015724\Documents\ApplicationsTraining\2016\Ultrasound\"
Dim YYMM As String
YYMM = Format(sh1.Cells(r, 16).Value, "YYMM")
Dim NewFileNamePDF As String
NewFileNamePDF = YYMM & "_" & sh1.Cells(r, 3).Value & "_" & sh1.Cells(r, 7).Value '& ".pdf" 'Change File Name as req'd"
objWord.ActiveDocument.ExportAsFixedFormat UltrasoundCertPath & NewFileNamePDF, ExportFormat:=wdExportFormatPDF

End With


' Close the Mail Merge Main Document
objMMMD.Close savechanges:=wdDoNotSaveChanges
Set objMMMD = Nothing
If bCreatedWordInstance Then
objWord.Quit
End If

Set objWord = Nothing
Cells(r, 11).Value = Date

0:
Set objWord = Nothing

nextrow:
Next r


End Sub

If you indent your code and get rid of the "unimportant" stuff, you end up with this: 如果您缩进代码并摆脱“不重要”的东西,您将得到以下结果:

Public Sub MailMergeCert()
    '...
    With objMMMD
        '...
        For r = 2 To lastrow
            '...
            With objMMMD.MailMerge
                '...
                With .DataSource
                    '...
                End With
                '...
            End With
            '...
        End With
        '...
    Next r

End Sub

If you look at that, you soon see that you have a mismatch of With / End With blocks and For / Next loops. 如果您看一下,很快就会发现With / End With块和For / Next循环不匹配。

Because you only have two With statements within the For loop, but you have three End With statements, the compiler gets "confused" and insists that you correct the error. 因为在For循环中只有两个With语句,但是有三个End With语句,所以编译器会感到“困惑”,并坚持要求您更正错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM