davesabine.com

 Search
How Do I Display the Euro Symbol in My ASP Pages? Really.

How Do I Display the Euro Symbol in My ASP Pages? Really.

I have read too many articles online about how to hack the Euro symbol into an ASP page -- this article (hopefully) will help you when you've discovered why those work-arounds are fundamentally wrong and ridiculous. Let's have a few moments together to determine the best solution.

How To Display The Euro...Really!

<%@ Language="VBScript" %>
<%
SetLocale("es-es")
response.write(FormatCurrency(123456))
%>

That's it -- that's all it takes. Paste that into an ASP document and give it a try. If it works, then thank you very much...you can pay at the door on your way out.

If you save the ASP file in UTF-8 format, then try this instead:

<%@ Language="VBScript" %>
<%
response.Codepage = 65001
response.Charset = "utf-8"
SetLocale("es-es")
response.write(FormatCurrency(123456))
%>

If that works, great -- tell all your friends. If it doesn't work and you receive an error like this:

Object doesn't support this property or method: 'response. blah blah blah...

...then you're using a very old web server and should consider upgrading...read on.

Why Does that Work (or Not Work)?

The example code above simply takes advantage of the tools Microsoft gives us. First, the "SetLocale()" function instructs the ASP engine to use a Euro-friendly locale ("es-es" in my example). This is similar to setting the LCID but I much prefer the "SetLocale()" function. If you're searching for a complete list of locales, language names, LCIDs, then you'll find my favourite list here: http://www.2020applications.com/xml_rss/_culture_info.xml.

Next, my example code above simply uses the "FormatCurrency()" function to format a number as a valid currency in that locale.

  • It works because Microsoft has done the heavy-lifting and the "FormatCurrency()" function and the "Response" object know that the "Español (España)" locale requires Euro. Furthermore, the built-in function knows that the Euro symbol should be displayed after the number and automatically takes care of the decimal and grouping digits.

  • If it doesn't work then for reasons discussed below your web server isn't equipped to handle the Euro symbol in that locale or your web server's Regional Settings are configured to enforce the pre-Euro symbols.

Solutions -- Good

