Jump to content

[Solved] Why do I keep losing the count on my variable?


Recommended Posts

Okay I see.... That did the trick. 

However when I select 2 patients as total

it works

but when I run it again it types champ, brett again

so it ends up looking like                                                          

Champ,Andrew                                                                         
        M
Champ,Brett
        M
Champ,Brett
        M
Champ,Claire
        F

 

 

On another note.

I need each clinic to have a diffrent vartation of the controlsend part of the code. (below code)

 

ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][1] & ',' & $aArray[$i][2] & @CR)
ControlSend("[CLASS:Notepad]", "", "Edit1", ("{TAB 2}"))
ControlSend("[CLASS:Notepad]", "", "Edit1", ("{RIGHT 3}"))
ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][4] & @CR)

So one clinic1 would do this combanation

But clinic 2 might have 3 tabs and 4 rights. instead of 2 tabs and 3 rights.

Clinic3, Clinic4, Clinic5, Etc will all have diffrent ControlSend commands.

I feel like I am going to drive you crazy here. If you would like to me clerify more just let me know. 

Edited by SkysLastChance

You miss 100% of the shots you don't take. -Wayne Gretzky -Michael Scott

Link to comment
Share on other sites

Don't worry about bad code, everyone has been there, I still go there, then main thing is getting the result you want first then optimize. I spend hours looking at a blank sheet trying to predict IFTTT and waste time. Reading other peoples posts and code is how you learn as well as doing your own. Once it's done you look and say, Hey, that doesn't need to be global,  this repeats so I can make it a function, and other ideas pop up. The main thing for me is comments, giving variables descriptive names and also signifying what you expect the value or values to be. If you have to go back and update in months it makes it easier to get up to speed.

Also when others are helping they don't have to spend time checking what $x does or $r does it they aren't loop related, (i.e For $i = ). If you used 'For $x =' in a loop then had $x +=1 after it doing something else, this leads to $x not being the value you were expecting.

Regarding the globals question, $yx only appear in the clinic functions so they can be local to those functions. The clinic functions have mostly the same code so could be one function instead of having 30, one for each clinic.

Either mine or Subz's code should be able to be tweaked for what you want.

You might also want to send the health inspector round to 1212 One Way, there seems to be a lot of families who aren't very well :x

Link to comment
Share on other sites

@SkysLastChance For the different Clinic settings you can just use a Switch see code below, have also fixed the user count.

#include <Excel.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>

$sExcelFile = @ScriptDir & '\test.xlsx'
$oExcel = _Excel_Open ()
$oWorkbook = _Excel_BookOpen($oExcel,$sExcelFile) ;this will open the chosen xls file.
$aArray = _Excel_RangeRead($oWorkbook)

Global $iPatients = HowMany()

Dropdown()

Func HowMany()
    Local $iMsg
    While 1
;~ Turn input into a number
        $iPatients = Number(InputBox("Registration", "How Many Patients are there total?")) ; #### changed to Registration ####
;~ If user enters a string or cancels then get them to try again
        If $iPatients = 0 Then
            $iMsg = MsgBox(1, 'Registration', 'Please enter a valid number') ; #### changed to Registration ####
            If $iMsg = 2 Then Exit
        Else
            Return $iPatients - 1
        EndIf
    WEnd
EndFunc   ;==>HowMany

