Click here to Skip to main content
Click here to Skip to main content

Number Speller COM-ponent

By , 18 Feb 2009
 

The original article: COM Number Speller.

Introduction

Some time ago, I needed to print numbers as text in Excel (Office 2003 as far as I remember). Searching the internet, I found a solution for English language, but not for Romanian language.

So, I created a reusable piece of code that may be easily used in as many environments as possible. I chose COM and ATL to be the solution to this problem. This is also a good programming exercise for my rusty COM / C++ skills and I plan to use it as a template for all my future COM objects.

Using the Code  

To install the COM object, just simply run Install.bat in NumberSpeller.zip archive.
Here is the Excel macro that makes use of the NumberSpeller COM object:

Function Spell(n As Currency) As String
'Create the speller object.
Dim s As NumberSpellerLib.speller
Set s = New NumberSpellerLib.speller

Dim o As Object
Set o = s
o.Language = "ro"
Spell = o.Translate(n)
End Function

Here is another example of using the component from WSH script:

// Create the speller object.
var speller = new ActiveXObject("NumberSpeller.Speller");

// Set Romanian language
speller.language = "en";

////////////////////////////////////////////
// Modify the  number constant below.
var numberToTranslate = 101001;

// Translate number to text.
try
{
    var textNumber = speller.Translate(numberToTranslate);
    WScript.Echo(textNumber);
}
catch (e)
{
    // Display details about any thrown exceptions.
    WScript.Echo(e.name + ": " + e.description + "  " + e.number);
}

Points of Interest

  • Error info support by implementing IErrorInfo interface.
  • Help in CHM format and context identifiers specified in MIDL source file.
  • BSTR manipulation using CComBSTR class provided by ATL
  • IDispatch support, so the component can be used from scripting environments.
  • Spelling implementation itself and support for multiple languages (only Romanian and English for now).  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Adrian Dorache
Software Developer (Senior) Codecentrix Software
Romania Romania
Member
Software consultant in Bucharest Romania writing Windows programs and browsers plug-ins since 1998 with Visual C++.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralGood job!memberMaze27 May '09 - 6:52 
Un 5 din Norvegia.
 
who dares wins!

GeneralModified English VersionmemberSynaptrik18 Feb '09 - 7:54 
First off, thanks. This algorithm is elegant. I would dare say, it qualifies as beautiful code. Smile | :)
 
I'm not sure if anyone else could use this, but I refactored the English version to suit what we needed. We print monetary amounts that we work with as unsigned integers in all caps.
 
If anyone else finds it useful, help yourself:
 

#include "stringstream" //preview is stripping the angle brackets... doh.

string MonetaryText(unsigned int amount);
void NumToStr(stringstream &buf, unsigned int num);
 
const char* const NUMBERS_UP_TO_20[] =
{
  "",         "ONE",     "TWO",       "THREE",    "FOUR",
  "FIVE",     "SIX",     "SEVEN",     "EIGHT",    "NINE",
  "TEN",      "ELEVEN",  "TWELVE",    "THIRTEEN", "FOURTEEN",
  "FIFTEEN",  "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"
};
 
const char* const NUMBERS_MULTIPLE_OF_10[] =
{
  "TWENTY", "THIRTY",  "FORTY", "FIFTY",
  "SIXTY",  "SEVENTY", "EIGHTY", "NINETY"
};
 
string MonetaryText(unsigned int amount)
{
  stringstream retBuf;
 
  unsigned int cents = amount % 100;
  unsigned int dollars = amount / 100;
 
  if(dollars > 0)
  {
    NumToStr(retBuf, dollars);
 
    retBuf << " DOLLAR";
 
    if(dollars > 1)
      retBuf << "S";
  }
  else
    retBuf << "ZERO DOLLARS";
 
  retBuf << " AND";
 
  if(cents > 0)
  {
    NumToStr(retBuf, cents);
 
    retBuf << " CENT";
 
    if(cents > 1)
      retBuf << "S";
  }
  else
    retBuf << " NO CENTS";
 
  return retBuf.str();
}
 
void NumToStr(stringstream &buf, unsigned int num)
{
  if(num < 20)
  {
    if(buf.tellp() > 0 && num != 0)
        buf << " ";
 
    buf << NUMBERS_UP_TO_20[num];
    return;
  }
  
  unsigned int tmpNum = num / 1000000000;
  if(tmpNum > 0)
  {
    NumToStr(buf, tmpNum);
    buf << " BILLION";
    num %= 1000000000;
  }
  
  tmpNum = num / 1000000;
  if(tmpNum > 0)
  {
    NumToStr(buf, tmpNum);
    buf << " MILLION";
    num %= 1000000;
  }
  
  tmpNum = num / 1000;
  if(tmpNum > 0)
  {
    NumToStr(buf, tmpNum);
    buf << " THOUSAND";
    num %= 1000;
  }
  
  tmpNum = num / 100;
  if(tmpNum > 0)
  {
    NumToStr(buf, tmpNum);
    buf << " HUNDRED";
    num %= 100;
  }
  
  if(num < 20)
    NumToStr(buf, num);
 
  else
  {
    tmpNum = num / 10;
    if(tmpNum > 0)
    {
      if(buf.tellp() > 0)
        buf << " ";
 
      buf << NUMBERS_MULTIPLE_OF_10[tmpNum - 2];
      num %= 10;
    }
    
    tmpNum = num;
    if(tmpNum > 0)
      NumToStr(buf, tmpNum);
  }
}

 
This statement is false

JokeRe: Modified English VersionmemberAdrian Dorache18 Feb '09 - 9:21 
If at least one person on earth find this code useful, then my mission is complete :--)
 

GeneralRe: Modified English VersionmemberSynaptrik18 Feb '09 - 9:23 
More than useful. Optimal. Smile | :) Thanks again.
 
This statement is false

Generalseventeen is mispelled..memberSynaptrik17 Feb '09 - 13:59 
..in your english speller.
 
This statement is false

GeneralRe: seventeen is mispelled..memberAdrian Dorache18 Feb '09 - 3:13 
Thank you. I have fixed the typo.
 

QuestionCom Component? Why?memberednrg14 Jan '09 - 5:32 
Why would this be a com component. It's a simple call that should be placed in a static class, that is called without any instantiation. Place it in the GAC, and it can be used throughout many apps.
AnswerRe: Com Component? Why?memberAdrian Dorache14 Jan '09 - 5:55 
Because I wanted it to be available from script languages like Jscript and other non .Net environments. However it can be used from .Net languages as well.
 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 18 Feb 2009
Article Copyright 2009 by Adrian Dorache
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid