Усечение поля слияния в Microsoft Word для слияния

Я хочу создать формулу и применить ее к полю слияния в Word 2013. У меня нет доступа к БД, и у меня есть только поля слияния. Моя цель - обрезать/укоротить определенные поля слияния. Например. Полное имя до начального, Возраст от [27 лет] до короткого возраста [27].

В Access и Excel есть формула «слева», которую я безуспешно пытался использовать. Кажется, для чисел доступно меньше вариантов.

{=left({ MERGEFIELD First_Name },1)}

Однако это дает синтаксическую ошибку. Есть ли список формул, которые работают для mergefield?

Результат

«Стивен» -> «С»

«27 лет» -> «27»


person Taz    schedule 22.07.2016    source источник


Ответы (1)


Краткий ответ на ваш вопрос заключается в том, что в языке полей Word нет ничего, что могло бы надежно выполнять манипуляции со строками, такие как left(), mid() и т. д. Поле {=} имеет только числовые функции, такие как СУММ, АБС, ПРОДУКТ и т. д. Существуют ненадежные подходы, и в некоторых случаях они могут быть достаточно надежными для ваших требований, но это действительно зависит от того, насколько вы уверены, что источник данных всегда будет содержать значения, отформатированные в соответствии с вашими ожиданиями.

В качестве простого примера возьмем «27 лет».

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

{ SET dat { MERGEFIELD age } }{ =dat }

Обратите внимание, что в этом случае, если вы выполняете слияние с новым документом, поля { =dat } останутся в выходных данных, и обновление этих полей вызовет ошибки. Этого можно избежать, вложив либо поле { =dat }, либо все поля в поле QUOTE:

{ QUOTE "{ SET dat { MERGEFIELD age } }{ =dat }" }

{ SET dat { MERGEFIELD age } }{ QUOTE { =dat } }

Однако, если ваше поле источника данных может содержать такое значение, как

4 years 2 months

тогда это не будет работать, потому что в этом случае { =dat } будет оцениваться как 6, а не 2. Word также будет оценивать все, что выглядит как выражение поля { = }, например. если ваш источник данных содержит

SUM(23,25)

тогда { =dat } будет оцениваться как 48. Есть и другие странности, которые я сейчас не буду описывать.

Самый простой ненадежный подход к извлечению первой буквы из поля — использовать большое количество полей ЕСЛИ для проверки каждой возможной начальной буквы, например

{ IF "{ MERGEFIELD First_Name }" = "A*" "A" }{ IF "{ MERGEFIELD First_Name }" = "B*" "B" } etc.

Если вам не нужно различать нижний и верхний регистр, вы можете использовать

{ IF "{ MERGEFIELD First_Name \*Upper }" = "A*" "A" } etc.

