If statement tree w/ variables Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Jakson
Posts: 47
Joined: 25 Jun 2021, 15:19

If statement tree w/ variables

Post by Jakson » 19 Jul 2021, 19:05

Help! I'm having a moment of ineptitude and I can't figure out what I'm doing wrong! (lol)

The circumstance:
I've got three subroutines to do some webform stuff for me. When it finishes I need to name a PDF file with a tag from the subroutine type I ran. For sake of ease, the subs will be called sub 1, sub 2, and sub 3. When I run 1, I want my subroutine to name the PDF file to name the PDF with sub 1's name, same for sub 2 and sub 3.
I'm using an .ini called "settings" to get the boolean value for all 3 subs into my parent script where the if statements and logical analysis happens. I had it working previously, however, I only made it work purely through trial/error. I want to know WHY it works just as much as why I'm not doing it right.

TL;DR:
I've got three subroutines to fire from one parent script. I want the parent script to hold on to a variable, (1,2,3...), from the child subs. Help!

See code below

Code: Select all

;CHILD SCRIPT CODE
; There's a bunch of clicks and copies, then a webform is submitted. The contents of the form are besides the point.
	; This variable becomes the decision maker for what style name to type out in the PDF name line.
NCMVar := 1

IniWrite,%NCMVar%,settings.ini,ncmtype,ncmvar

Code: Select all

;  PARENT SCRIPT CODE
;	Get boolean values from settings.ini.
	; 	If 1, or variable name, then send the style name, "NCM", "ISW", "POC"...
;Get Style
IniRead,NCMvar,settings.ini,ncmtype,ncmvar

If (NCMvar = 1,NCM)
{
clipboard = %servicedate%
Sleep 10
DllCall("SetCursorPos", int, 2258, int, 640)
Send {LButton}
Send {End}
Sleep 10
Send ^v{.}NCM {Space}
}

Else

IniRead,ISWvar,settings.ini,iswtype,iswvar

If (ISWVar = 1,ISW)
{
clipboard = %servicedate%
Sleep 10
DllCall("SetCursorPos", int, 2258, int, 640)
Send {LButton}
Send {End}
Sleep 10
Send ^v{.}ISWCM {Space}
}

Else

IniRead,POCvar,settings.ini,poctype,pocvar

If (POCVar = 1,POC)
{
clipboard = %servicedate%
Sleep 10
DllCall("SetCursorPos", int, 2258, int, 640)
Send {LButton}
Send {End}
Sleep 10
Send ^v{.}POC {Space} 
}


