Jump to content

Subtraction Causing Extra Decimal Places - SOLVED


Recommended Posts

Having some issues here... I'm trying to pull two numbers from a .tab text file, and one from an internal control inside another program. The only field I can access is the static text control that the program, and when I'm trying to subtract the two to double-check my numbers, I'm getting extra decimals added in. I'm not sure where they're coming from.

I've tried using Round() to drop it down to 2 places, in the current iteration I'm trying to use StringFormat to cut it down to 2 places, but every time I try it out, an extra 0.000000001 or so is added to the $vDifference variable. Here's my code (it's sloppy, forgive me - first attempt at GUIs as well).

 

UPDATE: Solved. Melba is a genius, and I have no idea how to syntax.

 

#include <File.au3>
#include <FileConstants.au3>
#include <Array.au3>
#include <MsgBoxConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

;~ Declare Variables
Global $vSourcePlanName
Global $vSourceRxNum
Global $vSourceRxPaid
Global $vIsolatedRxDate
Global $vIsolatedRxNum
Global $vIsolatedRxPaid
Global $vRunningTotal
Global $aTextArray
Global $vSourceArrayLine
Global $aPlanArray
Global $vPlanName
Global $vPlan
Global $vNocTotal
Global $vTabFile = "C:\Users\Owner\Downloads\EPIC_PaymentReport.tab"
Global $vPioneerClass = "0.2804c64"
Global $pButton = "[CLASS:WindowsForms10.BUTTON.app."
Global $pEdit = "[CLASS:WindowsForms10.EDIT.app."

;~ Create array from payment .tab file
Func CreatePaymentArray()
   _FileReadToArray ($vTabFile, $aTextArray, Default, @TAB)

;~ Create Result Array to be filled with data
Global $aResultArray[0][4]

;~ Check if $aTextArray is valid and pull variables from it
   If IsArray($aTextArray) Then
      $iMax = UBound($aTextArray)
      For $i = 0 to $iMax -1;

;~ Save Plan Name to Variable
         $vSourcePlanName = $aTextArray[$i][1]

;~ Save Rx Date to Variable
         $vSourceRxDate = $aTextArray[$i][2]
         Local $vSourceRxDateYear = StringRight($vSourceRxDate,4)
         $vSourceRxDate = StringReplace($vSourceRxDate,"/","")
         $vSourceRxDate = $vSourceRxDateYear & StringTrimRight($vSourceRxDate,4)

;~ Save Rx Number to Variable, Strip White Space, and - if no text - change to Number
         $vSourceRxNum = $aTextArray[$i][3]
         $vSourceRxNum = StringStripWS($vSourceRxNum, $STR_STRIPALL)
         If StringIsDigit($vSourceRxNum) Then
            $vSourceRxNum = Number($vSourceRxNum)
         EndIf


;~ Save Rx Paid Amount to Variable and change to Number
         $vSourceRxPaid = $aTextArray[$i][5]
         $vSourceRxPaid = StringStripWS($vSourceRxPaid, $STR_STRIPALL)
         If StringIsDigit($vSourceRxPaid) Then
            $vSourceRxPaid = Number($vSourceRxPaid)
         EndIf

;~ Add Payment Data to $aResultArray
         $vSourceArrayLine = $vSourcePlanName & "|" & $vSourceRxDate & "|" & $vSourceRxNum & "|" & $vSourceRxPaid
         _ArrayAdd($aResultArray, $vSourceArrayLine)
      Next

;~    _ArrayDisplay($aResultArray, "Result Array", Default, 8)
   EndIf


;~ Create $aPlanArray - an Array of Plan Names
   $aPlanArray = _ArrayUnique($aResultArray)
;~ _ArrayDisplay($aPlanArray)
   Global $iPlanMax = UBound($aPlanArray)
EndFunc


