Слияние MS Word: как исключить нечисловые символы в поле слияния «сумма»

ОКРУЖАЮЩАЯ СРЕДА

Мне нужно делать еженедельное слияние почты, чтобы создавать письма о пожертвованиях. Используемая нами программа базы данных создает файл Excel (xls), который затем объединяется с документом Word (2010) для печати квитанций. За один тираж будет распечатано 3-6 тысяч чеков. Мы получаем пожертвования в разных валютах.

ПРОБЛЕМА

Программа базы данных экспортирует сумму в валюте с символом валюты и без десятичной точки. например: 5000 долларов США (50 долларов США) или 500000 евро (5000,00 евро) или 1000 швейцарских франков (10 швейцарских франков).

(Не знаю, почему разработчики так решили! Но в целом программа неплохая.)

С помощью простой формулы в поле слияния я смог убрать символы доллара США и евро, а затем разделить сумму на 100.

{ = { MERGEFIELD currency_amount \# 0.00}  / 100 \# #,0.00}

Однако эта формула дает мне проблему для такой валюты, как CHF. Я получаю эту ошибку: !Undefiend Bookmark, CHF1000


Я пытался изменить формулу и искал в Интернете, но пока безуспешно.

У кого-нибудь есть решение или идея, как это решить? Если возможно, я не хочу редактировать исходный файл Excel (например, запускать макрос, искать и заменять и т. д.).

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

Спасибо!


person philips    schedule 02.02.2015    source источник


Ответы (1)


Я надеюсь, что у кого-то есть изящное решение, но, на мой взгляд, каждое решение этой проблемы, вероятно, приведет к осложнениям, которых можно было бы избежать, если бы вы могли изменить программное обеспечение для извлечения — либо разделить строку валюты и сумму на два столбца, либо, по крайней мере, , введите пробел между "CHF" и числом.

Вы можете сделать это, используя большой набор кодов полей, но будет проще, если только "CHF" вызывает проблему. Другой способ, не требующий редактирования источника данных, приведен ниже, но он может оказаться полезным лишь в некоторых случаях.

Я не думаю, что вы можете сделать это, используя простой набор кодов полей, потому что, хотя вы можете написать код, который будет определять, будет ли Word рассматривать сумму как число или нет, все же есть проблема, когда вы обнаружите, что это не число.

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

{ SET tmp { MERGEFIELD currency_amount } }{ IF { tmp } = { =tmp } "it's a number" "it's not a number" }

Это должно работать нормально и не вызывать ошибок во время слияния. Случай, когда это не сработает, как ожидалось, когда, например, у вас есть значение 1000 швейцарских франков, и у вас действительно есть закладка под названием «1000 швейцарских франков».

В случае, когда Word считает, что это число, вы можете использовать { =tmp #0 }, чтобы получить число и сделать с ним то, что вам нужно.

В случае, когда это не так, вам нужно подумать, как вы можете получить числовую часть из поля.

Вы не можете использовать { = } каким-либо полезным образом. (Иногда можно использовать арифметические «трюки», чтобы получить что-то из числа, но я не думаю, что в данном случае это возможно).

Вы не можете использовать косвенность каким-либо полезным способом (например, когда вы используете что-то вроде

{ DOCVARIABLE { REF tmp } }

для доступа к переменной CHF1000 со значением 1000. Для этого вам понадобится одна такая переменная для каждой возможной суммы. На самом деле, если бы вы могли получить суммы, скажем, до 9999 швейцарских франков, это могло бы сработать.

Поэтому я думаю, что вам нужно использовать «грубую силу», чтобы извлечь цифры одну за другой. Опять же, если это только для CHF и числа всегда в одном и том же формате (CHF1, CHF2,.., CHF1000 и т. д.) и вы знаете максимальное количество цифр, вы можете сделать это с целой кучей полей IF, подобных этому :

{ IF tmp = "CHF0*" { SET tmp2 "0" }
}{ IF tmp = "CHF1*" { SET tmp2 "1" }
}{ IF tmp = "CHF2*" { SET tmp2 "2" }
}{ IF tmp = "CHF3*" { SET tmp2 "3" }
}{ IF tmp = "CHF4*" { SET tmp2 "4" }
}{ IF tmp = "CHF5*" { SET tmp2 "5" }
}{ IF tmp = "CHF6*" { SET tmp2 "6" }
}{ IF tmp = "CHF7*" { SET tmp2 "7" }
}{ IF tmp = "CHF8*" { SET tmp2 "0" }
}{ IF tmp = "CHF9*" { SET tmp2 "9" }
}{ SET tmp1 { tmp2 }
}{ IF tmp = "CHF?0*" { SET tmp2 "{ tmp1 }0" }
}{ IF tmp = "CHF?1*" { SET tmp2 "{ tmp1 }1" }
}{ IF tmp = "CHF?2*" { SET tmp2 "{ tmp1 }2" }
}{ IF tmp = "CHF?3*" { SET tmp2 "{ tmp1 }3" }
}{ IF tmp = "CHF?4*" { SET tmp2 "{ tmp1 }4" }
}{ IF tmp = "CHF?5*" { SET tmp2 "{ tmp1 }5" }
}{ IF tmp = "CHF?6*" { SET tmp2 "{ tmp1 }6" }
}{ IF tmp = "CHF?7*" { SET tmp2 "{ tmp1 }7" }
}{ IF tmp = "CHF?8*" { SET tmp2 "{ tmp1 }8" }
}{ IF tmp = "CHF?9*" { SET tmp2 "{ tmp1 }9" }
}{ SET tmp1 { tmp2 }
}{ IF tmp = "CHF??0*" { SET tmp2 "{ tmp1 }0" }
}{ IF tmp = "CHF??1*" { SET tmp2 "{ tmp1 }1" }
}{ IF tmp = "CHF??2*" { SET tmp2 "{ tmp1 }2" }
}{ IF tmp = "CHF??3*" { SET tmp2 "{ tmp1 }3" }
}{ IF tmp = "CHF??4*" { SET tmp2 "{ tmp1 }4" }
}{ IF tmp = "CHF??5*" { SET tmp2 "{ tmp1 }5" }
}{ IF tmp = "CHF??6*" { SET tmp2 "{ tmp1 }6" }
}{ IF tmp = "CHF??7*" { SET tmp2 "{ tmp1 }7" }
}{ IF tmp = "CHF??8*" { SET tmp2 "{ tmp1 }8" }
}{ IF tmp = "CHF??9*" { SET tmp2 "{ tmp1 }9" }
}{ SET tmp1 { tmp2 }
}

и повторите эту партию для каждой цифры, которая у вас может быть, увеличивая количество "?" символов на один каждый раз. Затем используйте { =tmp1 #0 }, чтобы получить значение.

Другой способ, которым вы могли бы воспользоваться с источником данных Excel, — это написать VBA, который использует Jet SQL для изменения данных (т. е. он не будет изменять «основные данные»). Если есть только один пользователь, вы определяете все основные документы слияния, и вы можете реплицировать их среду, теоретически вам нужно запустить VBA только один раз - каждый раз, когда они повторно открывают свой основной документ слияния, один и тот же SQL будет быть казненным. На практике это редко бывает так просто. Если вам нужно иметь дело только с «CHF», вы можете использовать код в следующих строках:

Sub SetupDataSource()
ActiveDocument.MailMerge.OpenDataSource _
  Name:="c:\a\yourdatasource.xlsx", _
  sqlstatement:="SELECT t.*, iif(ucase(left(t.currency_amount,3))='CHF',mid(t.currency_amount,4),t.currency_amount) AS new_amount FROM [Sheet1$] t"
End Sub

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

  • Не все функции обработки строк в VBA доступны в Jet при таком подключении через OLE DB
  • Word ограничивает SQL до 511 символов (возможно, 255 в некоторых случаях). На самом деле это не много.
person Community    schedule 02.02.2015
comment
Большое спасибо за ваш подробный ответ! Сначала я попытаюсь использовать метод SQL и опубликую результаты, но это кажется самым простым в моей среде. - person philips; 03.02.2015