OMG I have a basic loop that is DRIVING ME NUTS

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
shipaddicted
Posts: 108
Joined: 15 Jul 2016, 19:57

OMG I have a basic loop that is DRIVING ME NUTS

18 Nov 2021, 22:29

OK ... so I'm trying to extract text from a customer's account to get just the payment info I need and reformat it so it's actually <<gasp>> useful to me. I don't know what happened, but what should be a fairly simple text manipulation has turned into my complete and total nightmare.

The raw text from the section I need looks like this (copied from the MsgBox):

Code: Select all

---------------------------
AHK_CQT_2337778109
---------------------------
Billing & CollectionsBills (Unpaid)1Ledger62Unposted1Payment History12Payment Accounts1Credit Checks
Create New: Adjustment · Credit · Charge · BillOther: Balance Transfer · Promise-to-Pay · Repost MRCs · Rerate Usage · History · Full Ledger
 	Payment #	Ref #	Method	Source	Auth Code	Date	Rep	Agent	Amount	Applied To	 	 
	76614	1159SPLIT	Manual Check
INHOUSE	-	10/26/2021	ErwinT	-	$18.35	160786: $18.35
 	Options
	68606	13872SPLIT	Manual Check
INHOUSE	-	9/21/2021	ErwinT	-	$18.44	147518: $18.44
 	Options
	63044	13858SPLIT	Manual Check
INHOUSE	-	8/25/2021	ErwinT	-	$18.44	134506: $18.44
 	Options
	56367	13837SPLIT	Manual Check
INHOUSE	-	7/26/2021	ErwinT	-	$18.44	121630: $18.44
 	Options
	48261	13819SPLIT	Manual Check
INHOUSE	-	6/16/2021	ErwinT	-	$18.50	109128: $18.5
 	Options
	42548	13805SPLIT	Manual Check
INHOUSE	-	5/19/2021	ErwinT	-	$17.50	97004: $17.5
 	Options
	35363	13775	Manual Check
INHOUSE	-	4/14/2021	ErwinT	-	$0.06	85058: $0.06
 	Options
	29692	13758SPLIT	Manual Check
INHOUSE	-	3/16/2021	ErwinT	-	$17.44	85058: $17.44
 	Options
	28854	62902461259	CC
INHOUSE	106576	3/11/2021	RaymondS	-	$17.44	61933: $1
73253: $16.44
 	Options
	19034	13717SPLIT	Manual Check
INHOUSE	-	1/21/2021	ErwinT	-	$18.44	61933: $17.44
73253: $1
 	Options
View Moreor View All
Services & Activity
What I want as the end product is, starting from line 4, combine all payment info and copy it for each invoice paid with that payment.
Each new payment line starts with a tab and a whole number. The line below that is part 2 of that same payment. Any lines between that line and the next line that starts with a tab and a whole number all belong to that same payment, just different invoices are paid. So in the end, for example, if I was looking at which invoices were paid with payment # 28854, I would want that section of the final product to look something like:

28854~62902461259~CC~106576~3/11/2021~RaymondS~$17.44~61933: $1
28854~62902461259~CC~106576~3/11/2021~RaymondS~$17.44~73253: $16.44

I have regexed out all the stuff I don't need from the text and replaced all tabs with "~" to get this (copied from the MsgBox)(code below):

Code: Select all

---------------------------
AHK_CQT_2337372890
---------------------------
Billing & CollectionsBills (Unpaid)1Ledger62Unposted1Payment History12Payment Accounts1Credit Checks
Create New: Adjustment · Credit · Charge · BillOther: Balance Transfer · Promise-to-Pay · Repost MRCs · Rerate Usage · History · Full Ledger
 ~Payment #~Ref #~Method~Source~Auth Code~Date~Rep~Agent~Amount~Applied To~ ~ 