;~ Create GUI
Func CreateWindow()
   Local $hGUI = GUICreate("Apply Payments", 285, 250, 550, 300, -1)
   Local $idComboBox = GUICtrlCreateCombo("Choose Insurance Plan",10,10,230)
   Local $vPaymentDateLabel = GUICtrlCreateLabel("Payment Date:",10,152)
   Local $vPaymentDateInput = GUICtrlCreateInput("mm/dd/yyyy",85,149,75)
   Local $vEpicDateLabel = GUICtrlCreateLabel("EPIC Date:",10,175)
   Local $vEpicDateInput = GUICtrlCreateInput("mm/dd/yyyy",85,171,75)
   Local $idOkButton = GUICtrlCreateButton("OK",250,8,25,25)
   Local $idOpenButton = GUICtrlCreateButton("Open...",10,215,50)
   Local $idContinueButton = GUICtrlCreateButton("Continue",120,215,75)
   GUICtrlSetState($idContinueButton,$GUI_DISABLE)
   Local $idCancelButton = GUICtrlCreateButton("Cancel",200,215,75)
   Local $vPlanLabel = GUICtrlCreateLabel("Insurance Plan Selected: ", 10, 40)
   Local $vPlanSelect = GUICtrlCreateLabel("None", 135, 40, 120)
   Local $vNocLabel = GUICtrlCreateLabel("Number of Claims: ", 10, 60)
   Local $vNoc = GUICtrlCreateLabel(0,100,60,20)
   Local $vTotalPayLabel = GUICtrlCreateLabel("Total Payment Amount: ", 10, 80)
   Local $vTotalPayAmt = GUICtrlCreateLabel(0,125,80,75)
   Local $vMinDateLabel = GUICtrlCreateLabel("Date Range - From ", 10, 100)
   Local $vMinDate = GUICtrlCreateLabel("yyyyMMdd", 105, 100)
   Local $vMaxDateLabel = GUICtrlCreateLabel("To ", 87, 120)
   Local $vMaxDate = GUICtrlCreateLabel("yyyyMMdd", 105, 120)



   GUICtrlSetState(-1, $GUI_DROPACCEPTED) ; to allow drag and dropping
   GUISetState(@SW_SHOW)

   If IsArray($aPlanArray) Then
      For $i = 3 to $iPlanMax -1;
         $vPlanName = $aPlanArray[$i]
         GUICtrlSetData($idComboBox,$vPlanName)
      Next
   EndIf

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
        Case $idOkButton
            $vPlan = GUICtrlRead($idComboBox)

            If Not($vPlan == "Choose Insurance Plan") Then
;~              Search $aResultArray for all entries with Plan Name
               Global $aPlanSearch = _ArrayFindAll($aResultArray, $vPlan, Default, Default, Default, Default, 0)
               If IsArray($aPlanSearch) Then
                  $vRunningTotal = 0
                  $jMax = UBound($aPlanSearch)
                  For $j = 0 to $jMax -1;
                     $vIsolatedRxDate = $aResultArray[$aPlanSearch[$j]][1]
                     $vIsolatedRxNum = $aResultArray[$aPlanSearch[$j]][2]
                     $vIsolatedRxPaid = $aResultArray[$aPlanSearch[$j]][3]
;~                   MsgBox($MB_OK,"",$vIsolatedRxDate & "|" & $vIsolatedRxNum & "|" & $vIsolatedRxPaid,3)
                     $vRunningTotal += $vIsolatedRxPaid
                  Next
               EndIf
               GUICtrlSetData($vNoc,UBound($aPlanSearch))
               GUICtrlSetData($vTotalPayAmt, $vRunningTotal)
               Global $vMaxRange = UBound($aPlanSearch)
               $vMaxRange -= 1
               Local $vMinDateUnformatted = _ArrayMin($aResultArray, 1, $aPlanSearch[0], $aPlanSearch[$vMaxRange], 1)
               Local $vMinDateYear = StringLeft($vMinDateUnformatted,4)
               $vMinDateUnformatted = StringTrimLeft($vMinDateUnformatted,4) & $vMinDateYear
               GUICtrlSetData($vMinDate, $vMinDateUnformatted)
               Local $vMaxDateUnformatted = _ArrayMax($aResultArray, 1, $aPlanSearch[0], $aPlanSearch[$vMaxRange], 1)
               Local $vMaxDateYear = StringLeft($vMaxDateUnformatted,4)
               $vMaxDateUnformatted = StringTrimLeft($vMaxDateUnformatted,4) & $vMaxDateYear
               GUICtrlSetData($vMaxDate, $vMaxDateUnformatted)
               Global $vPaymentDate = GUICtrlRead($vPaymentDateInput)
               Global $vEpicDate = GUICtrlRead($vEpicDateInput)
               If ($vPaymentDate == "mm/dd/yyyy") OR ($vEpicDate == "mm/dd/yyyy") Then
                  MsgBox($MB_ICONERROR,"Invalid Selection","Date(s) Entered Invalid.")
               Else
                  GUICtrlSetState($idContinueButton, $GUI_ENABLE)
               EndIf
            Else
               MsgBox($MB_ICONERROR,"Invalid Selection","No Insurance Plan Selected.")
            EndIf


         Case $idOpenButton
            OpenFile()
            ExitLoop

         Case $idContinueButton
            Global $vContinuePaidTotal = 0
            $vContinuePaidTotal = Number($vContinuePaidTotal)

            If WinExists("Reconcile Payment") Then
               Local $vContinueMin = $aPlanSearch[0]
               Local $vContinueMax = $aPlanSearch[$vMaxRange]
               Global $vReconciledAmt
