К сожалению, для некоторых источников данных Word устанавливает RecordCount в -1. В некоторых случаях это может быть результатом Word с использованием соединения ADO/OLE DB, потому что, например, когда вы извлекаете RecordSet с использованием ADO, вам иногда приходится использовать .MoveLast для получения фактического количества записей, и даже это зависит от тип курсора ADO и другие настройки ADO. Однако даже при подключении DDE к Excel Word может возвращать -1 учетную запись.
Я не совсем ясно, что именно вам нужно, чтобы быть в состоянии сделать, но в некоторых случаях вы можете установить текущее наибольшее количество записи, установив
theDoc.MailMerge.DataSource.ActiveRecord
на любое число больше, чем количество записей. Я подозреваю, что самое лучшее, что вы можете сделать, это
theDoc.MailMerge.DataSource.ActiveRecord = 2147483647#
Однако я не совсем уверен, что этого достаточно. Во-первых, если источник данных является многопользовательской базой данных, не исключено, что количество записей может измениться во время слияния, поэтому установка .lastrecord в начале может фактически не работать (хотя я бы подумал, что в большинстве случаев , вы действительно будете получать и обрабатывать записи в транзакции, и в этом случае вы, вероятно, увидите все тот же набор записей все время). Вы можете справиться с этой возможностью, пытаясь увеличить значение .ActiveRecord на каждой итерации. Если вы достигли конца записей, .ActiveRecord не будет увеличиваться. В Windows Word вам также придется иметь дело с возможностью того, что пользователь может исключить отдельные записи в диалоговом окне «Редактировать список получателей». В этом случае, когда вы пытаетесь увеличить значение .ActiveRecord, оно фактически перейдет к следующей записи «Включено/выбрано» (если есть), и Word также может вызвать ошибку. Итак, следующее показывает, как вы можете кодировать все возможности, которые я знаю в Windows Word. (Данная версия не проверялась, хотя):
Sub MailMergeOneThingPerDataSourceRecord()
Dim lngSourceRecord As Long
Dim objMerge As Word.MailMerge
Dim bError As Boolean
Dim bTerminateMerge As Boolean
Set objMerge = ActiveDocument.MailMerge
bError = False
bTerminateMerge = False
With objMerge
lngSourceRecord = 1
Do Until bTerminateMerge
On Error Resume Next
.DataSource.ActiveRecord = lngSourceRecord
If Err.Number = 0 Then
On Error GoTo 0
If .DataSource.ActiveRecord < lngSourceRecord Then
bTerminateMerge = True
Else
lngSourceRecord = .DataSource.ActiveRecord
.DataSource.FirstRecord = lngSourceRecord
.DataSource.LastRecord = lngSourceRecord
.Destination = wdSendToNewDocument
.Execute
lngSourceRecord = lngSourceRecord + 1
End If
Else
bTerminateMerge = True
If Err.Number <> 5853 Then
bError = True
End If
End If
Loop
End With
If bError Then
' deal with the error (you may prefer to do your error
' handling some other way) but e.g....
MsgBox "Error " & Err.Number & ": " & Err.Description
End If
Set objMerge = Nothing
End Sub
Однако, это только действительно работает, если вы знаете, что основной документ слияния потребляет только 1 источника данных записи в то время. Если в нем есть поля, такие как {NEXT}, он может потреблять несколько записей на итерацию. Если вы знаете, сколько, вы можете попытаться пропустить соответствующее количество записей. Если число может меняться (например, с помощью операторов {NEXTIF}, неясно, как вы можете обнаружить в VBA точно, сколько записей было использовано в каждом слиянии.