If your web server isn't equipped to format the Euro currency properly, then you should consider one of the following:

  1. Update your server with the "Euro Conversion Tool". This should have been done years ago!
  2. Ask your server administrator if their system is fully patched and updated.
  3. Ask your server administrator if their operating system's Regional Settings are configured to enforce the pre-Euro symbol in your locale.
  4. Upgrade your server to IIS 5.1 or higher -- Windows XP (if you're so inclined) or Windows Server 2003.

In other words, the best solution is to operate an up-to-date web server and use the built-in VBScript functions as they're intended.

Once you've successfully displayed the Euro on your pages using the "FormatCurrency()" function (as demonstrated by the example code above) you might be looking for more information about manipulating currencies, locales, and some definitive advice about programming for multi-lingual environments. If so, I highly recommend the following resources:

  • Using ASP to Internationalize Your Web Pages: This article is published at Microsoft's TechNet. The information is excellent and should be read by every author working with multi-lingual and/or non-US-English applications.

  • ASP Server Test Utility: This is a utility I've created for our customers to test their web server's compatibility with ASP, their Locale and Regional Settings, their SMTP components...etc. It's a great little tool which will help you determine if your web server will display the Euro properly for your locale.

  • A Comprehensive List of Languages, Cultures, and LCIDs: I have compiled a complete list of all languages currently supported by the Windows Operating System that you *should* be able to use in the ASP environment. This list contains the name, shortname, LCID hexvalue, LCID decimal value, 3-digit currency code, and currency name. Note that for some of the languages, you may need to install the appropriate Microsoft Windows "Language Pack" -- for instance, most Western-Euro operating systems will not support "glyph" languages like Chinese or Inuktitut without additional software.

One Additional Problem I'd Like To Mention, and The Solution

Subtitle: "...hmm, that's weird...this LCID produces the Euro but now my upload script says: 'Invalid Procedure Call or Argument'"

On most systems, once you employ an LCID that is Euro-friendly and if your environment is also configured to use a non-standard "CodePage", then the heading above has likely crossed your mind.

Even if you've diligently followed Microsoft's documentation and you're certain you've done everything correctly, and your web server is properly managing the Euro currency, then you might experience problems elsewhere in your code. In some cases, all your hard work to improve your web server and implement the correct LCID pays off and your pages miraculously begin churning out the Euro as you had hoped but by changing LCID you might discover that other scripts break with an "Invalid Procedure Call or Argument" error message. What's going on?

I have run into this error most often with pure-ASP "upload" scripts. The reason is that those scripts usually incorporate VBScript's wide-byte character functions (to convert binary data to strings or vice-versa). If your scripts utilize such functions (AscB(), ChrB(), MidB(), LenB(), InStrB(), LeftB(), RightB()) then you should expect this error as soon as you alter the LCID. This circumstance occurs by design and the reason is simply that the wide-byte functions are apt to break in multi-lingual environments unless the "Response.CodePage" property is managed carefully.

You'll face this conundrum:

  1. Changing the LCID or CodePage to successfully produce the Euro symbol will break the wide-byte functions (and your upload scripts won't work).

  2. Changing the LCID or CodePage so that the wide-byte functions work properly will shift your currency to pre-Euro or some other unrelated format.

The solution is to change the "Response.CodePage" property to a non-Unicode language (like "1252") at the beginning of your function or class, then change it back to your Euro-friendly CodePage (like my personal favourite: "65001") at the end of your function or class. Like this:

Class YourPureASPFileUploadClass

   Private SUB Class_Initialize
   response.CodePage = 1252
   ....etc....
   END SUB

   Private SUB Class_Terminate
   response.CodePage = 65001
   ....etc....
   END SUB

END Class

If you implement this fix, then suffer the following error message:

Object doesn't support this property or method: 'response.CodePage'

...then your using an obsolete version of ASP. The ".CodePage" method was incorporated into the "Response" object in ASP 3.0 and you should upgrade your web server. There's simply no excuse to be using a web server that is older than the Euro itself! You should consider upgrading your web server to IIS 5.1 or higher -- Windows XP (if you're so inclined) or Windows Server 2003.

"Do I really have to upgrade?" I heard that question just two months ago and what I wanted to say was: "Why are you using an obsolete web server to serve your web site? EasyCGI will host your site for a few bucks a months and you won't have to bother me again with this idiotic question." But instead I replied, "it would be best, sir, the web server you are using is older than the Euro".

Solutions -- Bad

Subtitle: "What are the Hacks? Is there a Workaround?"

Let me pause for a moment to clarify something.

I've made an assumption while writing the remainder of this article that you are experiencing difficulty using the Euro because you are using an outdated web server and that you're here searching for a way to avoid having to upgrade your server by hacking the Euro into your pages with a sledge-hammer. Perhaps I'm wrong to have made this assumption, so:

  • If you are using Windows Server 2003, and you're still having difficulty, then please forgive. If this article hasn't helped you to implement the Euro, then I have failed you and I will revise it as necessary if you leave a helpful comment below.

  • If you've read the article to this point, and I've been unclear in any way or I've failed to provide adequate explanation, then I apologize. Please leave a comment and tell me how I can improve this article for you.

  • If my assumption is correct and you are currently experiencing difficulty implementing the Euro on a system that is older than the Euro itself...then I make no apologies. I'm not going to sugar-coat the information nor encourage you to continue using an antique operating system. Ultimately, the example code at the beginning of this article will work. If it doesn't, then the source of the problem will never be found or cured within the ASP or VBScript environment; it will require a change or upgrade to your web server. But if you arrived at this article hoping to find some way to hack the Euro symbol into your code, then read on...

If you are still reading this section then you're either really interested or really stubborn. Either way, you should never have to read this section because the Euro is supported by the Microsoft web server and ASP and VBScript -- if you're suffering a problem regarding the Euro then all the information you need is above this paragraph, not below.

The foolish hack you might be looking for can be found below and at your favourite search engine while perhaps the most famous of these abominations is here: http://www.drdev.net/article04.asp

Open letter to the author of http://www.drdev.net/article04.asp:

Dear Dr. Dev (or whomever it may concern),

Your article was written a while ago and I understand that. I also believe that most of the content of that article is very helpful until of course your "note about the Euro". Please don't purport that your workaround is necessary because the built-in methods "can't be relied upon". That article should be updated/deleted immediately so as not to continue to provide well-meaning ASP authors with bad advice.

Your article has cost me time and money because:
  • Some of my clients (who are clinging to their Windows NT and ASP 2.0!) have insisted, with "Dr.-Dev-said-so" confidence that there's a workaround to their problem;
  • and that they really don't have to upgrade their nine-year-old web server -- and that I'm just being dense;
  • that they'll just modify my source code themselves and prove to me that I'm the crazy one. (At which point they implement your wacky workaround and contact me months later when their web site and databases are irreparably damaged by mismanagement (or avoidance!) of the currency data-type.)
Ciao

Invariably, those hacks suggest that you can write the Euro symbol in front (or behind) the "FormatNumber()" function. Like this:

response.write("&#8364;"& FormatNumber(123456))
  • Those hacks are suggested by stubborn people who won't simply upgrade their web server.

  • Those hacks are written for stubborn people who won't simply upgrade their web server.

That is bad -- it's worse than bad -- and those hacks do not tell you the reasons why, so I will.

Microsoft Has Fixed the Problem You're Having

There are very good reasons that Microsoft released two all-new operating systems in 2002 (Windows XP) and 2003 (Server 2003) -- one of those reasons was to improve support for the new Euro currency and to ensure that their technologies are able to process Euro as a native currency data-type. To achieve this, Microsoft rebuilt much of their operating system. In my opinion, those who are living and working in any of the Euro nations should upgrade and avoid further frustration.

For argument's sake: the biggest brains at Microsoft were asked to develop support for the Euro currency and the solution they produced is called "Windows Server 2003". Microsoft also produced upgrades for "Microsoft Office" suite, the "Exchange Server", "Commerce Server", "BizTalk", "Small Business Server", and so on. One of the many reasons for this is simply that the legacy systems were not capable of processing the Euro currency comfortably.

It's Not Just a Different Symbol!

Yes, the Euro "symbol" (€) is of course just another symbol in the computer's alphabet -- just another character on your keyboard. In that respect it's not much different from the dollar sign ($) or a slash (/) or any other letter.

It's rather easy to display the symbol; web browsers and word processors have been able to achieve this for many years -- that's not the hard part. The hard part is in processing the currency -- as a currency. The "currency" is a unique data-type in the VBScript environment. Your web server likes currencies because it can perform math with currencies as though they are numbers. (The ability to perform math with numbers/currencies is absolutely essential -- who would argue?)

Your web server cannot perform math with text, and those bizarre workarounds that you'll find scattered around the internet all require that you change your beautiful "number" into "text" (What?) Let's really take a look at the famous workaround and understand what's really happening to your data when you do such a terrible thing:

FormatNumber(123456)
First, the hacks suggest using FormatNumber() instead of the more appropriate FormatCurrency() because, well, FormatCurrency() on your system might not produce the Euro symbol properly and you'll get the pre-Euro symbol (or something else) instead.
Second, the function accepts a number or a string which looks convincingly like a number and magically converts it to a string with the proper decimal and grouping digits.
Then the &#8364; (or equivalent entity)
This is HTML's way of printing the € symbol to the screen. It tells the web browser to display the appropriate character.
But it does not make your number a currency.

Then those two strings are concatenated with an & (ampersand) and pushed to the web browser through the "Response.write" method and the whole retarded thing looks like this:

<%
dim aNumber
    aNumber = 12.3456

dim yourSalary
    yourSalary = "&#8364; "& aNumber

'did you know that your beautiful number is a "double"
'and yourSalary is a string?

response.write("<br />aNumber: "& TypeName(aNumber))
response.write("<br />yourSalary: "& TypeName(yourSalary))
response.write("<br />")

response.write(yourSalary &"<br />") ' this line probably works
response.write(FormatCurrency(yourSalary) &"<br />") ' this line won't

dim annualIncome
   annualIncome = 12 * yourSalary 'this line won't work either
   ' so you'll have to keep track of two variables for one piece of data...your number, and your string
   annualIncome = 12 * aNumber 'this line will work.

   ' and what if you want to operate this same script on a web server in Spain?...oops! you can't. You'll have to rewrite the hack to put the € on the other side of the number.
%>

Let me say it again, "then that string is pushed out to the page". The proposed workaround does not make the construct a currency; it's a string. You can put a Porsche hood ornament on a Honda Civic, but that doesn't make it a Carrera. You have not fooled ASP into believing that your data is related in any way to money.

As such, this hack is capable only of displaying the appropriate symbols on a page. But if that's all you need to accomplish, then you should just write the characters in the HTML directly. Likely, that's not all you'll need to do with the number/currency. Chances are good that you've retrieved the value from a database or from user input and you'll have to perform math with it or compare it to other data -- something! -- that's why you're using ASP in the first place right?

If you subscribe to the workaround (any of them) then you'll also have to consistently store your value as either a number or as a string. Even if you do not, VBScript will implicitly convert your variable as it sees fit. Like this:

Imagine getting a number from a form (user input):
<%
dim yourVariable
    yourVariable = request.form("The_User_Input") 'perhaps it looks like "€ 123.45"
%>

That's a string. It will be a string every time. Try to do math with it like: yourVariable + 1; I dare ya!

<%
dim yourVariable
    yourVariable = request.form("The_User_Input") 'perhaps it looks like "123.45"
%>

That's a string too. Try to do math with it like: yourVariable + 1; If you're lucky, then VBScript will implicitly cast the string: "123.45", to a number: 123.45, and then add one (1), and your variable might be equal to: 124.45. But I wouldn't count on it.

Moreover, perhaps your application doesn't break (at first) and you're able to carry on for a while with this ridiculous hack. Eventually you'll want to put that value into a database or something equally useful and...guess what?...you'll have to hack again with a giant hammer to get the value into your database without causing a type mismatch or syntax error in the SQL. If you're lucky the database will puke on your input immediately and let you know there's a problem. If you're not lucky, your queries might succeed and you'll never know that your database is riddled with invalid information. In order to prevent errors in your SQL query you might even be tempted (in the worst case scenarios involving the most stubborn people) to change your database column from a "currency" or "money" to a "text" or "varchar". If you've ever been tempted to do such a thing, go immediately to the section in this article entitled "Solutions -- Good".

Ultimately the goal should be to cast the variable as a currency data-type like this:

<%
dim yourVariable
    yourVariable = CCur(request.form("The_User_Input"))
%>

Now the value of that variable is a proper currency and you can do with it as you please and all the built-in functions like "FormatCurrency()" will work like a charm. But the hack-workaround will instead force you (one way or other) to do this at best:

<%
dim yourVariable
    yourVariable = CNum(request.form("The_User_Input"))
    ' or
    yourVariable = CDbl(request.form("The_User_Input"))
%>

If that construct doesn't fail, then you've succeeded in casting the input as a "number" or a "double" data-type. But it still has nothing to do with money and you're further from your goal, not closer.

Imagine getting a number from a database:

The same problems outlined above (regarding user input) will apply to database input. One way or other, if your web server isn't capable of managing the Euro as a "currency" data-type, then you'll be sliding a slippery slope and have to hack your way through your entire application to accommodate the hack and successfully avoid the currency data-type.

Rather than workaround the problem...solve the problem. Go back to the section entitled "Solutions -- Good".

Regards,
D. S.