;~              _ArrayDisplay($aResultArray,"Result Array", $vContinueMin & ":" & $vContinueMax)
               For $i = $vContinueMin to $vContinueMax
;~                 Send Rx Number to Reconcile Payment Screen
                  ControlFocus("Reconcile Payment","",$pEdit & $vPioneerClass & "; INSTANCE:1]")
                  ControlSend("Reconcile Payment","",$pEdit & $vPioneerClass & "; INSTANCE:1]",$aResultArray[$i][2])
                  ControlFocus("Reconcile Payment","",$pButton & $vPioneerClass & "; INSTANCE:1]")
                  ControlClick("Reconcile Payment","",$pButton & $vPioneerClass & "; INSTANCE:1]")

                  Local $vContineRxNum = $aResultArray[$i][2]
                  Local $vContinueRxDate = $aResultArray[$i][1]
                  Local $vContinueRxPaidAmt = Number($aResultArray[$i][3])
                  $vContinueRxPaidAmt = StringFormat($vContinueRxPaidAmt, "%.2f")
                  Local $vDifference = 0

                  $vReconciledAmt = ControlGetText("Reconcile Payment","","[CLASS:WindowsForms10.STATIC.app." & $vPioneerClass & "; INSTANCE:36]")
                  $vReconciledAmt = Number(StringTrimLeft($vReconciledAmt, 1))
                  $vReconciledAmt = StringFormat($vReconciledAmt, "%.2f")
                  $vContinuePaidTotal = StringFormat($vContinuePaidTotal,"%.2f")
                  $vContinueRxPaidAmt = StringFormat($vContinueRxPaidAmt, "%.2f")
                  $vContinuePaidTotal = $vContinuePaidTotal + $vContinueRxPaidAmt
                  $vContinuePaidTotal = StringFormat($vContinuePaidTotal, "%.2f")
                  $vDifference = $vContinuePaidTotal - $vReconciledAmt
                  $vDifference = StringFormat($vDifference, "%.2f")

                  MsgBox($MB_OK,"",$vReconciledAmt & @CRLF & $vContinuePaidTotal & @CRLF & @CRLF & "Difference: " & $vDifference)

                  If $vReconciledAmt = $vContinuePaidTotal Then
                     MsgBox($MB_OK,"","Amounts Match.")
                  Else
                     MsgBox($MB_OK,"","Amounts Do Not Match.")
                     $vContinuePaidTotal = StringFormat($vContinuePaidTotal, "%.2f")
                     $vDifference = StringFormat($vDifference, "%.2f")
                     $vContinuePaidTotal = $vContinuePaidTotal - $vDifference
                     $vContinuePaidTotal = StringFormat($vContinuePaidTotal, "%.2f")
                     $vDifference = StringFormat($vDifference, "%.2f")
                  EndIf





               Next
            Else
               MsgBox($MB_ICONERROR,"Invalid Selection","Reconcile Payment Screen not found.")
            EndIf


         Case $idCancelButton, $GUI_EVENT_CLOSE
            ExitLoop
        EndSwitch
    WEnd



EndFunc

