Date: prev next · Thread: first prev next last
2013 Archives by date, by thread · List index


Hi :)
It's really good to see more people sharing code on this list.  Looks like a useful function to 
have.  

Sometimes it is more useful to have a working bit of code that is a mess rather than something 
elegant that doesn't work.  It follows the philosophy of "Release early and release often".  if 
it's working then people use it and maybe look at it and maybe edit it to improve it.  If it's 
beautiful code but doesn't work and doesn't get used then no-one sees it and it may never get 
completed.  So it's great to have something working.  Also i can't see anything wrong with the code 
anyway!  

If anyone can improve it or stream-line it then please post the code back to this mailing list, or 
at least to toodr.  

I noticed a couple of things in the Rem statements, Echos and "commented out" bits (that's the ' s, 
right?),  ie none of which affects the running of the program and most never even gets seen by 
users.  Digits only needs 1 g.  Accepsts is a tpyo of Accepts.  Exessive a tpyo of excessive.  If 
Rems and stuff are important i'm sure the Docs Team wouldn't mind trying to de-geekify them or 
maybe people here might but i think it really doesn't make much difference.  

Just out of curiosity would it be tough to translate this sort of thing into Python and make it 
into an Extension?  Perhaps joined with other code that has been on the mailing list here?  

@ Toodr: Would you mind giving permission to license your code under the copyleft licensing used by 
the rest of the code?  So people could share and modify?  Looks like you said it would be fine, 
informally.  GPL?  LGPL?  

Thanks and regards from 
Tom :)  





________________________________
From: toodr <todortakov@gmail.com>
To: users@global.libreoffice.org 
Sent: Saturday, 20 July 2013, 0:26
Subject: [libreoffice-users] Re: Visible currency rounding


I had the same problem. I needed to implement the so called Bankers' Rounding
Function, which would round with respect to the 4/5 rule. And finally I
ended doing it myself in a short Function in LO Basic. I tried my best,
although math  and programming are not my strong sides. So here it is,
together with a Subroutine called "rounded_test" and the very Function is
called "Rounded".


Sub rounded_test
N=20.45454545454545454545
N= Rounded(N)
N=0
End Sub

REM Banker's Rounding Function
REM Accepsts parameter as Double with or without a sign +/-
REM Returns Double  with or without a sign +/-,rounded to the second diggit
after the comma separator
Function Rounded (NumD As Double)
Dim NumI as Integer
Dim position as Integer
position=0
Dim overflow as Integer
overflow=0
Dim NumS as String

REM initilize 2 arrays (integer and string) and we save the number into them
NumS=Format( NumD, "0.################################################")
len01=LEN(NumS)
Dim Stringarray(len01-1) as String
Dim Integerarray(len01-1) as Integer
For i=1 to len01
string0=Mid(NumS,i,1)
    If string0="." Or string0="," Then
    Stringarray(i-1)="."
    Integerarray(i-1)=0
    position=i
    Else
    Stringarray(i-1)=string0
    Integerarray(i-1)=Val(string0)
    End if
next i

string0="" 'Emptying the variable which will be used to return the number -
string
REM Rounding
If position=0 Then 'an integer without a fraction part - return the number
as it is!
    Rounded=NumD
    Exit Function
Else
End If
If len01-position>2 Then     'will be rounding
    For j=1 to len01-position-2        '(len01-position-2) number of diggits till the
end of the number string which will be dropped out
        If Integerarray(len01-j)>5 Or overflow=1 Or (Integerarray(len01-j)=5 And
(Stringarray(len01-j-1)="1" Or Stringarray(len01-j-1)="3"  Or
Stringarray(len01-j-1)="5"  Or Stringarray(len01-j-1)="7"  Or
Stringarray(len01-j-1)="9")) Then
            overflow=1
            If Integerarray(len01-j-1)+overflow<=9 Then 
            Integerarray(len01-j-1)=Integerarray(len01-j-1)+overflow
            overflow=0
            Else
            Integerarray(len01-j-1)=0
            overflow=1
            End if
        Integerarray(len01-j)=0
        Stringarray(len01-j)="0"
        Stringarray(len01-j-1)=CStr(Integerarray(len01-j-1))
        Else
        Integerarray(len01-j)=0
        Stringarray(len01-j)="0"
        End If
    Next j
'If we have some left over, remaining after the removal of the exessive
diggits, we shall distribute it 
'among the remaining integer and fractional part
    If overflow=1 Then
        For k=position to 0 step -1
        If k=position-1 Then goto Lbl    'skip this if it is a comma or point
separator
        If k=0 And (Stringarray(k)="-" Or Stringarray(k)="+") Then goto Lbl    'skip
this if it is a +/- sign
            If Integerarray(k)+overflow<=9 Then
            Integerarray(k)=Integerarray(k)+overflow
            overflow=0
            Else
            Integerarray(k)=0
            overflow=1
            End if
        Stringarray(k)=CStr(Integerarray(k))
Lbl:    next k
    Else
    End If
'Check if we have a +/- sign in front
    If Stringarray(0)="-" Or Stringarray(0)="+" Then 
        string0=Stringarray(0)
        'If we have still some overflow remaining,
        If overflow=1 Then
            'We add 1 in front but, after the sign
            string0=string0 & "1"
            'Construct the remainder of the number
            For i=2 to len01
            string0=string0 & Stringarray(i-1)
            next i
        Else 'Without a sign in front
            'Construct the remainder of the number
            For i=2 to len01
            string0=string0 & Stringarray(i-1)
            next i
        End If
    Else
        'If we have still some overflow remaining,
        If overflow=1 Then
            'We add 1 in front
            string0=string0 & "1"
            'Construct the remainder of the number
            For i=1 to len01
            string0=string0 & Stringarray(i-1)
            next i
        Else 'Without a sign in front
            'Construct the remainder of the number
            For i=1 to len01
            string0=string0 & Stringarray(i-1)
            next i
        End If
    End If
    string0=Format( Val(string0),
"0.################################################")
    len01=LEN(string0)
    For i=1 to len01
        string2=Mid(string0,i,1)
        If string2="," Then Mid(string0,i,1)="."
    next i
    Rounded=Val(string0)
Else 'if the number is integer or has a fractional part with up to 2 diggit
after the comma separator, we return it as it is
    Rounded=NumD
End if
End Function





You can call it for each line (item) in an invoice. It will take the number
you through at it and will return it rounded to the second diggit after the
comma or point separator. Then when you sum the invoice up - the numbers
will always be consistent and correctly rounded.

This is not the best of programming though, but it works.
I hope it will help someone.
Feel free to modify and use it as you please.
Cheers,
toodr



--
View this message in context: 
http://nabble.documentfoundation.org/Visible-currency-rounding-tp4065342p4066292.html
Sent from the Users mailing list archive at Nabble.com.

-- 
To unsubscribe e-mail to: users+unsubscribe@global.libreoffice.org
Problems? http://www.libreoffice.org/get-help/mailing-lists/how-to-unsubscribe/
Posting guidelines + more: http://wiki.documentfoundation.org/Netiquette
List archive: http://listarchives.libreoffice.org/global/users/
All messages sent to this list will be publicly archived and cannot be deleted




-- 
To unsubscribe e-mail to: users+unsubscribe@global.libreoffice.org
Problems? http://www.libreoffice.org/get-help/mailing-lists/how-to-unsubscribe/
Posting guidelines + more: http://wiki.documentfoundation.org/Netiquette
List archive: http://listarchives.libreoffice.org/global/users/
All messages sent to this list will be publicly archived and cannot be deleted

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.