Word Automation (VBA): расширенный текстовый формат для слияния писем

Я пытаюсь сделать Word MailMerge через VBA из моего проекта Access. Я создал класс clsWordMerge, чтобы я мог объявить приложение Word WithEvents и воспользоваться преимуществами событий Word MailMerge, в основном события AfterMerge.

Все работает нормально, и я получаю готовые документы Word, за исключением того, что исходные поля, содержащие данные RTF, попадают в документ не в виде форматированного текста, а вместо кодов и данных RTF:

<div><font face="Times New Roman" size=3 color=black>This is my <strong><em>test </em></strong>paragraph.</font></div>

Где я ожидал увидеть: это мой тестовый абзац

Это происходит независимо от того, выполняю ли я слияние почты с использованием файла CSV для моего источника данных или таблицы Access.

Так есть ли способ исправить это и показать отформатированные данные? У меня есть доступ ко всем событиям MailMerge, которые предоставляет Word.

Спасибо..


person RMittelman    schedule 17.12.2019    source источник


Ответы (2)


Нет, нет возможности объединить RTF и отобразить его как содержимое Word. RTF не является собственным форматом файлов Word - для отображения RTF как содержимого Word требуется конвертер.

Слияние почты буквально отображает текст данных, как он появляется в источнике данных. Не существует «дополнительных функций», позволяющих выборочно форматировать результат слияния.

Кроме того, исходя из болезненного опыта, полагаться на MailMergeAfterMerge не рекомендуется. Когда он был представлен, я попробовал, был в восторге ... пока он не начал давать сбой. Событие непредсказуемо и ненадежно.

С учетом ваших требований передача данных из Access в Word полностью на основе VBA - более эффективное вложение времени и энергии.

person Cindy Meister    schedule 17.12.2019
comment
Спасибо. Жаль, что MailMergeAfterMerge ненадежен, он кажется идеальным местом для выполнения таких операций по очистке, как закрытие шаблона и выполнение поиска / замены в сгенерированном документе. - person RMittelman; 17.12.2019
comment
Я беспокоился об очистке от вызывающей стороны на случай, если слияние почты еще не было выполнено, так что это событие казалось идеальным. Если это не проблема, мне вообще не нужен класс, просто метод в модуле, не вызывающий никаких событий. Думаю, я просто удалю весь форматированный текст и перейду к обычному тексту и стандартному слиянию. Мы можем несколько стилизовать шаблон документа. Большое спасибо... - person RMittelman; 17.12.2019

Вероятно, это можно сделать при определенных обстоятельствах, но я согласен с Синди Мейстер в том, что события слияния почты не оказались надежными (если они не были исправлены - я фактически не использовал их в течение многих лет). Следующее описание реальных и вероятных проблем, с которыми я ранее столкнулся, пытаясь это сделать, может помочь:

  1. Не уверен, что это можно сделать, если вы собираетесь использовать электронную почту.

  2. AFAICR событие, которое, вероятно, вам понадобится (MailMergeBeforeRecordMerge), запускается только каждый раз, когда Word обрабатывает основной документ, а не каждый раз, когда он обрабатывает запись в источнике данных. Итак, если ваш основной документ слияния "потребляет" более одной записи источника данных, например поскольку он использует поля {NEXT} или {NEXTIF}, может быть очень сложно заставить MaiMergeBeforeRecordMerge делать то, что вам нужно. Если я прав в этом, этого было бы достаточно, чтобы я отказался от попытки.

  3. чтобы вставить ваш "RTF", вы должны либо

    а. Иметь код, который может интерпретировать кодировку "RTF" и делать все, что необходимо для ее вставки в ваш документ, или b. Имейте код, который сохраняет "RTF" во внешний файл, а затем использует (скажем) Range.InsertFile, чтобы вставить его и заставить Word интерпретировать его содержимое, или, возможно, c. Используйте буфер обмена, чтобы облегчить преобразование.

    Если бы какое-либо из ваших полей с форматированным текстом действительно содержало RTF, (а) было бы сложно, если бы вы не смогли найти подходящую библиотеку, которая могла бы вам помочь. Но на самом деле ваш образец показывает типичное значение поля форматированного текста Access, которое похоже на HTML. На самом деле, я думаю, что Word может интерпретировать все стандартные теги HTML, но я не знаю наверняка. Это может быть намного проще интерпретировать, особенно если вам нужен только простой текст (в самом простом случае вы можете выбросить теги и вставить результат.

  4. Если ваш форматированный текст длиннее 255 символов (включая разметку), Word Document.MailMerge.DataSource.DataFields («чувствительное к регистру имя поля, как его видит Word»). Значение будет усечено. Так что, если вам нужен весь текст или его больше, вам придется взять его где-нибудь в другом месте.

  5. Значение, вставленное в документ с помощью поля {MERGEFIELD}, не усекается до 255 символов, поэтому вы можете получить значение из документа. Word MailMerge может налагать другое ограничение (не могу вспомнить, возможно, 64 КБ для соединения OLE DB, возможно, меньше, или, возможно, существует ограничение на длину для данных в целом.

  6. Если вы не можете получить данные из документа, вы можете получить их прямо из Access. Вероятно, довольно легко, если ваш код работает в Access, но это можно сделать с помощью ADODB или, возможно, ADO из кода Word VBA. Ваш источник данных для слияния почты должен будет получить ключевые поля записи, если вы хотите сделать это надежно. Во время разработки, если ваше приложение запускается из Access, но вы используете код VBA в Word, вам, вероятно, также потребуется сохранять базу данных Access каждый раз, когда вы изменяете код Access VBA, в противном случае Access открывает только базу данных и Word не сможет получить из него данные.

  7. Если вам нужно использовать (b) или (c) для сохранения HTML-кода в файл, вам может потребоваться окружить HTML-код, полученный из Access, тегами и, возможно, тегами, чтобы Word распознал HTML. Вы можете использовать Scripting.FileSystemObject для сохранения текста или, возможно, ADODB.Stream, если вы уже используете ADODB для получения данных Access.

  8. Вы должны иметь возможность использовать VBA Range.InsertFile для его вставки, если у вас есть заполнитель, который сообщает вам, что его поместить. Или вы можете использовать поле INCLUDETEXT и убедиться, что ваш код события обновляет это поле. Загвоздка с подходом INCLUDETEXT заключается в том, что при слиянии с новым документом поля INCLUDETEXT остаются в документе, поэтому, если вы обновите их, все они будут иметь тот же результат, если вы также не создадите новый файл для каждого источника. записывать.

т.е. довольно много над чем подумать!

person Community    schedule 17.12.2019
comment
Вау, спасибо за невероятно подробное объяснение. Похоже, в этом случае против меня сложены кости. Я перейду на более простой метод, возможно, откажусь от всего этого форматирования. Еще раз спасибо... - person RMittelman; 17.12.2019