(Someone please tell me I'm just being silly!)

THANK YOU!

User avatar
boiler
Posts: 16705
Joined: 21 Dec 2014, 02:44

Re: If statement tree w/ variables

Post by boiler » 19 Jul 2021, 20:33

What are you expecting from this line and those like it? Can you say in English what it is meant to do?

Code: Select all

If (NCMvar = 1,NCM)

Jakson
Posts: 47
Joined: 25 Jun 2021, 15:19

Re: If statement tree w/ variables

Post by Jakson » 21 Jul 2021, 15:27

boiler wrote:
19 Jul 2021, 20:33
What are you expecting from this line and those like it? Can you say in English what it is meant to do?

Code: Select all

If (NCMvar = 1,NCM)
Does it not do?:

If NCMvar is 1 or literal string, "NCM", do thing, else, don't do thing

User avatar
boiler
Posts: 16705
Joined: 21 Dec 2014, 02:44

Re: If statement tree w/ variables

Post by boiler » 21 Jul 2021, 15:44

No, it does not do that. I guess you are expecting it to check a list or something. It does not work that way. It's easy to check:

Code: Select all

NCMvar := "NCM"
if (NCMvar = 1,NCM)
	MsgBox, Yes
else
	MsgBox, No

You could use:

Code: Select all

NCMvar := "NCM"
if NCMvar in 1,NCM
	MsgBox, Yes
else
	MsgBox, No
Reference: If Var in/contains Matchlist

Jakson
Posts: 47
Joined: 25 Jun 2021, 15:19

Re: If statement tree w/ variables

Post by Jakson » 21 Jul 2021, 15:57

boiler wrote:
21 Jul 2021, 15:44
No, it does not do that. I guess you are expecting it to check a list or something. It does not work that way. It's easy to check:

Code: Select all

NCMvar := "NCM"
if (NCMvar = 1,NCM)
	MsgBox, Yes
else
	MsgBox, No
Woops! Thanks for pointing that out!

boiler wrote:
21 Jul 2021, 15:44
You could use:

Code: Select all

NCMvar := "NCM"
if NCMvar in 1,NCM
	MsgBox, Yes
else
	MsgBox, No
Reference: If Var in/contains Matchlist

I'll look into this and give it a try. Thank you very much for your help, boiler!

Jakson
Posts: 47
Joined: 25 Jun 2021, 15:19

Re: If statement tree w/ variables

Post by Jakson » 22 Jul 2021, 14:36

boiler wrote:
21 Jul 2021, 15:44
You could use:

Code: Select all

NCMvar := "NCM"
if NCMvar in 1,NCM
	MsgBox, Yes
else
	MsgBox, No
Reference: If Var in/contains Matchlist
I looked over the help document you attached, thank you very much by the way, and I decided to try the var contains method. If var contains literal string, do thing.

See code below

Code: Select all

IniRead,NCMvar,settings.ini,ncmtype,ncmvar ; read settings ini file for variable state

If NCMvar contains NCM ; if variable is NCM, one of 3 options, then do this
{
clipboard = %servicedate% ; clipboard becomes a previously copied value
Sleep 10
DllCall("SetCursorPos", int, 2258, int, 640) ; move mouse to web element
Send {LButton}
Send {End} ; click inside web element field and move cursor to end to avoid flubbing data
Sleep 10
Send ^v{.}NCM {Space} ; send var %servicedate% through the clipboard (this is to deal with Chrome's behavior), send "NCM" and space
goto, finish ; step control all the way around the following code block
}

Else ; if NCMvar does not contain NCM, but does contain something else

If NCMvar contains 0 ; if NCMvar is 0 then move control to the next analysis. When the first If statement results in No_
; _ I need control to go directly to the next analysis rather than do anything more with the above code block. Overkill? Definitely.
{
goto, gISW
}

gISW:
IniRead,ISWvar,settings.ini,iswtype,iswvar

If ISWVar contains ISW
{
clipboard = %servicedate%
Sleep 10
DllCall("SetCursorPos", int, 2258, int, 640)
Send {LButton}
Send {End}
Sleep 10
Send ^v{.}ISWCM {Space}
goto, finish
}
... code continues until there are no more variables to read/write.

Thank you, Boiler! I wouldn't have figured out that I was doing something not-quite-right if you hadn't pointed it out to me!
:dance:

User avatar
boiler
Posts: 16705
Joined: 21 Dec 2014, 02:44

Re: If statement tree w/ variables

Post by boiler » 23 Jul 2021, 04:36

Well @Jakson, please don't tell people I taught you to do that, because I didn't. ;) You took something I suggested and misapplied it (it happens to work in this case but you would get in real trouble if you did this in general going forward). If you were going to just separate your if statements so that they are now checking single items at a time instead of lists, then you just should have used if (NCMVar = "NMC") (quotes needed because it's a literal string in expression format) and if (NCMVar = 1) (no quotes because 1 is a numerical value, although it would work with them which would treat it as the string "1").

The reason I suggested using if Var in s that it allows lists like you were trying to use with =. And if Var contains is also meant for lists, not single values. I showed you how if (NCMVar = 1,NCM) was incorrect but you could use if NCMVar in 1,NCM. So it seems you are using contains now only because you saw it on that page and it sounds more appropriate from an English perspective, but using it with a single value like if NCMVar contains 1 isn’t how it was meant to be used. In fact it is the wrong use of it. That statement would be true if the variable contained a 1 anywhere in it, such as 10, "Text1", or 2010:

Code: Select all

NCMVar := 10
if NCMVar contains 1
	MsgBox, Yes ; produces Yes, which is surely not desired
else
	MsgBox, No
If you were going to do that, at least it would make more sense to use if NCMVar in 1, since that at least produces the desired result. But please don't use that either as in is meant to be used with lists. It makes more sense from an English perspective when you say it with a list: "Is the value of NCMVar in the list of values 1,NCM?"

Jakson
Posts: 47
Joined: 25 Jun 2021, 15:19

Re: If statement tree w/ variables

Post by Jakson » 23 Jul 2021, 19:23

boiler wrote:
23 Jul 2021, 04:36
Well @Jakson, please don't tell people I taught you to do that, because I didn't. ;) You took something I suggested and misapplied it (it happens to work in this case but you would get in real trouble if you did this in general going forward). If you were going to just separate your if statements so that they are now checking single items at a time instead of lists, then you just should have used if (NCMVar = "NMC") (quotes needed because it's a literal string in expression format) and if (NCMVar = 1) (no quotes because 1 is a numerical value, although it would work with them which would treat it as the string "1").

The reason I suggested using if Var in s that it allows lists like you were trying to use with =. And if Var contains is also meant for lists, not single values. I showed you how if (NCMVar = 1,NCM) was incorrect but you could use if NCMVar in 1,NCM. So it seems you are using contains now only because you saw it on that page and it sounds more appropriate from an English perspective, but using it with a single value like if NCMVar contains 1 isn’t how it was meant to be used. In fact it is the wrong use of it. That statement would be true if the variable contained a 1 anywhere in it, such as 10, "Text1", or 2010:

Code: Select all

NCMVar := 10
if NCMVar contains 1
	MsgBox, Yes ; produces Yes, which is surely not desired
else
	MsgBox, No
If you were going to do that, at least it would make more sense to use if NCMVar in 1, since that at least produces the desired result. But please don't use that either as in is meant to be used with lists. It makes more sense from an English perspective when you say it with a list: "Is the value of NCMVar in the list of values 1,NCM?"

It appears I'm being a little overzealous!

It would also appear this solution I came up with, the one you mention above, is also not the right way forward!

I've slightly modified what my iniwrite lines do. Instead of assigning each variable a 1, or their literal string name ("NCM", "ISW"...), I'm only assigning their literal string name. From the outset, it appears to have made things simpler.

Code: Select all

NCMVar := NCM

IniWrite,%NCMVar%,settings.ini,ncmtype,ncmvar
I'm still using contains inappropriately, however.

Instead of checking if my variable is one of two values I'm instead checking if it is a literal string using contains.
boiler wrote:
23 Jul 2021, 04:36
If you were going to just separate your if statements so that they are now checking single items at a time instead of lists, then you just should have used if (NCMVar = "NMC") (quotes needed because it's a literal string in expression format) and if (NCMVar = 1) (no quotes because 1 is a numerical value, although it would work with them which would treat it as the string "1").
If I'm following along with what your saying, my original iteration was wrong because I was using the wrong function, and the wrong syntax, to check the contents of a variable against a list. Now that I'm not checking a variable's contents against a list of strings or numbers, (only one string to compare per each if) am I correct in re-formatting my if statements to be as you stated above, If (NCMVar = "NMC")?

Example code below

Code: Select all

IniRead,NCMvar,settings.ini,ncmtype,ncmvar

If (NCMvar := "NCM") ; if True, do the thing
{
clipboard = %servicedate%
Sleep 10
DllCall("SetCursorPos", int, 2258, int, 640)
Send {LButton}
Send {End}
Sleep 10
Send ^v{.}NCM {Space}
goto, finish
}

Else ; if False, do the other thing

gISW:
IniRead,ISWvar,settings.ini,iswtype,iswvar

If (ISWVar := "ISW")
{
clipboard = %servicedate%
Sleep 10
DllCall("SetCursorPos", int, 2258, int, 640)
Send {LButton}
Send {End}
Sleep 10
Send ^v{.}ISWCM {Space}
goto, finish
}

Else

....
Also, thank you again for your grace, Boiler! You're really helpful, man! Some of these concepts I'm finding are very difficult to digest at first - but when you tell me about them a little, like in this current topic and the last topic you helped me with, you made it a lot easier to understand what I wasn't getting.

Thank you!

User avatar
boiler
Posts: 16705
Joined: 21 Dec 2014, 02:44

Re: If statement tree w/ variables

Post by boiler » 24 Jul 2021, 08:33

Jakson wrote: Now that I'm not checking a variable's contents against a list of strings or numbers, (only one string to compare per each if) am I correct in re-formatting my if statements to be as you stated above, If (NCMVar = "NMC")?
That would be correct, but then that’s not what you put in your code. Instead of the comparative operator =, you used the assignment operator := in your if statement:

Code: Select all

If (NCMvar := "NCM") ; if True, do the thing
What that does is actually assign the string NCM to the variable NCMVar, not check its contents. So that statement will always evaluate to be true because it is just checking the value of the variable as to whether it evaluates to true or false itself, and a string evaluates as true. It’s the same as if you made it this statement:

Code: Select all

If ("NCM") ; if True, do the thing
…which is always true. Plus you changed the contents of the variable NCMVar, which isn’t what you wanted to do there.

Jakson
Posts: 47
Joined: 25 Jun 2021, 15:19

Re: If statement tree w/ variables  Topic is solved

Post by Jakson » 26 Jul 2021, 15:59

boiler wrote:
24 Jul 2021, 08:33
Jakson wrote: Now that I'm not checking a variable's contents against a list of strings or numbers, (only one string to compare per each if) am I correct in re-formatting my if statements to be as you stated above, If (NCMVar = "NMC")?
That would be correct, but then that’s not what you put in your code. Instead of the comparative operator =, you used the assignment operator := in your if statement:

Code: Select all

If (NCMvar := "NCM") ; if True, do the thing
What that does is actually assign the string NCM to the variable NCMVar, not check its contents. So that statement will always evaluate to be true because it is just checking the value of the variable as to whether it evaluates to true or false itself, and a string evaluates as true. It’s the same as if you made it this statement:

Code: Select all

If ("NCM") ; if True, do the thing
…which is always true. Plus you changed the contents of the variable NCMVar, which isn’t what you wanted to do there.

Lmfao I'm making a ton of mistakes. Thank you very much for your guidance Boiler. I feel like I understand now what I was doing wrong and WHY it was wrong instead of, "oh hey, it works now!"


I've made some changes based on above. Its working and it does everything I need it to do.

Code: Select all


;Get Style
IniRead,NCMvar,settings.ini,ncmtype,ncmvar ; Read settings.ini for variable state

If (NCMvar = "NCM") ; if last run macro was this style, use this in the name
{
clipboard = %servicedate% ; get date of service from excel page
Sleep 10
DllCall("SetCursorPos", int, 2258, int, 640) ; put mouse on web field
Send {LButton} ; click into field
Send {End} ; move to end
Sleep 10
Send ^v{.}NCM {Space} ; send date of service, period, style, and space.
goto, finish ; skip all other style code blocks
}


gISW:
IniRead,ISWvar,settings.ini,iswtype,iswvar

If (ISWVar = "ISW")
{
clipboard = %servicedate%
Sleep 10
DllCall("SetCursorPos", int, 2258, int, 640)
Send {LButton}
Send {End}
Sleep 10
Send ^v{.}ISWCM {Space}
goto, finish
}

...
; if not these first two options, evaluate all other options...

; Once evaluation is done, this is the following decision maker

finish:
Sleep 10

Iniread,EOBCount,settings.ini,eobcount,eobc ; how many times did the invoice error?

	If (EOBCount = 1) ; if 1 error invoice = paying
	{
	Send p ; state that this invoice is paying
	}
	
	Else ; if more than 1
	
	If (EOBCount > 1) ; cannot be paying, this invoice is suspended or denied
	{
	;*clipboard = %servicedate% ; get date of service - I realized after posting that this line is pointless. In the above evaluation the style name and service date are already written into the field.
	;*Send ^v {Space} ; send date of service and space
	Send suspended or denied ; tell me this one is not paying
	}
Thank you very much for your patience, Boiler. I feel much more confident in this script.

Post Reply

Return to “Ask for Help (v1)”