Code: Select all
;- Currency Functions Library
; written by Frarth Jan-2011
EnableExplicit
Structure CharacterType
c.c[0]
EndStructure
; handles values up to 999 999 999 999.99 (1 trillion - 1 (en), 1 biljoen - 1 (nl))
#Currency_MPV = 99999999999999 ;maximum positive value (incl. 2 digits precision)
#Currency_MNV = -99999999999999 ;maximum negative value (incl. 2 digits precision)
#Currency_MVL = 14 ;maximum value length (checks with positive values)
Global Currency_Error.b
Procedure.s String_Include(Text.s, Filter.s)
Protected *ptr.CharacterType = @Text
Protected Count.i = MemoryStringLength(*ptr) - 1
Protected c.s{1}, i.i, r.s = ""
; collect characters by filter
For i = 0 To Count
c = Chr(*ptr\c[i])
If FindString(Filter, LCase(c), 1) > 0
r + c
EndIf
Next
ProcedureReturn r
EndProcedure
Procedure.i String_DECPOS(Text.s)
;return position of decimal sign
Protected *ptr.CharacterType = @Text, n.i = MemoryStringLength(*ptr) - 1, i.i
; find decimal sign
For i = n To 0 Step -1
Select *ptr\c[i]
Case '.', ','
ProcedureReturn n - i + 1
EndSelect
Next
EndProcedure
Procedure.b Currency_VALIDVAL(Value.q)
If Value >= #Currency_MNV And Value <= #Currency_MPV
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure.b Currency_VALIDSTR(Text.s)
Protected s.s = Text
;remove possible sign
Select Left(s, 1)
Case Chr(43), Chr(45)
s = Mid(s, 2)
EndSelect
; check length
If Len(s) <= #Currency_MVL
;check content
If s = String_Include(s, "0123456789.,")
ProcedureReturn #True
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure.q Currency_Val(Text.s)
; return currency in string format as integer
Protected l.s, r.s, f.i, n.i, v.q
; init
Currency_Error = #False
; find decimal sign position
f = String_DECPOS(Text)
If f > 0
; left part
l = Left(Text, Len(Text) - f + 1)
; remove possible thousand separators
l = ReplaceString(l, Chr(44), "")
l = ReplaceString(l, Chr(46), "")
; right part
r = Right(Text, f - 1)
n = Len(r)
; make right part 3 digits
If n < 3
r = LSet(r, n + (3 - n), Chr(48))
EndIf
r = Left(r, 3)
; round off to 2-digit precision
n = Val(Right(r, 1))
If n > 4
n = 1
Else
n = 0
EndIf
; build string
Text = l + Left(r, 2)
Else
; add the 2-digit precision
Text + "00"
EndIf
; check
If Currency_VALIDSTR(Text)
; convert to integer
v = Val(Text)
; round to nearest
If v >= 0
v + n
Else
v - n
EndIf
; check value
If Currency_VALIDVAL(v)
ProcedureReturn v
EndIf
EndIf
Currency_Error = #True
ProcedureReturn 0
EndProcedure
Procedure.s Currency_Str(Value.q)
; return currency in integer format as string
Protected n.i, l.s, r.s, s.s{1}
;init
Currency_Error = #False
; check
If Currency_VALIDVAL(Value)
; <0? make positive, save sign
If Value < 0
s = Chr(45)
Value = -Value
EndIf
; convert to string
r = Str(Value)
n = Len(r)
; add leading zeros
If n < 3
r = RSet(r, n + (3 - n), Chr(48))
n = Len(r)
EndIf
; left part
l = Left(r, n - 2)
; build string
r = s + l + Chr(46) + Right(r, 2)
Else
Currency_Error = #True
EndIf
ProcedureReturn r
EndProcedure
Procedure.s Currency_Format(Value.q)
Protected *ptr.CharacterType, b.i, c.i, i.i, n.i, r.s, t.s, s.s{1}
; sign
If Value < 0
s = Chr(45)
Value = -Value
EndIf
; convert to text
t = Currency_Str(Value)
; string address
*ptr = @t
n = MemoryStringLength(*ptr) - 1
; sep count base
b = 7
; find decimal sign
For i = n To 0 Step -1
c + 1
If c = b
r = Chr(44) + r
b + 3
EndIf
r = Chr(*ptr\c[i]) + r
Next
r = s + r
ProcedureReturn r
EndProcedure
;- EXAMPLES
Global Text.s, Text1.s, Text2.s
Global Value.q, Value1.q, Value2.q, Value3.q
;- example 1
Text = "0.015"
Value = Currency_Val(Text)
Debug Currency_Str(Value)
;- example 2
Text1 = "3.501"
Text2 = "4.605"
Value1 = Currency_Val(Text1)
Value2 = Currency_Val(Text2)
Value3 = Value1 + Value2
Debug Currency_Str(Value3)
;- example 3
Text = "999999999999.994"
Value = Currency_Val(Text)
If Not Currency_Error
Debug Value
Debug Currency_Str(Value)
Else
Debug "Overflow!"
EndIf
;- example 4
Text = "999999999999.995"
Value = Currency_Val(Text)
If Not Currency_Error
Debug Value
Debug Currency_Str(Value)
Else
Debug "Overflow!"
EndIf
;- example 5
Text = "11222333444,55"
Value = Currency_Val(Text)
Debug Value
Debug Currency_Format(Value)