Func Dropdown()
    Local $iCount = 1, $iCurrent = 1
    GUICreate("Chart", 225, 80)
    $idClinic = GUICtrlCreateCombo("Clinic 1", 10, 10, 120, 20)
    GUICtrlSetData(-1, "Clinic 2|Clinic 3|Clinic 4")
    $idSelect = GUICtrlCreateButton("Select", 10, 40, 60, 20)
    GUISetState(@SW_SHOW)

    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $idSelect
                $sClinic = GUICtrlRead($idClinic)
                For $i = $iCurrent To UBound($aArray) - 1
                    If $aArray[$i][1] = "" Or $aArray[$i][2] = "" Or $aArray[$i][10] <> "" Then
                        $iCurrent += 1
                        $iCount = $iCount + 1
                        ContinueLoop
                    EndIf
                    Switch $sClinic
                        Case "Clinic 1"
                            WinWaitActive("Untitled - Notepad") ;I want to manually open notepad so all 6 patients will go through the same loop
                            ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][1] & ',' & $aArray[$i][2] & @CR)
                            ControlSend("[CLASS:Notepad]", "", "Edit1", ("{TAB 2}"))
                            ControlSend("[CLASS:Notepad]", "", "Edit1", ("{RIGHT 3}"))
                            ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][4] & @CR)
                        Case "Clinic 2"
                            WinWaitActive("Untitled - Notepad") ;I want to manually open notepad so all 6 patients will go through the same loop
                            ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][1] & ',' & $aArray[$i][2] & @CR)
                            ControlSend("[CLASS:Notepad]", "", "Edit1", ("{TAB 3}"))
                            ControlSend("[CLASS:Notepad]", "", "Edit1", ("{RIGHT 4}"))
                            ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][4] & @CR)
                        Case "Clinic 3"
                            WinWaitActive("Untitled - Notepad") ;I want to manually open notepad so all 6 patients will go through the same loop
                            ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][1] & ',' & $aArray[$i][2] & @CR)
                            ControlSend("[CLASS:Notepad]", "", "Edit1", ("{TAB 2}"))
                            ControlSend("[CLASS:Notepad]", "", "Edit1", ("{RIGHT 3}"))
                            ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][4] & @CR)
                        Case "Clinic 4"
                            WinWaitActive("Untitled - Notepad") ;I want to manually open notepad so all 6 patients will go through the same loop
                            ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][1] & ',' & $aArray[$i][2] & @CR)
                            ControlSend("[CLASS:Notepad]", "", "Edit1", ("{TAB 3}"))
                            ControlSend("[CLASS:Notepad]", "", "Edit1", ("{RIGHT 4}"))
                            ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][4] & @CR)
                    EndSwitch
                    If $i = $iCount + $iPatients Then
                        $iCount = $i + 1
                        $iCurrent = $i + 1
                        ExitLoop
                    EndIf
                Next
            Case $GUI_EVENT_CLOSE
                _Excel_Close($oExcel)
                Exit
        EndSwitch
    WEnd
EndFunc

 

Link to comment
Share on other sites

As for the clinic tabs and spaces, using Subz code you could create a function to pass the codes

#include <Excel.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>

$sExcelFile = 'D:\Example Format.xlsx'
$oExcel = _Excel_Open()
$oWorkbook = _Excel_BookOpen($oExcel, $sExcelFile) ;this will open the chosen xls file.
$aArray = _Excel_RangeRead($oWorkbook)
Global $iPatients = HowMany()
Dropdown()

Func HowMany()
    Local $iMsg
    While 1
;~ Turn input into a number
        $iPatients = Number(InputBox("Registration", "How Many Patients are there total?")) ; #### changed to Registration ####
;~ If user enters a string or cancels then get them to try again
        If $iPatients = 0 Then
            $iMsg = MsgBox(1, 'Registration', 'Please enter a valid number') ; #### changed to Registration ####
            If $iMsg = 2 Then Exit
        Else
            Return $iPatients - 1
        EndIf
    WEnd
EndFunc   ;==>HowMany