~76614~1159SPLIT~Manual Check
10/26/2021~$18.35~160786: $18.35
~68606~13872SPLIT~Manual Check
9/21/2021~$18.44~147518: $18.44
~63044~13858SPLIT~Manual Check
8/25/2021~$18.44~134506: $18.44
~56367~13837SPLIT~Manual Check
7/26/2021~$18.44~121630: $18.44
~48261~13819SPLIT~Manual Check
6/16/2021~$18.50~109128: $18.5
~42548~13805SPLIT~Manual Check
5/19/2021~$17.50~97004: $17.5
~35363~13775~Manual Check
4/14/2021~$0.06~85058: $0.06
~29692~13758SPLIT~Manual Check
3/16/2021~$17.44~85058: $17.44
~28854~62902461259~CC
106576~3/11/2021~RaymondS~$17.44~61933: $1
73253: $16.44
~19034~13717SPLIT~Manual Check
1/21/2021~$18.44~61933: $17.44
73253: $1
View Moreor View All
Services & Activity
---------------------------
OK   
---------------------------
This is the clusterflock of code that I have so far. I am seriously confusing myself more and more every time I try to figure out what I already have and what I need to do next ... I know this is a complete mess and it only works a tiny, tiny bit. My line of thinking was that for each line that started with my tab replacement character, "~", I would tag it with a count var, and add that var to an array of similar vars.

Then when the script was done evaluating the text, I would create another loop that would iterate through the count var and reassemble the parts of the text that pertained to each payment number.

My code at that point where I was ready to throw a match over my shoulder and walk away:

Code: Select all

GoSub, getAcctNumNamerevio 
meat := RegExMatch(text, "Billing & Collections.*Services & Activity", meatier ) 
meatier := RegExReplace(meatier, "`r`n|`r`r|`n`n", "`n")
meatier := RegExReplace(meatier, "`t", "~")  
meatier := RegExReplace(meatier, "INHOUSE~|-~|ErwinT~| ~Options`n|^~")
count := 1 
Loop, Parse, meatier, `n 
{
	If (A_Index < 4)
		continue 
		payField%A_Index% := % A_LoopField

	If (RegExMatch(A_LoopField, "^~"))
	{
		payIndex%count% := % A_Index
		newInvs := % payIndex%count% . "," . newInvs 
;MsgBox % payField%A_Index%
		count += 1
	}
}
Sort, newInvs, N D,

count2 := 1 
Loop, Parse, newInvs, `,
{
	loop := A_LoopField + 1 
	payField := payIndex%count2%
	payNum%count2% := payField%A_LoopField% . "~" . payField%loop%
	loop := loop + 1
	If (loop = (newInvs[count2] + 1))
	{
		payNum%count2% := % payNum%count2% . "|" 
		Continue 
	}		
	Else 
	{
		payNum%count2% := payNum%count2% . "~" . payField%loop%
	}
		count2 := % count2 + 1
MsgBox % payNum%count2%
}

MsgBox % count
Return 

getAcctNumNamerevio:
{
tmpCB := ClipBoard 
	ClipBoard := "" 
		Send ^a
		Send ^c 
		ClipWait, 2 
	text := ClipBoard 
	text := RegExReplace(text, "m)`r`r|`r`n|`n`n", "`n") 
	array := StrSplit(text, "`n") 
	acctStuff := StrSplit(array[4],")") 
	acctNum := SubStr(acctStuff[1],2,-1)
	acctName := trim(acctStuff[2])
	ClipBoard := tmpCB 
	WinActivate, rev.io
		Click, 11 235
} 
Return 
But my brain is apparently no longer functioning. I have completely veered off course somewhere and I'm just making things worse the more I try to straighten it out. I am trying not to be too proud to ask for help here ... so be aware of my fragile ego if you choose to respond 🤣🤣

I don't necessarily want someone to FIX my code (although if you want, hey , I won't stop you 😎 ) ... a smack upside the head and a point in the right direction would be helpful. Also, if you have any hints on how I can pretty it up, speed it up, or just make things work better with fewer errors would be great. I am admittedly a "Search and Destroy" writer when trying to write my scripts, so I frequently opt for "well, it works" over trying to find the best, most efficient way to write a piece of code.

