Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to get the return value of a prg? 6

Status
Not open for further replies.

Mandy_crw

Programmer
Jul 23, 2020
585
PH
Hi everyone, i found a program from this site, and saw it will be useful to my project, my question is how can i copy the reurn value of the program? I want to put the return value LcPhrase to a variable so that i could print it... thanks in advance....

** Author : Ramani (Subramanian.G)
** áFoxAcc Software / Winners Software
** ** Type á: Freeware with reservation to Copyrights
** Warranty : Nothing implied or explicit
** Last modified : June, 2003
*********************************************************
** How to Run..
** 1. Save the following code as Num2Word.PRG
** 2. From within your PRG or Report call it as
** áááNum2Word(nYourAmount)
*********************************************************
** Modify decimal places suitably, if > 2 decimals required
*********************************************************

** FUNCTION num2word

LPARAMETER amt
amt = ABS(amt)

IF amt > 999999999999.99 && => 1000 billion
=MESSAGEBOX("Amount exceeds word convertion provision. Contact system administrator", ;
0+16, "CAUTION. Check total amount !")
ENDIF
IF amt = 0
RETURN "Zero Only."
ENDIF

** used by Function numWord

PRIVATE pcWord1, pcWord2, pcWord3, pcWord4, pcWord5, pcWord6, pcWord7, ;
pcWord8, pcWord9, pcWord10, pcWord11, pcWord12, pcWord13, pcWord14, ;
pcWord15, pcWord16, pcWord17, pcWord18, pcWord19, pcWord20, pcWord30, ;
pcWord40, pcWord50, pcWord60, pcWord70, pcWord80, pcWord90
pcWord1 = "One "
pcWord2 = "Two "
pcWord3 = "Three "
pcWord4 = "Four "
pcWord5 = "Five "
pcWord6 = "Six "
pcWord7 = "Seven "
pcWord8 = "Eight "
pcWord9 = "Nine "
pcWord10 = "Ten "
pcWord11 = "Eleven "
pcWord12 = "Twelve "
pcWord13 = "Thirteen "
pcWord14 = "Fourteen "
pcWord15 = "Fifteen "
pcWord16 = "Sixteen "
pcWord17 = "Seventeen "
pcWord18 = "Eighteen "
pcWord19 = "Ninteen "
pcWord20 = "Twenty "
pcWord30 = "Thirty "
pcWord40 = "Forty "
pcWord50 = "Fifty "
pcWord60 = "Sixty "
pcWord70 = "Seventy "
pcWord80 = "Eighty "
pcWord90 = "Ninety "
**
LOCAL lcNumPhrase, lcNumStr

m.lcNumphrase = ""
m.lcNumStr = STR(amt,17,4)

IF VAL(SUBSTR(m.lcNumStr,1,3)) > 0 && Amount in Billions
m.lcNumphrase = m.lcNumphrase + Numword(SUBSTR(m.lcNumStr,1,3)) + ;
" Billion "
ENDIF

IF VAL(SUBSTR(m.lcNumStr,4,3)) > 0 && Amount in millions
m.lcNumphrase = m.lcNumphrase + Numword(SUBSTR(m.lcNumStr,4,3)) + ;
" Million "
ENDIF

IF VAL(SUBSTR(m.lcNumStr,7,3)) > 0 && Amount in thousands
m.lcNumphrase = m.lcNumphrase + Numword(SUBSTR(m.lcNumStr,7,3)) + ;
" Thousand "
ENDIF

IF VAL(SUBSTR(m.lcNumStr,10,3)) > 0 && Amount below thousands
m.lcNumphrase = m.lcNumphrase + Numword(SUBSTR(m.lcNumStr,10,3))
ENDIF

IF VAL(SUBSTR(m.lcNumStr,14,2)) > 0 && Amount in Decimals
** needs tingering depending on digits - Default is 2 decimals
IF LEN(ALLTRIM(m.lcNumphrase)) > 1
m.lcNumphrase = ALLTRIM(m.lcNumphrase) + " and "
ELSE
m.lcNumphrase = "Zero and "
ENDIF
m.lcNumphrase = m.lcNumphrase + SUBSTR(m.lcNumStr,14,2) + "/100"
ENDIF