Func Dropdown()
    Local $iCount = 1, $iCurrent = 1
    Local $as_Clinic = ''

    GUICreate("Chart", 225, 80)
    $idClinic = GUICtrlCreateCombo("Clinic 1", 10, 10, 120, 20)
    GUICtrlSetData(-1, "Clinic 2|Clinic 3|Clinic 4")
    $idSelect = GUICtrlCreateButton("Select", 10, 40, 60, 20)
    GUISetState(@SW_SHOW)

    While 1
        $nMsg = GUIGetMsg()

        Switch $nMsg
            Case $idSelect
                $sClinic = GUICtrlRead($idClinic)

                For $i = $iCurrent To UBound($aArray) - 1

                    If $aArray[$i][1] = "" Or $aArray[$i][2] = "" Or $aArray[$i][10] <> "" Then
                        $iCount = $iCount + 1
                        ContinueLoop
                    EndIf

                    WinWaitActive("Untitled - Notepad") ;I want to manually open notepad so all 6 patients will go through the same loop
                    ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][1] & ',' & $aArray[$i][2] & @CR)

                    ; get the clinic specific tabs spaces etc
                    $as_Clinic = Clinic_GetString($sClinic)

                    For $j = 1 To $as_Clinic[0]
                        ControlSend("[CLASS:Notepad]", "", "Edit1", $as_Clinic[$j])
                    Next

                    ControlSend("[CLASS:Notepad]", "", "Edit1", $aArray[$i][4] & @CR)

                    $iCurrent += 1

                    If $i = $iCount + $iPatients Then
                        $iCount = $i
                        $iCurrent = $i
                        ExitLoop
                    EndIf
                Next
            Case $GUI_EVENT_CLOSE
                _Excel_Close($oExcel)
                Exit
        EndSwitch
    WEnd
EndFunc   ;==>Dropdown

Func Clinic_GetString($s_Clinic)
    Local $s_Return = ''

    Switch $s_Clinic
        Case 'Clinic 1'
            $s_Return = '{TAB 2}|{RIGHT 3}'
    EndSwitch

    Return StringSplit($s_Return, '|')
EndFunc   ;==>Clinic_GetString

Subz beat me to it

Edited by benners
Link to comment
Share on other sites

@benners I just hope at some point I can start helping people out as well. Thank you so much for the help and advice.

25 minutes ago, benners said:

Regarding the globals question, $yx only appear in the clinic functions so they can be local to those functions. The clinic functions have mostly the same code so could be one function instead of having 30, one for each clinic.

  I am not sure exactly what you mean here by putting it into a function.

48 minutes ago, benners said:

You might also want to send the health inspector round to 1212 One Way, there seems to be a lot of families who aren't very well :x

HAHA It is defintly spreading... 

 

@Subz That is exactly what I was looking to do. I was on the right track with the switch, but was struggling with it.  Thank you again for all the help this is awesome! I am so glad I can mark this solved. LOL

You miss 100% of the shots you don't take. -Wayne Gretzky -Michael Scott

Link to comment
Share on other sites

14 minutes ago, SkysLastChance said:

i am not sure exactly what you mean here by putting it into a function.

When your project start getting bigger you will see a lot of code repeating itself, performing the same actions. One example would be the different clinics. rather than writing separate functions for each clinic with each only having minor differences, you can put the repetitive code in a new function and either pass variables to the function or decide in the function what to do. This is what the function below does

Func Clinic_GetString($s_Clinic)
    Local $s_Return = ''

    Switch $s_Clinic
        Case 'Clinic 1'
            $s_Return = '{TAB 2}|{RIGHT 3}'
    EndSwitch

    Return StringSplit($s_Return, '|')
EndFunc   ;==>Clinic_GetString

Glad it's sorted. Now you can optimize it and get rid of the Global variables, They probably wont be needed if you create functions to do the work

 

Link to comment
Share on other sites

Cleaned up a bit.

#include <Excel.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>

Dropdown()

