Please enable JavaScript to view this site.

R:BASE 11 Help

Navigation: Function Index > U > UDF (User-Defined Functions)

Sample UDF

Scroll Prev Top Next More

The following example uses a UDF named dwrd to convert a currency value to words:

 

SET VAR v1=(UDF('dwrd','$1,456.99'))

 

If you execute the above command and then enter SHOW VARIABLE at the R> Prompt, you see the following output:

 

one thousand four hundred fifty-six dollars and ninety-nine cents

 

 

Examples

 

The following is a R:BASE command that calls the UDF named random.

 

SET VAR v1 = (UDF('random', '25 345'))

 

The following are the command line arguments for the UDF named random for DOS as seen by the UDF code:

 

DOS

argv[0] = random

argv[1] = 25

argv[2] = 345

argv[3] = A345BD3456

argc    = 4

 

Argument 0 is the name of the executable. Argument 1 is the first parameter. Argument 2 is the second parameter. Argument 3 is the memory address. This brings the argument count to 4.

 

The following example uses a UDF named DWRD.EXE to convert a currency value to words:

 

SET VAR v1=(UDF('dwrd','$1,456.99'))

SHOW VAR v1

 

Result: v1= one thousand, four hundred fifty six dollars and ninety nine cents

 

The following example uses the DWRD.DLL to accomplish the same function.

 

SET VAR v1=(UDF('@dwrd.dll','$1,456.99'))

SHOW VAR v1

 

Result: v1= one thousand, four hundred fifty six dollars and ninety nine cents

 

Source Code

 

What follows is the source code for the dwrd.exe sample UDF, shipped with DOS products, and the source code for the dwrd.dll sample UDF, shipped with Windows products.

 


/*

*     Copyright 2001 by R:BASE Technologies, Inc.

*     Author:  Wayne J. Erickson  12 Apr 1991

*

************************************************************************

* *    Routine:  dwrd2 *** DOS VERSION ***

* *    Purpose:  convert a currency value to words

*

*      Input Parameters:

*              name                    Brief description

*              --------------          ------------------------------------------------

*              value                   Currency string to be parsed

*              Shared Segment          Shared memory segment to place the parsed string

*

************************************************************************

*/

 

#include

#include

#include

 

void conout(char *, int);

void crlf(void);

int lenstr(char *, int);

void dwrd(char *, char *);

 

cdecl main(argc,argv)

int argc;

char * argv[];

{

       long int i4;

       char *pt;

       char wordnum[160];

       int lw;

 

       /* Get the argument count.  */

       if(argc <= 1) {

               conout("DWRD number pointer", 19);

               crlf();

               goto done;

               }

 

       /* Do the conversion */

       dwrd(argv[1], wordnum);

 

       /* Display the result */

       lw = strlen(wordnum);

       if (argc == 2) {

               conout(wordnum, lw);

               crlf();

       }

 

       /* See if there was an address to store the result */

       if(argc > 2) {

               i4 = atol(argv[2]);

               pt = (char *)i4;

               memcpy(pt, wordnum, lw+1);

       }

done:

       return(0);

}

 

 

/**** Start of DWRD function ****/

void dwrd(strin, strout)

char *strin;

char *strout;