IF LEN(ALLTRIM(m.lcNumphrase)) > 1
m.lcNumphrase = ALLTRIM(m.lcNumphrase) + " Only."
ENDIF

? m.lcNumPhrase

RETURN m.lcNumphrase


*********************************************************
** Called by: numtoword() (function in NUMWORD.PRG)
*********************************************************


FUNCTION numword
LPARAMETERS tStr

LOCAL lnStr, lcPhrase, lcStr
lcPhrase = " "
lnStr = VAL(tStr)

** Hundredth position
IF lnStr > 99
lcStr = LEFT(tStr,1)
lcPhrase = pcWord&lcStr + "Hundred "
ENDIF

** Balance Position
lnStr = VAL(RIGHT(tStr,2))
IF BETWEEN(lnStr,1,20)
lcStr = ALLTRIM(STR(lnStr))
lcPhrase = lcPhrase + pcWord&lcStr
ENDIF
IF BETWEEN(lnStr,21,99)
IF lnStr > 20
lcStr = SUBSTR(tStr,2,1)+"0"
lcPhrase = lcPhrase + pcWord&lcStr
ENDIF
IF RIGHT(tStr,1) > '0'
lcStr = RIGHT(tStr,1)
lcPhrase = lcPhrase + pcWord&lcStr
ENDIF
ENDIF
RETURN ALLTRIM(lcPhrase)
 
This is from faq184-2848.

No need to copy code of a FAQ, simply copy the FAQ number faq184-2848 and a link to the FAQ is generated.

Well, the usage is given in the header of the code:

Code:
** How to Run..
** 1. Save the following code as Num2Word.PRG
** 2. From within your PRG or Report call it as
**    Num2Word(nYourAmount)

The ááá in the FAQ must be an artifact. Of course, when the PRG is named Num2Word.prg you call it by Num2Word().

There is no need to put it into a variable, once you SET PROCEDURE TO the PRG or have it in the search path by SET PATH to the directory with the prg, the call to it will work. A report control can have
Num2Word(numericfieldname) and that will print as the word the PRG generates and returns.

Chriss
 
Just to summarise ...

Code:
* Assume lnNum contains the number that you want to convert. 
lcWord = Num2Word(lnNum)
* lcword will now contain the converted number

Does that answer the question?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mandy,

This is a procedure I wrote several years ago to print the (US) dollars & cents on a check. I haven't tested it recently but you're welcome to use or change it as you like.

Steve

Code:
******************************** convert number to word for checks
* called by Checks, Merge.Command1 ("Create")
PROCEDURE Numword
LPARAMETERS nNum
LOCAL nDollars, nCents
nDollars = INT(m.nNum)
cDollars = TRANS(INT(m.nNum),'@l 999999999')  && "000012345"
cUnits = ',One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Eleven,' ;
  + 'Twelve,Thirteen,Fourteen,Fifteen,Sixteen,Seventeen,Eighteen,Nineteen,'