Это нормально, если вы знаете (например), что имена могут начинаться только с AZ, az (и вы, очевидно, также можете проверить на 0-9 и т. д. Но что, если оно может начинаться с любой буквы Unicode? Не уверен, что вставка тысяч полей ЕСЛИ является надежным подходом.

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

Что вы можете сделать, так это создать полностью пустую базу данных Access/Jet .mdb (скажем, она находится в c:\i\i.mdb, а затем вставить поле DATABASE, вложенное в поле QUOTE, подобное этому

{ QUOTE { DATABASE \d "c:\\i\\i.mdb" \s "SELECT left('{ MERGEFIELD First_Name }',1)" } }

Обычно поле DATABASE вставляет таблицу Word (если источник данных не содержит больше столбцов, чем может содержать таблица Word), но когда вы вставляете только одно значение без заголовков, Word не помещает значение в ячейку. К сожалению, в наши дни Word добавляет знак абзаца, но вложение поля DATABASE в поле QUOTE, по-видимому, снова удаляет его.

Так почему же это «ненадежно»? Ну, основная причина в том, что если поле First_Name содержит какие-либо кавычки (конечно, одинарные кавычки, а OTTOMH, я думаю, двойные кавычки), то запрос, который Word отправляет в Jet, будет выглядеть вот так

SELECT left('a name containing a ' mark'),1)

и Jet вернет синтаксическую ошибку.

Есть и другие проблемы с полевым подходом DATABASE, в том числе

  • Word ограничивает оператор SELECT до 255 символов (я думаю). Если ваш источник данных приводит к тому, что длина оператора SLEECT превышает это значение, Jet вернет ошибку.
  • Вы должны разместить базу данных где-то. Если вы просто используете это слияние самостоятельно, это может не быть проблемой, но если вам нужно распространять документ Word и т. д. для использования другими, вы также должны убедиться, что у них есть .mdb и что он находится в указанном месте.
  • Word иногда путается между источником данных Mail Merge и источником данных, представленным через поле DATABASE.
  • Даже одно поле DATABASE будет выполнять запрос для каждой записи в источнике данных. Если вы используете эту технику в нескольких местах, будет выдано очень большое количество запросов. Это может вызвать проблемы.

Что касается «извлечения одной буквы», существует другой подход, очень похожий на подход DATABASE, который использует внешний файл .XML и набор полей INCLUDETEXT для указания узла в файле и возврата его содержимого. Но есть и аналогичные трудности. Я могу изменить этот ответ, чтобы описать этот подход в какой-то момент, но, насколько мне известно, он никогда не использовался в реальном сценарии.

Так что, если вам нужно что-то более надежное? Что ж, подходов несколько, но все они страдают теми или иными недостатками. Основные подходы, которые я знаю:

  1. используйте Word VBA и метод OpenDataSource, чтобы открыть источник данных. Это позволяет указать запрос на диалекте SQL, понятном источнику данных.
  2. используйте запрос/представление, определенный в промежуточной базе данных, для извлечения необходимых элементов данных и используйте этот запрос/представление в качестве источника данных
  3. Используйте события MailMerge Word VBA для управления данными для каждой записи в источнике данных, когда Word обрабатывает слияние.
  4. использовать ручной промежуточный шаг
  5. (более радикально) отказаться от Word MailMerge и найти другой подход, например. создать .docx с помощью .NET, соответствующего поставщика базы данных и пакета SDK для Office Open XML.

Если вы создаете это слияние для использования другими людьми, два побочных эффекта всех этих подходов заключаются в том, что общий процесс становится более сложным или незнакомым для пользователя, и, в частности, они могут не иметь возможности использовать возможности Word для источника данных. фильтрация записей и так далее. Еще одна проблема, с которой сталкиваются некоторые люди, заключается в том, что если ваша база данных содержит длинные текстовые поля/памятные поля длиной более 255 символов, Jet имеет тенденцию усекать их всякий раз, когда вы делаете что-то гораздо более сложное, чем по умолчанию «SELECT * FROM TABLE».

(1) требует, чтобы вы могли написать подходящий запрос для получения необходимых столбцов из вашего источника данных. Поскольку запрос выполняется с использованием OLE DB, вам фактически не нужно создавать какие-либо постоянные объекты в вашей базе данных. Таким образом, это может быть жизнеспособным подходом, если внутренняя база данных позволяет выполнять внешние запросы. Но Word также накладывает на запрос ограничение в 255 или 511 символов, поэтому, если вам приходится манипулировать большим количеством полей или нужные вам сложные функции, вы можете обнаружить, что вы довольно быстро превысите лимит символов.

(2) очень похож на (1), но может позволить вам указать гораздо более сложный запрос. Например, если вашим источником данных является Jet .accdb, вы можете создать свой собственный .accdb и определить в нем запрос, который обращается к таблицам в .accdb, которые вам не разрешены. изменить. Для этого вы можете либо использовать «связанные таблицы», либо в некоторых случаях вы можете указать расположение базовых таблиц/запросов в SQL.

(3) означает, что вы используете VBA для перехвата Word, когда он обрабатывает каждую запись источника данных. Я оставляю вас исследовать это. Вы должны контролировать процесс из VBA, чтобы убедиться, что события MailMerge вызываются. Были сообщения о различных ненадежностях. VBA может получить доступ только к первым 255 символам любых полей memo.

(4), например. вы создаете книгу Excel и используете ее для запросов к базе данных. В этом случае вы сможете выполнить гораздо более длинный SQL-запрос, чем в Word, и вы сможете создать новые столбцы Excel, которые обрабатывают данные с помощью формул Excel. (Хотя я никогда этого не пробовал). Затем используйте это как источник данных.

Наконец, веб-поиск должен показать список функций, распознаваемых полем «=» в Word, но в последней документации Microsoft функция IF(), как правило, не упоминается. Документы ISO29500 по стандарту .docx также опускают его, но я думаю, что это не было намерением и может быть исправлено в будущей версии стандарта. Функции:

АБС, И, СРЕДНИЙ, СЧЕТ, ОПРЕДЕЛЕН, ЛОЖЬ, ЕСЛИ, ЦЕЛОЕ, МИН, МАКС, МОД, НЕ, ИЛИ, ПРОИЗВЕД, ОКРУГЛ, СУММА, ИСТИНА.

person Community    schedule 22.07.2016
comment
Спасибо за идеальный ответ. Охватывает все базы! - person Taz; 23.07.2016