; #FUNCTION# ====================================================================================================================
; Name ..........: Clinic_GetString
; Description ...: Returns 'Clinic' specific character patterns for use with ControlSend
; Syntax ........: Clinic_GetString($s_Clinic)
; Parameters ....: $s_Clinic - The string of the clinic to process
; Return values .: Success - Returns an array with the characters to use
; ===============================================================================================================================
Func Clinic_GetString($s_Clinic)
    Local $s_Return = ''

    Switch $s_Clinic
        Case 'Clinic 1'
            $s_Return = '{TAB 2}|{RIGHT 3}'
        Case 'Clinic 2'
            ; add keystrokes here
        Case 'Clinic 3'
            ; add keystrokes here
    EndSwitch

    Return StringSplit($s_Return, '|') ; split the keystrokes to an array
EndFunc   ;==>Clinic_GetString

Func Dropdown()
    Local $iCount = 1, $iCurrent = 1
    Local $i_PatientTotal = Patient_GetTotal()
    Local $av_RangeRead = WorkBook_ReadToArray()
    Local $as_ClinicChars = ''

    GUICreate("Chart", 225, 80)
    $idClinic = GUICtrlCreateCombo("Clinic 1", 10, 10, 120, 20)
    GUICtrlSetData(-1, "Clinic 2|Clinic 3|Clinic 4")
    $idSelect = GUICtrlCreateButton("Select", 10, 40, 60, 20)
    GUISetState(@SW_SHOW)

    While 1
        $nMsg = GUIGetMsg()

        Switch $nMsg
            Case $idSelect
                $sClinic = GUICtrlRead($idClinic)

                For $i = $iCurrent To UBound($av_RangeRead) - 1

                    If $av_RangeRead[$i][1] = "" Or $av_RangeRead[$i][2] = "" Or $av_RangeRead[$i][10] <> "" Then
                        $iCount = $iCount + 1
                        ContinueLoop
                    EndIf

                    WinWaitActive("Untitled - Notepad") ;I want to manually open notepad so all 6 patients will go through the same loop
                    ControlSend("[CLASS:Notepad]", "", "Edit1", $av_RangeRead[$i][1] & ',' & $av_RangeRead[$i][2] & @CR)

                    ; get the clinic specific tabs spaces etc
                    $as_ClinicChars = Clinic_GetString($sClinic)

                    For $j = 1 To $as_ClinicChars[0] ; loop and perform the clinic specific key presses
                        ControlSend("[CLASS:Notepad]", "", "Edit1", $as_ClinicChars[$j])
                    Next

                    ControlSend("[CLASS:Notepad]", "", "Edit1", $av_RangeRead[$i][4] & @CR)

                    $iCurrent += 1

                    If $i = $iCount + $i_PatientTotal Then
                        $iCount = $i
                        $iCurrent = $i
                        ExitLoop
                    EndIf
                Next
            Case $GUI_EVENT_CLOSE
                Program_Exit()
        EndSwitch
    WEnd
EndFunc   ;==>Dropdown

; #FUNCTION# ====================================================================================================================
; Name ..........: Patient_GetTotal
; Description ...: Displays an input box, prompting for user input denoting the number of patients to process
; Syntax ........: Patient_GetTotal()
; Parameters ....: None
; Return values .: Success - Returns an integer who's value was read from the input box
; ===============================================================================================================================
Func Patient_GetTotal()
    Local $i_Count = 0

    Do
        $i_Count = InputBox("Registration", "How Many Patients are there in total?") ; prompt for patient #
    Until @error = 1 Or Number($i_Count) ; end if cancelled or number entered

    If @error Then Program_Exit() ; user cancelled
    Return Floor($i_Count) - 1 ; round down to closest integer (deals with decimal entries)
EndFunc   ;==>Patient_GetTotal

; #FUNCTION# ====================================================================================================================
; Name ..........: Program_Exit
; Description ...: Runs tasks related to program clean up and exits the running program
; Syntax ........: Program_Exit()
; Parameters ....: None
; Return values .: None
;================================================================================================================================
Func Program_Exit()
    WorkBook_ReadToArray('Close'); close excel
    ; any other clean up duties
    Exit ; bye
EndFunc   ;==>Program_Exit