cTens = ',Twenty,Thirty,Forty,Fifty,Sixty,Seventy,Eighty,Ninety,'
cWords = ''
FOR ii = 1 TO 3  && 3 groups of 3 digits (up to 999 million)
 cXxx = SUBSTR(m.cDollars, 3*m.ii-2, 3)
 cWord3 = ''
 nHundreds = VAL(LEFT(m.cXxx,1))
 IF m.nHundreds > 0
  comma1 = AT(',',m.cUnits,m.nHundreds)
  comma2 = AT(',',m.cUnits,m.nHundreds+1)
  cWord3 = SUBSTR(m.cUnits,m.comma1+1,m.comma2-m.comma1-1) + ' Hundred '
 ENDIF
 nTens = VAL(RIGHT(m.cXxx,2))
 IF m.nTens > 0
  IF m.nTens >= 20
   comma1 = AT(',',m.cTens,INT(m.nTens/10)-1)
   comma2 = AT(',',m.cTens,INT(m.nTens/10))
   cWord3 = m.cWord3 + SUBSTR(m.cTens,m.comma1+1,m.comma2-m.comma1-1) + ' '
   nOnes = VAL(RIGHT(m.cXxx,1))
   IF m.nOnes > 0
    comma1 = AT(',',m.cUnits,m.nOnes)
    comma2 = AT(',',m.cUnits,m.nOnes+1)
    cWord3 = m.cWord3 + SUBSTR(m.cUnits,m.comma1+1,m.comma2-m.comma1-1) + ' '
   ENDIF
  ELSE
   comma1 = AT(',',m.cUnits,m.nTens)
   comma2 = AT(',',m.cUnits,m.nTens+1)
   cWord3 = m.cWord3 + SUBSTR(m.cUnits,m.comma1+1,m.comma2-m.comma1-1) + ' '
  ENDIF
 ENDIF
 IF NOT EMPTY(m.cWord3)
  cWords = m.cWords + m.cWord3 ;
    + IIF(m.ii=1, 'Million ', IIF(m.ii=2, 'Thousand ', ''))
 ENDIF
NEXT
RETURN IIF(EMPTY(m.cWords), 'Zero', TRIM(m.cWords)) ;
  + ' And ' + TRANS(100*(m.nNum-m.nDollars),'@l 99') + '/100'
 
And here's one I wrote a few years ago. Like Steve's, it's intended mainly to print dollar+cents (or pound+pence, or euros+eurocents, etc.) in words on a cheque.

Code:
FUNCTION AmountInWords
* Given an amount up to 99,999.99, this function returns one of the digits
* of the whole-number part, as a word. This can be used to generate the
* "amount in words" boxes of a cheque.

* First param is the amount. Second param indicates the required digit
* (1 = units, 2 = tens, 3 = hundreds, 4 = thousands, 5 = ten thousands).

LPARAMETERS tnAmount, tnDigit

LOCAL lcString, lnV

lcString = TRANSFORM(tnAmount, "@L 99999")
lnV = VAL(SUBSTR(lcString, 6 - tnDigit, 1))
RETURN ICASE( ;
  lnV = 0, "ZERO", lnV = 1, "ONE", lnV = 2, "TWO", ;
  lnV = 3, "THREE", lnV = 4, "FOUR", lnV = 5, "FIVE", ;
  lnV = 6, "SIX", lnV = 7, "SEVEN", lnV = 8, "EIGHT", ;
  lnV = 9, "NINE", lnV = 10, "TEN" )

ENDFUNC

For any given amount, you have to call the function several times: once for each digit. I did it that way so that you can correctly position each word in the appropriate box on the cheque.

So, typically, you would call this from a report. The report would contain, say, five adjacent fields in a row, each one in a position that corresponds to one of the "amount" boxes on the cheque. In the first (left-most) of the fields, the expression would be [tt]AmountInWords(Ch_Total, 5)[/tt], whe Ch_Total is a numeric value representing the total amount. The second field would be [tt]AmountInWords(Ch_Total, 4)[/tt], and so on down to [tt]AmountInWords(Ch_Total, 1)[/tt].

The pennies or cents don't get converted, as these are normally printed as plain numbers on the cheque.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi everyone... i have included this code but it always say "Variable m.lcNumPhrase is not found." The this.Parent.text1.value is the text where I input number where it should be converted into words....

code...
code...​

lcword = " "

amt = this.Parent.text14.value
num2word(amt)

lcWord = Num2word(m.lcNumphrase)

but m.lcNumPhrase does appear on my form at the bottom... I want to get the value of m.lcNumPhrase in the calling program which is my project... thanks in advance...
 
I only mentioned lcWord as an example of the variable that was to hold the result. You don't have to take it literally.

You just need something like this:

Code:
amt = this.Parent.text14.value
lcNumphrase = num2word(amt)

You can now go ahead and use lcNumphrase in your program (or report, or whatever).

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
[bigsmile] Thank you Mike, it worked like magic! I really love your example together with Steve… ill try to read carefully to learn more…. thank you for being so kind… God bless…
 