I'm walking away from this mess for a bit and will check later tonight or in the morning for any responses ... I need a drink ... 🍷🍷🍷
hd0202
Posts: 183
Joined: 04 Oct 2013, 03:07
Location: Germany near Cologne

Re: OMG I have a basic loop that is DRIVING ME NUTS

19 Nov 2021, 01:37

one simple note:
put your MsgBox % payNum%count2% before you increase *count2 := % count2 + 1 to show the results of your hard work

I hope this gives you new courage to proceed, you are on a good way !
Of course you can do everything differently, but that depends on your experience

Hubert
User avatar
Xtra
Posts: 2750
Joined: 02 Oct 2015, 12:15

Re: OMG I have a basic loop that is DRIVING ME NUTS

19 Nov 2021, 03:04

I believe you are having issues on the last 2 with the 3rd price on their own lines.
I took a different approach:
Spoiler
User avatar
Chunjee
Posts: 1452
Joined: 18 Apr 2014, 19:05
Contact:

Re: OMG I have a basic loop that is DRIVING ME NUTS

19 Nov 2021, 03:24

Ok here's two slaps in the head. Easy one first: avoid gosubs, use functions.

The next one is: don't mutate your raw data trying to malform it into the text you want.

In this example we use regex to grab the data we want and put it into variables customer, money, dateAndCustomer; the original text is never manipulated or changed, we just extract and leave it alone.

Code: Select all

text =
(
	Billing & CollectionsBills (Unpaid)1Ledger62Unposted1Payment History12Payment Accounts1Credit Checks
Create New: Adjustment · Credit · Charge · BillOther: Balance Transfer · Promise-to-Pay · Repost MRCs · Rerate Usage · History · Full Ledger
 	Payment #	Ref #	Method	Source	Auth Code	Date	Rep	Agent	Amount	Applied To
	76614	1159SPLIT	Manual Check
INHOUSE	-	10/26/2021	ErwinT	-	$18.35	160786: $18.35
 	Options
	68606	13872SPLIT	Manual Check
INHOUSE	-	9/21/2021	ErwinT	-	$18.44	147518: $18.44
 	Options
	63044	13858SPLIT	Manual Check
INHOUSE	-	8/25/2021	ErwinT	-	$18.44	134506: $18.44
 	Options
	56367	13837SPLIT	Manual Check
INHOUSE	-	7/26/2021	ErwinT	-	$18.44	121630: $18.44
 	Options
	48261	13819SPLIT	Manual Check
INHOUSE	-	6/16/2021	ErwinT	-	$18.50	109128: $18.5
 	Options
	42548	13805SPLIT	Manual Check
INHOUSE	-	5/19/2021	ErwinT	-	$17.50	97004: $17.5
 	Options
	35363	13775	Manual Check
INHOUSE	-	4/14/2021	ErwinT	-	$0.06	85058: $0.06
 	Options
	29692	13758SPLIT	Manual Check
INHOUSE	-	3/16/2021	ErwinT	-	$17.44	85058: $17.44
 	Options
	28854	62902461259	CC
INHOUSE	106576	3/11/2021	RaymondS	-	$17.44	61933: $1
73253: $16.44
 	Options
	19034	13717SPLIT	Manual Check
INHOUSE	-	1/21/2021	ErwinT	-	$18.44	61933: $17.44
73253: $1
 	Options
View Moreor View All
Services & Activity
)

; split data into an array for easier looping
dataAsArray := strSplit(text, "`n")
; create a new array to hold the data
extractedData := []


; grab the customer name and payment(s) out of each line
for key, value in dataAsArray {
	; regex the values we are interested in to variables
	regexMatch(value, "\d+\/\d+\/\d{4}\s(\w+)", dateAndCustomer)
	regexMatch(value, "\d+\.\d+", money)
	regexMatch(dateAndCustomer, "[a-zA-Z]+", customer)
	; fill object if customer name is found longer than 3 characters
	if (strLen(customer) > 3) {
		dataLine := {}
		dataLine.payment := money
		dataLine.name := customer

		; remember this customer for next loop if more payments
		lastCustomer := customer
	}
	; push data onto array, use the last customer if no newone defined on this line
	if (strLen(money) > 3 && lastCustomer == customer) {
		extractedData.push(dataLine)
		continue
	}
	if (strLen(money) > 3 && lastCustomer != customer) {
		extractedData.push({name: lastCustomer, payment: money})
	}
}
this puts all the data into a an array of objects extractedData which would look like the following:

Code: Select all

[{"name": "ErwinT", "payment": "18.35"},
{"name": "ErwinT", "payment": "18.44"}, 
{"name": "ErwinT", "payment": "18.44"}, 
{"name": "ErwinT", "payment": "18.44"}, 
{"name": "ErwinT", "payment": "18.50"}, 
{"name": "ErwinT", "payment": "17.50"}, 
{"name": "ErwinT", "payment": "0.06"}, 
{"name": "ErwinT", "payment": "17.44"}, 
{"name": "RaymondS", "payment": "17.44"}, 
{"name": "RaymondS", "payment": "16.44"}, 
{"name": "ErwinT", "payment": "18.44"}]
just me
Posts: 9528
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: OMG I have a basic loop that is DRIVING ME NUTS

19 Nov 2021, 04:04

shipaddicted wrote:The raw text from the section I need looks like this (copied from the MsgBox):
If your problem isn't solved, you'd post the original file contents.
shipaddicted
Posts: 108
Joined: 15 Jul 2016, 19:57

Re: OMG I have a basic loop that is DRIVING ME NUTS

19 Nov 2021, 13:57

Thanks for the help, all of you!! I think I almost have it ... I've run it on several different pages and I'm getting consistent results. but why is it adding the last line twice?? And how do I get rid of it? I thought adding

Code: Select all

allPays := RegExReplace(allPays, "m)`n.*`n$","")
at the end would remove it, but that didn't work.

Here is my final spaghetti monster:

Code: Select all

GoSub, getAcctNumNamerevio 
meat := RegExMatch(text, "Billing & Collections.*Services & Activity", meatier) 
meatier := SubStr(Trim(meatier), InStr(meatier, "`n",,,3)+1)
meatier := RegExReplace(meatier, "`r`n|`r`r|`n`n", "`n")
meatier := RegExReplace(meatier, "`t|`n", "~")  
meatier := RegExReplace(meatier, "Services & Activity")

count3 := 1 
for index, loops in StrSplit(meatier, "~Options~") 
{
	count := 1 
	for key, Val in StrSplit(Trim(loops, "~"), "~")
	{
		payNum%A_Index% := % Val
		count += 1
	}	
		payLine := % payNum1 . "," . payNum2 . "," . payNum3 . "," . payNum5 . "," . payNum6 . "," . payNum9
		count2 := 10
		Loop
		{
			invStuff := StrSplit(trim(payNum%count2%), ": ")
			payment%count3% := % payLine . "," . invStuff[1] . "," . invStuff[2]
			count2 += 1 
;			MsgBox % payment%count3% . "`n`n" . count2 . " ... " . count - 1
			allPays := % allPays . "`n" . payment%count3%			
			count3 += 1 
			If (count2 = (count - 1))
				Break 
			If ((count - 1) = 0)
				Break 
		}
}
	allPays := RegExReplace(allPays, "m)`n.*`n$","") 
	MsgBox % count3 . " `n`n " . allPays 
Return 

getAcctNumNamerevio:
{
	tmpCB := ClipBoard 
	Send {F3}
	Sleep 100 
	Send View All{Esc}{Enter}
	Sleep 500 
	ClipBoard := "" 
		Send ^a
		Send ^c 
		ClipWait, 2 
	text := ClipBoard 
	text := RegExReplace(text, "m)`r`r|`r`n|`n`n", "`n") 
	array := StrSplit(text, "`n") 
	acctStuff := StrSplit(array[4],")") 
	acctNum := SubStr(acctStuff[1],2,-1)
	acctName := trim(acctStuff[2])
	ClipBoard := tmpCB 
	WinActivate, rev.io
		Click, 11 235
} 
Return 

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: CoffeeChaton, Rohwedder and 154 guests