; #FUNCTION# ====================================================================================================================
; Name ..........: WorkBook_ReadToArray
; Description ...: Reads the value, formula or displayed text from a cell or range of cells of the specified workbook and worksheet
; Syntax ........: WorkBook_ReadToArray([$_Action = 'Open'])
; Parameters ....: $s_Action - Action to perform
; Return values .: Success - Open : Returns an array of values read from the specified range
;                            Close: Closes the Excel instance opened by _Excel_Open()
; Remarks .......: A static variable $o_Excel keeps the value of the excel object returned by  _Excel_Open() after exiting
;                  the function
; ===============================================================================================================================
Func WorkBook_ReadToArray($s_Action = 'Open')
    Local Static $o_Excel = ''

    If $s_Action = 'Open' Then
        Local $s_WorkBook = 'D:\Example Format.xlsx' ; change this to your file
        $o_Excel = _Excel_Open()
        Local $o_Workbook = _Excel_BookOpen($o_Excel, $s_WorkBook) ;this will open the chosen xls file.
        Local $av_RangeRead = _Excel_RangeRead($o_Workbook, 'NURSE Training Pts')
        Return $av_RangeRead
    Else
        If IsObj($o_Excel) Then _Excel_Close($o_Excel)
    EndIf
EndFunc   ;==>WorkBook_ReadToArray

 

Link to comment
Share on other sites

@benners Like your layout, very nice, however I noticed it uses static information and also if you only select 2 of a Patient Block and then re-run it, it will redo the first 2 users on that list even though they have already been assigned.

Personally I would have used the attached, although could be cleaned up, basically LastSkysChance would only have to update the spreadsheet and the Ini without recompiling the script again.

Anyway Just my 2cents

 

Clinic.ini

Clinic.v1.au3

Link to comment
Share on other sites

8 hours ago, Subz said:

@benners Like your layout, very nice, however I noticed it uses static information and also if you only select 2 of a Patient Block and then re-run it, it will redo the first 2 users on that list even though they have already been assigned.

Personally I would have used the attached, although could be cleaned up, basically LastSkysChance would only have to update the spreadsheet and the Ini without recompiling the script again.

Anyway Just my 2cents

 

Clinic.ini

Clinic.v1.au3

Yep, mine was only an example to show LastSkysChance, there's no error checking which is needed.

I liked your code, it's compact, and the _ClinicIni()  function negates the need for the long clinic string. I had to alter the ini to remove the comment that stopped Execute() from running correctly

;I want to manually open notepad so all 6 patients will go through the same loop

I don't know how many clinics will be entered into the ini , The OP said 30 to 40 maybe, but I think there is still the 32KB limitation on the IniRead functions so he would have to be careful with the file size. Copying the ini contents x10 made the filesize still safe @ around 20Kb, but it's getting up there. There are user UDFs that don't have the limitation so he could use one of those or only have the keystroke info in the ini and the actual function code inside _ClinicIni()

Func _ClinicIni($s_ClientId, $i_ClientId)
    Local $a_ClinicId = IniReadSection($gs_ClinicIni, $s_ClientId)

    WinWaitActive("Untitled - Notepad")
    ControlSend("[CLASS:Notepad]", "", "Edit1", $ga_Workbook[$i_ClientId][1] & ',' & $ga_Workbook[$i_ClientId][2] & @CR)

    For $i = 1 To $a_ClinicId[0][0]
        ControlSend("[CLASS:Notepad]", "", "Edit1", $a_ClinicId[$i][1])
;~      Execute($a_ClinicId[$i][1])
    Next

    ControlSend("[CLASS:Notepad]", "", "Edit1", $ga_Workbook[$i_ClientId][4] & @CR)
EndFunc

and the Ini section like this

[Clinic 1]
1={TAB 3}
2={RIGHT 3}

I'm sure there's enough for the OP to work on :D

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...