Am i violating something if i use codes or take codes from here and put in my project?
 
Hi Mandy,
As I said you are welcome to use any of my code for your profit. amusement or whatever.

I'm not possessive about my code. 99% of it has been customized - written for companies or organizations having unique requirements (I'm sure many of us have done the same). I believe most of my code would be of little use anyway for other companies even with similar businesses.

Story: A while ago I was requested to quote a price for full ownership of my timeshare app. I refused and told her she could do anything she wanted with it because I knew it was so customized it would be of little value to any other company. (I found out later she was selling the company and wanted to include my software in the sale). The other company (big) ended up using their own software instead. I heard it was horrible.

The moral of the story (in my opinion) is in the long run I (we?) benefit by sharing.

Steve
 
Thats so unselfish of you… Thank you so much Steve… God bless you…
 
I see you already solved this, but...

Mandy_crw said:
Variable m.lcNumPhrase is not found.

You say you get this error when you do
Code:
Num2word(m.lcNumphrase)

It should be clear from the get go that the resulting word is returned and what you pass in has to be a numeric value.
That's what is indicated by the n in Ramanis' usage comment, when he says you call it by Num2Word([highlight #FCE94F]n[/highlight]YourAmount) that parameter has to be the number.

You actually already had the right Num2Word call right before that:
Code:
amt = this.Parent.text14.value
num2word(amt)

Well, that just doesn't store the result of num2word(amt) anywhere, the result value is just lost. So all that's missing is a prefix of "variable =":
Code:
amt = this.Parent.text14.value
lcNumphrase = num2word(amt)

It's like that for any function call, also for predefined functions. If you want to store the result of a call to DATE() into a variable, then don't write Date(variable) but you write variable=Date(), don't you?

And by the way, if num2word(amt) would error with a message stating something about a wrong data type, then you'd need to ensure that the text14.value is a number and not a string. There's a risk of that to still happen, if you don't ensure that textbox is numeric. In general textboxes are - as the name says - for (short) text and if you don't have a controlsource of a numeric field or an initial numeric value, amt=this.Parent.text14.value would make amt the data type string or in short "C", not numeric or "N".

Never ever forget while VFP is not a so-called "strictly typed language", functions are in most cases defined to process only specific data types as parameters and while technically you can pass in other data types as requested by the function author, a function would then usually fail. In the best case it could check the passed in parameter types and give out a warning. In Ramanis' code the first thing his function does with the amt parameter is amt = ABS(amt), which errors if amt isn't numeric. And, by the way, also means that his function doesn't return the prefix "minus" of you pass in a negative number. And remember in data types "1000" also isn't numeric just because it's still a number printed on the screen or shown in a textbox. That only looks like a number to you but technically is text.

There are exceptions to the rule, for example TRANSFORM() acts on any parameter type. It's still a very natural and unsurprising exception as the intention of that function is to turn any data type into its string representation. There's an even simpler command which does that, the "? | ?? Command". It just does not return the string, it prints it to the activated form, usually the _Screen.

The Num2Word function already tells in its name that it expects aa number as input, not just a string of a number and surely not the variable you want to set to the word(s) for that number.

These things have to be on your mind all the time. This is "your daily bread" as a programmer. And it usually becomes natural, you don't need to concentrate on it, it becomes an auto pilot thing. A language like JavaScript would let you pass with computing "1000"+1 as 1001, because it's so loosely defined. But I'll stop here, before lamenting on how bad JavaScript is. It's still great in other aspects.

Chriss
 
Mandy said:
Am i violating something if i use codes or take codes from here and put in my project?

In general, you shouldn't assume that, just because something is posted on the internet, that it is free of copyright. This applies to program code, as well as text, images, maps, and other things. The copyright in all of those things belongs to the person who created it, unless they have specifically given it up.

However, it's reasonably safe to assume that, if someone posts program code in a forum, then they are happy for anyone to use it. They wouldn't have posted it otherwise. After all, the whole point of forums such as Tek Tips is to share knowledge.

That's certainly true in my case. When I post code in Tek Tips, anyone is free to use it. The only thing I would object to is if someone claims the code is their own. But that is very rare.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Chriss... thank you for your comprehensive explanation.... Mike, Thanks to you always... God Bless.... a little enhancement on my project... i just wonder why i dont stop editing my project, even if its already working... i always want more.... [bigsmile] an through your help, i always have what i want... thank you eveyrone.... this forum is really full of amazing people/programmers!
 
One thing I have seen multiple times is the anger about sites demanding rights from you. Legally they have to have the right to post your posts so by subscribing or joining to a site you usually agree to terms of use that ask you to the legally necessary permission to publish your post.

Copyright laws are subject of many opinions but are clearly differentiating the right to publish something from the ownership and copyright and even more so from patents. Also, unlike patents, the copyright is an automatic right protecting the authors intellectual property or work, the question in detail becomes what is copyrightable, what is worth to call "intellectual property".

You also don't waive that right just because the site is allowed to post it. The whole subject has resulted in all the license schemes you can use for hosting projects and such. As Mike says it would be nonsense if someone giving you a solution would need to painstakingly give you permission to also use it. And, for example, you couldn't claim that variable=function(parameters) is copyright by who posted it first somewhere.

I wouldn't necessarily say what I post is automatically free to use by anyone. If detecting usage of a complex enough solution I could still claim copyright for it. It's questionable whether something similar wasn't already posted as solution somewhere else, not only as forum post but blog article or other publication. Well, that's more a question about patents anyway, but also the automatic copyright, as said, depends on that intellectual property worth noting it as such.

If I as a software author would want something to be explicitly known to have the intention to be copyrighted by me, I would think of making it a repository/project hosted with an explicit license I pick, and then refer to that in a forum to make this very clear. Also just writing (c) Your Name in a comment does neither grant you the copyright nor does omitting a copyright note automatically make what you post public domain.

But surely, if at some point Mike noting his code in your project (actually how, if you wouldn't publish you projects source code?) would sue you of copyright infringement for using it, I assume he'd lose a lawsuit because the outset and intention of answering your question in a forum only makes sense including the permission to use it. I think a court would judge this to be implicit, even if not explicitly expressed.

I won't dive into the question whether any forum like tek-tips core intent is to build a knowledgebase usable for everyone in terms of what law applies to ownership and copyrights and even patents. Surely it's a normal intention of forums, not only regarding the topic of programming. Even less so thinking about posting something from an own repository that is in fact copyrighted taking that part out of the copyright or any such detail questions.

Of course, I am not a lawyer, but I'm very sure copyright - as long as something is actually copyrightable - is automatic, you even stay the author and have the copyright when explicitly giving something into the public domain. You just state that you will never enforce your copyright. A patent - on the other hand - is something that you need to explicitly claim and the patent office will grant it after you pay for that, which is one hurdle, and they also research that there is no previous patent holder. In that stage it's claimed but not granted it's the infamous patent pending.

So just speaking for me and I guess Mike Lewis will concur, if I'd want something to be protected by an explicit license, I'd organize it at sites like Github or Sourceforge, where choosing a license is a first step of starting a project. In some posts members actually point to their or other peoples repositories you can of course find the conditions in the license assigned.

Chriss
 
I just hint on 23 Apr 22 05:39

And indeed you can SET PROCEDURE - OR - as I also said, have it in the search path.
That first post did somehow not solve it, ask Mandy why not. I can't force her to understand, but at least, like Mike Lewis, I'm patient.

Chriss
 
Thanks myearwood and chriss.... but what if i have alot of return value, like i have two or more needed variable to return to a calling prgram? is it possible?
 
Mandy,

Basically, a function can only ever return one value. (That's true in all programming languages, not just VFP.)

However, it is also possible for a function to return an object, and an object can have multiple properties. So you could create an object within the function, store the relevant values in its properties, and return the object to the calling program.

Do you know how to do that? If not, I (or someone else here) can show you some code.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top