{

       int lstr;

       static char numbers[20][10] = {

               "          ","one       ","two       ",

               "three     ","four      ","five      ",

               "six       ","seven     ","eight     ",

               "nine      ","ten       ","eleven    ",

               "twelve    ","thirteen  ","fourteen  ",

               "fifteen   ","sixteen   ","seventeen ",

               "eighteen  ","nineteen  "};

 

       static char tenvals[10][10] = {

               "no        ","ten       ","twenty    ",

               "thirty    ","forty     ","fifty     ",

               "sixty     ","seventy   ","eighty    ",

               "ninety    "};

       char blank = ' ';

       char comma = ',';

       char dsign = '$';

       char dot = '.';

       char minus = '-';

       char ch;

       char tmoney[16];

       int offset;

       int tens;

       int lw, ls, n, intch, l;

 

       /*  CONVERT THE NUMBER. */

 

       tens = 0;

       memset(tmoney, ' ', 16);

       lw = 0;

       lstr = strlen(strin);

       ls = 16 - lstr + 1;

       strcpy(&tmoney[ls-1],strin);

 

       /*  PICK OFF THE CHARACTERS. */

 

       n = ls - 1;

next_digit:

       n++;

       if(n > 16) goto cleanup;

       ch = tmoney[n-1];

 

       /*  SKIP THE COSMETIC CHARACTERS. */

 

       if((ch == blank) || (ch == comma) || (ch == dsign)) goto next_digit;

       if(ch == minus) {

               memcpy(&strout[(lw+1)-1], "minus ", 6);

               lw = lw + 6;

               goto next_digit;

               }

       if((n == 4) || (n == 8) || (n == 12)) tens = 1;

 

       /*  SPECIAL STUFF WHEN WE HIT THE DECIMAL POINT. */

 

       if(ch == dot) {

               tens = 1;

               if(lw == 0) {

                       memcpy(&strout[(lw+1)-1], "zero ", 5);

                       lw = lw + 5;

                       }

               memcpy(&strout[(lw+1)-1], "dollars and ", 12);

               lw = lw + 12;

               if(tmoney[(n+1)-1] == '0') {

                       if(tmoney[(n+2)-1] == '0') {

                               memcpy(&strout[(lw+1)-1], "zero ", 5);

                               lw = lw + 5;

                               n = n + 2;

                               }

                       }

               goto next_digit;

               }

 

       /*  CONVERT A CHARACTER INTO AN OFFSET. */

 

       intch = ch - 48;

       if(tens) {

               if(intch <= 1) {

                       offset = 0;

                       if(intch == 1) offset = 10;

                       n = n + 1;

                       ch = tmoney[(n)-1];

                       intch = ch - 48 + offset;

                       }

               else {

                       l = lenstr(tenvals[(intch+1) - 1], 10);

                       if(l > 0) {

                               memcpy(&strout[(lw+1)-1], tenvals[(intch+1)-1], l+1);

                               lw = lw + l + 1;

                               }

                       tens = 0;

                       goto next_digit;

                       }

               }

       l = lenstr(numbers[(intch+1)-1], 10);

       if(l > 0) {

               memcpy(&strout[(lw+1)-1], numbers[(intch+1)-1], l+1);

               lw = lw + l + 1;

               }

       tens = 0;

       if(((n == 3) || (n == 7) || (n == 11)) && (intch != 0)) {

               memcpy(&strout[(lw+1)-1], "hundred ", 8);

               lw = lw + 8;

               }

       if(n == 5) {

               memcpy(&strout[(lw+1)-1], "million ", 8);

               lw = lw + 8;

               }

       if(n == 9) {

               memcpy(&strout[(lw+1)-1], "thousand ", 9);

               lw = lw + 9;

               }

       goto next_digit;

cleanup:

       memcpy(&strout[(lw+1)-1], "cents", 5);

       lw = lw + 5;

 

       /* Add the null terminator */

       strout[(lw+1)-1] = '\0';

 

       /*    ALL DONE.  */

 

       return;

}

/**** End of DWRD function ****/

 

 

/**** Start of CONOUT function ****/

void conout(str, count)

char *str;

int count;

{

       int i;

       for (i = 0; i < count; i++) {

               putchar(str[i]);

               }

       return;

}

/**** End of CONOUT function ****/

 

/**** Start of CRLF function ****/

void crlf()

{

       putchar('\r');

       putchar('\n');

       return;

}

/**** End of CRLF function ****/

 

/**** Start of LENSTR function ****/

int lenstr(str, count)

char *str;

int count;

{

       int i;

 

       i = count - 1;

       while (i >= 0) {

               if (str[i] != ' ') break;

               i--;

               }

       return (i+1);

}

/**** End of LENSTR function ****/

 

 

 

#include

/*

*     Copyright 2001 R:BASE Technologies, Inc.

*     Author:  Wayne J. Erickson  18 October 1999

*

************************************************************************

*

*      Routine:  dwrd  *** DLL VERSION ***

*

*      Purpose:  convert a currency value to words

*

*      Input Parameters:

*              name                    Brief description

*              --------------          ------------------------------------------------

*              value                   Currency string to be parsed

*              Shared Segment          Shared memory segment to place the parsed string

*

*

************************************************************************

*/

 

#include

void dwrd(char *, char *);

int lenstr(char *, int);

 

#pragma hdrstop

 

//---------------------------------------------------------------------------

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)

{

       return 1;

}

 

//---------------------------------------------------------------------------

extern "C" __declspec(dllexport) int WINAPI RbDllExec(const HWND dc,const char *in, int inlen, char *out, int outlen)

{

       int returnValue = 0;

       char instr[80];

       char wordnum[160];

 

       // Put the input string in a null terminated string

       memcpy(instr, in, inlen);

       instr[inlen] = '\0';

 

       // Convert to a text string

       dwrd(instr, wordnum);

 

       // Return the result

       outlen = strlen(wordnum);

       if (outlen)

               memcpy(out, wordnum, outlen);

       // returnValue = MessageBox(dc, wordnum,"Result value",MB_OK);

       // returnValue = 0;

       return returnValue;

}

 

//---------------------------------------------------------------------------

extern "C" __declspec(dllexport) int WINAPI RbDllVersion(void)

{

 return 100;

}

 

/**** Start of DWRD function ****/

void dwrd(char *strin,char *strout)