;~ Open File
Func OpenFile()
   Local $sFileOpenDialog = FileOpenDialog("Select Payment Data to Import","C:\Users\Owner\Downloads\","Payment Files (*.xls;*.tab)", $FD_FILEMUSTEXIST)
   If @error Then
      MsgBox($MB_SYSTEMMODAL,"","No file was selected.")
   Else
      $vTabFile = $sFileOpenDialog
   EndIf
   CreatePaymentArray()
   CreateWindow()
EndFunc

;~ Set up Payments in Pioneer - UNFINISHED
Func SetupPioneer()
   If WinExists("PioneerRx Quinlans Pharmacy") Then
      WinActivate("PioneerRx Quinlans Pharmacy")
      Send("{ESC 3}")
      Send("!{S}")
      Send("{P 2}")
      WinWait("Save Rx?","",1)

      If WinExists("Save Rx?") Then
         Send("{N}")
         Sleep(200)
         WinActivate("PioneerRx Quinlans Pharmacy")
         ControlClick("PioneerRx Quinlans Pharmacy","", $pButton & $vPioneerClass & "; INSTANCE:8]")
      Else
         WinActivate("PioneerRx Quinlans Pharmacy")
      EndIf

      ControlClick("PioneerRx Quinlans Pharmacy","", $pButton & $vPioneerClass & "; INSTANCE:8]")
      WinWait("Action Menu")
      ControlClick("Action Menu","", $pButton & $vPioneerClass & "; INSTANCE:5]")
      WinWait("Add Third Party Payment")
      ControlSend("Add Third Party Payment", "", $pEdit & $vPioneerClass & "; INSTANCE:4]", StringLeft($vPlan,5))
      Send("{ENTER 2}")
      Sleep(100)
      ControlClick("Add Third Party Payment","","[CLASS:WindowsForms10.COMBOBOX.app." & $vPioneerClass & "; INSTANCE:1]")
      Send("{DOWN}")
      ControlFocus("Add Third Party Payment","",$pEdit & $vPioneerClass & "; INSTANCE:3]")
      ControlSend("Add Third Party Payment","",$pEdit & $vPioneerClass & "; INSTANCE:3]", $vPaymentDate)
      ControlFocus("Add Third Party Payment","",$pEdit & $vPioneerClass & "; INSTANCE:2]")
      ControlSend("Add Third Party Payment","",$pEdit & $vPioneerClass & "; INSTANCE:2]", "EPIC " & $vEpicDate & " Automated")
;~    ControlClick("Add Third Party Payment","",$pButton & $vPioneerClass & "; INSTANCE:4]")





   Else
      MsgBox ($MB_ICONERROR,"Window Test", "PioneerRx Quinlans Pharmacy Window Does Not Exist")
   EndIf

EndFunc


CreatePaymentArray()

CreateWindow()

 

Edited by asakust
Solved
Link to comment
Share on other sites

  • Moderators

asakust,

Go and look up "floating point arithmetic" - or search the forum because it has been discussed I do not know how many times.  And before you ask, this is NOT an Autoit problem - it affects all computers regardless of language unless they use special arithmetic routines.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Go and look up "floating point arithmetic" - or search the forum because it has been discussed I do not know how many times.

​Good deal, I'll look into it. Thanks for giving me the name of something to look for, I had no idea where to even start - I tried searching for "extra decimal places," "math extra decimals," and anything else I could think of, but since I had no idea what to look for, I couldn't find anything to start from. I'll update when I get somewhere. 

 

Thanks, M!

Edited by asakust
Link to comment
Share on other sites

Actually, I still have issues with this... I'm trying to use StringFormat to force the numbers to truncate anyway, and it's still coming out with the extra decimals. Code snippet below.

$vContinuePaidTotal = StringFormat($vContinuePaidTotal, "%.2f")
    $vDifference = StringFormat($vDifference, "%.2f")
    $vContinuePaidTotal = $vContinuePaidTotal - $vDifference
    $vContinuePaidTotal = StringFormat($vContinuePaidTotal, "%.2f")

I'm assuming I'm using the StringFormat correctly, but even after repeatedly trying to force it into 2 decimal places (yes, I'm working with money) the $vContinuePaidTotal variable always returns with added decimal places. I have tried the same thing I'm doing here with Round(), am I missing something? Should I be formatting the string and/or rounding it as I'm trying to return the value?

MsgBox($MB_OK,"Total Amount","ContinuePaidTotal = " & Round($vContinuePaidTotal,2))

;~ OR

MsgBox($MB_OK,"Total Amount","ContinuePaidTotal = " & StringFormat($vContinuePaidTotal, "%.2f")

Something like this?

I understand the floating point issue is not one with AutoIt, but I'm just confused as to where I'm going wrong in attempting to format the resulting values.

Link to comment
Share on other sites

  • Moderators

asakust,

I'm assuming I'm using the StringFormat correctly

Check the order of the parameters for StringFormat - you might find it works better if you get them the right way round.

But you might get .99999999999 returned and so I would not recommend that method.

If you are working with cash, why not convert everything to cents/pence/lowest and do all the maths on integers, reconverting at the end?

M23

Edited by Melba23
Wrong button too soon

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Melba - 

I got stuck in the reference with this PrintFormat Function. Thanks for that.

PrintFormat($iInt_Unsigned, "%.2f", "floating point with 2 digits after decimal point", 1) ; 43951789.00

The only reason I haven't switched everything into cents and reconverted is that... Well, I figured it would be more difficult and take more time - but with the issues I'm having on the floating-point nonsense, that may be the easier route.

 

Thanks again, I'll try it again later on and update you!

Link to comment
Share on other sites

  • Moderators

asakust,

Glad I could help.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...