{

       int lstr;

       static char numbers[20][11] = {

               "          ","one       ","two       ",

               "three     ","four      ","five      ",

               "six       ","seven     ","eight     ",

               "nine      ","ten       ","eleven    ",

               "twelve    ","thirteen  ","fourteen  ",

               "fifteen   ","sixteen   ","seventeen ",

               "eighteen  ","nineteen  "};

 

       static char tenvals[10][11] = {

               "no        ","ten       ","twenty    ",

               "thirty    ","forty     ","fifty     ",

               "sixty     ","seventy   ","eighty    ",

               "ninety    "};

       char blank = ' ';

       char comma = ',';

       char dsign = '$';

       char dot = '.';

       char minus = '-';

       char ch;

       char tmoney[16];

       int offset;

       int tens;

       int lw, ls, n, intch, l;

 

       /*  CONVERT THE NUMBER. */

 

       tens = 0;

       memset(tmoney, ' ', 16);

       lw = 0;

       lstr = strlen(strin);

       ls = 16 - lstr + 1;

       strcpy(&tmoney[ls-1],strin);

 

       /*  PICK OFF THE CHARACTERS. */

 

       n = ls - 1;

next_digit:

       n++;

       if(n > 16) goto cleanup;

       ch = tmoney[n-1];

 

       /*  SKIP THE COSMETIC CHARACTERS. */

 

       if((ch == blank) || (ch == comma) || (ch == dsign)) goto next_digit;

       if(ch == minus) {

               memcpy(&strout[(lw+1)-1], "minus ", 6);

               lw = lw + 6;

               goto next_digit;

               }

       if((n == 4) || (n == 8) || (n == 12)) tens = 1;

 

       /*  SPECIAL STUFF WHEN WE HIT THE DECIMAL POINT. */

 

       if(ch == dot) {

               tens = 1;

               if(lw == 0) {

                       memcpy(&strout[(lw+1)-1], "zero ", 5);

                       lw = lw + 5;

                       }

               memcpy(&strout[(lw+1)-1], "dollars and ", 12);

               lw = lw + 12;

               if(tmoney[(n+1)-1] == '0') {

                       if(tmoney[(n+2)-1] == '0') {

                               memcpy(&strout[(lw+1)-1], "zero ", 5);

                               lw = lw + 5;

                               n = n + 2;

                               }

                       }

               goto next_digit;

               }

 

       /*  CONVERT A CHARACTER INTO AN OFFSET. */

 

       intch = ch - 48;

       if(tens) {

               if(intch <= 1) {

                       offset = 0;

                       if(intch == 1) offset = 10;

                       n = n + 1;

                       ch = tmoney[(n)-1];

                       intch = ch - 48 + offset;

                       }

               else {

                       l = lenstr(tenvals[(intch+1) - 1], 10);

                       if(l > 0) {

                               memcpy(&strout[(lw+1)-1], tenvals[(intch+1)-1], l+1);

                               lw = lw + l + 1;

                               }

                       tens = 0;

                       goto next_digit;

                       }

               }

       l = lenstr(numbers[(intch+1)-1], 10);

       if(l > 0) {

               memcpy(&strout[(lw+1)-1], numbers[(intch+1)-1], l+1);

               lw = lw + l + 1;

               }

       tens = 0;

       if(((n == 3) || (n == 7) || (n == 11)) && (intch != 0)) {

               memcpy(&strout[(lw+1)-1], "hundred ", 8);

               lw = lw + 8;

               }

       if(n == 5) {

               memcpy(&strout[(lw+1)-1], "million ", 8);

               lw = lw + 8;

               }

       if(n == 9) {

               memcpy(&strout[(lw+1)-1], "thousand ", 9);

               lw = lw + 9;

               }

       goto next_digit;

cleanup:

       memcpy(&strout[(lw+1)-1], "cents", 5);

       lw = lw + 5;

 

       /* Add the null terminator */

       strout[(lw+1)-1] = '\0';

 

       /*    ALL DONE.  */

 

       return;

}

/**** End of DWRD function ****/

 

/**** Start of LENSTR function ****/

int lenstr(char *str, int count)

{

       int i;

 

       i = count - 1;

       while (i >= 0) {

               if (str[i] != ' ') break;

               i--;

               }

       return (i+1);

}

/**** End of LENSTR function ****/

 


Making and Setting DLL

 

You can use a DLL (Dynamic Link Library) which you make for use in R:BASE. DLLs which you make can be used column and variable objects in Forms, Reports and Labels.

 

If you make a DLL, you must follow some rules of making DLLs.

 

Rules of making DLLs

 

Value of DLL's version        

 

int WINAPI RbDllVersion(void);        

You must specify to return 100.        

 

DLL name which is displayed in the Combo Box        

 

const char* WINAPI RbDllSpec(void);        

You designate the DLL function's name which is displayed in the Combo Box.        

 

DLL's ID        

 

int WINAPI RbDllId(void);        

It is the identity number of the DLL. You designate to return a number form 2 to 127.        

 

The function called by Form when drawing field        

 

int WINAPI RbDllDraw(const char*, const HDC, long, long, long, long)        

Return value : 0 success / Not 0 fails        

Argument : const char* Data strings

const HDC Device Context handle

long Left upper corner X position of object

long Left upper corner Y position of object

long Right lower corner X position of object

long Right lower corner Y position of object

 

The function called by Report or Label when drawing field        

 

int WINAPI RbDllDrawP(const char*, const HDC, long, long, long, long)        

Return value : 0 success / Not 0 fails        

Argument : const char* Data strings        

const HDC Device Context handle        

long Left upper corner X position of object        

long Left upper corner Y position of object        

long Right lower corner X position of object        

long Right lower corner Y position of object