Get a value from an associative matrix

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Albireo
Posts: 1747
Joined: 16 Oct 2013, 13:53

Re: Get a value from an associative matrix

18 Jan 2018, 14:32

just me wrote:Rec_Array.Push(Value) appends the specified value(s) to Rec_Array and returns the index of the last added value.....
Interesting function - thanks - Good to know!

I have tried this .:

Code: Select all

RecIndex := Rec_Array.Push(Fields)	; Rec_Array - Simple array to hold the file records as arrays
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Rec_Array[RecIndex]
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Rec_Array[(RecIndex)]
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Rec_Array[1]
No result! - Maybe "Rec_Array" is probably not a Simple Array.

Content, from a specific field in "Rec_Array", appears with these three "MsgBox" - interesting

Code: Select all

	RecIndex := Rec_Array.Push(Fields)	; Rec_Array - Simple array to hold the file records as arrays
art_id = 1
RecIndex = 1
Rec_Array[RecIndex, art_id]
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Rec_Array[RecIndex, art_id]
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Rec_Array[(RecIndex), (art_id)]
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Rec_Array[1,1]
In order to see the entire "Rec_Array", do you not have to make a "loop" through every fields and records?

Code: Select all

PID_Array[Fields[1] . ""] := RecIndex
What happens here? [Fields[1] . ""]
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Get a value from an associative matrix

19 Jan 2018, 03:54

No result! - Maybe "Rec_Array" is probably not a Simple Array.
Rec_Array is a simple array of arrays, i.e. each "value" returned by Rec_Array[RecIndex] is an array reference. So MsgBox will show nothing.
[b]Objects->Usage->Remarks[/b] wrote:If an object is used in any context where an object is not expected, it is treated as an empty string. For example, MsgBox %object% shows an empty MsgBox and object + 1 yields an empty string. Do not rely on this behaviour as it may change.

In order to see the entire "Rec_Array", do you not have to make a "loop" through every fields and records?
Yes. Example:

Code: Select all

For RecIndex, FieldArray In Rec_Array
   For FieldIndex, FieldValue In FieldArray
      MsgBox, 0, Field %FieldIndex% of record %RecIndex%, %FieldValue%

What happens here? [Fields[1] . ""]
[Fields[1] . ""] ensures that the key will be a string key even if Fields[1] contains a pure number. (Do you remember?)
Albireo
Posts: 1747
Joined: 16 Oct 2013, 13:53

Re: Get a value from an associative matrix

19 Jan 2018, 10:03

Thanks for your time!
just me wrote:

Code: Select all

PID_Array[Fields[1] . ""] := RecIndex
[Fields[1] . ""] ensures that the key will be a string key even if Fields[1] contains a pure number. (Do you remember?)
Yes I remenber - intresting solution.
But I don't understand what the "." (dot) means.
Is the command

Code: Select all

PID_Array[Fields[1] . ""] := RecIndex
the same as

Code: Select all

PID_Array[Fields[1]] := PID_Array[Fields[1]] ""
PID_Array[Fields[1]] := RecIndex
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Get a value from an associative matrix

19 Jan 2018, 11:50

But I don't understand what the "." (dot) means.
The dot is the concatenate operator. If you concatenate a number with a string (even an empty string "") AHK will treat the result as a string in expressions.
Albireo
Posts: 1747
Joined: 16 Oct 2013, 13:53

Re: Get a value from an associative matrix

20 Jan 2018, 17:44

I have still problem with my program. Thought that "." (dot with space) would solve my desire.....
My wish (Step 1) is to write a function that reads (and handle) a CSV file - create an array.

My desire is just to enter the name of the array, the article number and name of the header, to get a value.
like this .: Result1 := ProdInfo.00053.Count or Result2 := ProdInfo.GT101264-1.Supplier
Made a try, but failed.. I did a function that reads data from a CSV file, and a function that manages CSV information from a variable (in a different way).
I tried to present a result from the CSV-file as follows .:

Code: Select all

MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "00053 - Counts .: " ProdInfo[00053 . "","Count"]
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "GT101264-1 Supplier .: " ProdInfo[GT101264-1 . "","Supplier"]
The first MsgBox give a result, but not the second.

I tried to present the result from the variable with these MsgBox

Code: Select all

MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "00053 - Counts .: " ProdInfo1._00053.Count
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "GT101264-1 Supplier .: " ProdInfo._GT101264-1.Supplier
The first MsgBox give a result, but not the second.

I had no idea why it doesn't work.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The test file (TestValue.txt) still looks like this .:

Code: Select all

"ArtNo";"Head1";"Head2";"Head3";"Count";"Supplier";

"00053";"Info1";"Info2";"Info3";"35";"Supp"
"001589-045-00";"Info1a";"Info2a";"Info3a";"128";"Supp1"

"GT101264-1";"Info1b";"Info2b";"Info3b";"0";"Supp2";
"00053";"Info1";"Info2";"Info3";"15";"Supp";
"00053";"Info1";"Info2";"Info3";"10";"Supp";
"939431-1";"Info1c";"Info2c";"Info3c";"17";"Supp";
;;;;;
And the test program look like this. (Much is from the program "just me" above)

Code: Select all

#SingleInstance	force
#NoEnv

Support = Support info

InputData = 
(LTrim Join
	"ArtNo";"Head1";"Head2";"Head3";"Count";"Supplier"`n
	"00053";"Info1";"Info2";"Info3";"35";"Supp"`n
	"001589-045-00";"Info1a";"Info2a";"Info3a";"128";"Supp1"`n
	"GT101264-1";"Info1b";"Info2b";"Info3b";"0";"Supp2"`n
	"00053";"Info1";"Info2";"Info3";"15";"Supp"`n`n
	"00053";"Info1";"Info2";"Info3";"10";"Supp"`n
	"939431-1";"Info1c";"Info2c";"Info3c";"17";"Supp"`n
	;;;;;`n
)
; Goto FileRead1
InputFile1 = TestValue.txt
ProdInfo := ReadFile(InputFile1, "ArtNo", "Count", A_LineNumber)
; ShowArray(ProdInfo, A_LineNumber)
; ShowMatrix(ProdInfo, A_LineNumber)
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "00053 - Counts .: " ProdInfo[00053 . "","Count"]
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "GT101264-1 Supplier .: " ProdInfo[GT101264-1 . "","Supplier"]


FileRead1:
ProdInfo1 := ReadData(InputData, "Count", A_LineNumber)
; ShowArray(ProdInfo1, A_LineNumber)
; ShowMatrix(ProdInfo1, A_LineNumber)
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "00053 - Counts .: " ProdInfo1._00053.Count
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "GT101264-1 Supplier .: " ProdInfo._GT101264-1.Supplier
ExitApp

ReadFile(FileName, TheKey, AddHead, JumpFromLine)	; 
{	; - FileName = The CSV-filename
	; - TheKey - Name of the key field (an unique field)
	; - AddHead - Name of field to be added, if "AddHead" is empty no field is added
	; - JumpFromLine - Used only to know where the call came from
	
	Global Support
	ArrayXY := []
	ArtID := []
	
	If !(FileHandle := FileOpen(FileName, "r"))
		ErrorExit("Could not open " . FileName, A_LineNumber)
	
	; Progress B2 zh0 fs18 CWFFFF00, Loading inventory ...	
	ST := A_TickCount
	For RecordIndex, Record In StrSplit(FileHandle.Read(), "`n", "`r")
	{	Fields := StrSplit(Record, ";", """")
		If ( Fields[1] = "" ) ; Skip invalid records
			Continue

		If !Header	; Check the header as the first approved line
		{	If ( Fields[1] <> TheKey )	; If the first field is not the unique field or the headerfield is missing
			{	SplitPath FileName, OutFileName, OutDir
				RecordField1 := Fields[1]
				Txt1 = First field in the first row (a headline?) .: %RecordField1%
				Txt2 = must be the same as
				Txt3 = Preferred KEY field (wrong key?) .: %TheKey%
				Txt4 = FileName (wrong file?) .: %OutFileName%
				Txt5 = FilePath (wrong path?) .: %OutDir%
				Txt6 = The header found (missed header?) .: `n%Record%
				ErrorExit(Txt1 "`n" Txt2 "`n" Txt3 "`n`n" Txt4 "`n" Txt5 "`n`n" Txt6, A_LineNumber)
			}
			
			; If the Header on the field is missing, give the field a name (usually the last field)
			; ex. Header .:  Fields = "art_id";"art_ean";"art_ean2";"Barcode3";"Barcode4";"su_art_id".......
			For ID, FieldName in Fields	; Check if one header is missing
			{	If !FieldName	; Header for one field is missing
					Fields[(A_Index)] := "NoName" A_Index
			}
			FieldCount := Fields.Length()
			Header := Fields	; Save the name of the Headers
			Continue
		}
		
		; - - - - - Check and handle the article fields below - - - - -
		If ( Fields[1] = "" ) ; Skip invalid records
			Continue
		
		; Are there more number of headers than fields? - Add empty field in the end of the array.
		If ( Fields.Length() < FieldCount )
		{	Loop % FieldCount - Fields.Length()
			{	Fields.Push("")
			}
		}

		; Stop the program if there are more number of fields than headers?
		If ( Fields.Length() > FieldCount )
		{	SplitPath FileName, OutFileName, OutDir
			FieldNo := Fields.Length()
			Txt1 = The Header have .: %FieldCount% fields.
			Txt2 = This row (no %A_Index%) in the file, have .: %FieldNo% fields.
			Txt3 = FileName (wrong filename?) .: %OutFileName%
			Txt4 = FilePath (wrong path?) .: %OutDir%
			Txt5 = The fields .: `n%Record%
			ErrorExit( Txt1 "`n" Txt2 "`n`n" Txt3 "`n" Txt4 "`n`n" Txt5, A_LineNumber)
		}
		; - - - - Error handling is complete
		; - - - - Array .: Header exist - 1:ArtNo  2:Head1  3:Head2... (Simple array - to remember)
		; - - - - Array .: Fields exist - 1:001-1  2:Info1  3:Info2... (Simple array - every field on each line)
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


		ArtCount += 1	; Number of articles
		; --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
		; ShowArray(Header,A_LineNumber)	; 1:ArtNo  2:Head1  3:Head2  4:Head3  5:Count   6:Supplier   7:NoName7
		; ShowArray(Fields,A_LineNumber)	; 1:00053  2:Info1  3:Info2  4:Info3  5:35      6:Supp       7:
		; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "ArtCount .: " ArtCount "`nHeader.1 .: " Header.1 "`nFields.1 . .: " Fields.1 "`n`nHeader[ArtCount] .: " Header[ArtCount] "`nFields[ArtCount] . .: " Fields[ArtCount]
		; --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
				
		; All ArticleNumbers in a Array "ArtID" .: 00053:1   001589-045-00:2   GT101264-1:3 ...
		If ArtID.HasKey(Fields[1] . "")	; Add the contents to the selected field "AddHead"
		{	If AddHead
			{	For ID, HeaderValue in Header	; Check which field to add
				{	If ( HeaderValue = AddHead )
					{	ArrayXY[ Fields[1] . "", AddHead] += Fields[ID]	; Calculate the field "AddHead"
					}
				}
			}
			; Maybe - Message to a log file - Article is ignored
			
			ArtCount -= 1	; Adjust the number of articles
			Continue	; Next Article
		}
		else
			ArtID[Fields.1 . ""] := ArtCount	; Add all unique article number to the array "ArtID"

		For ID, HeaderValue in Header
		{	If A_Index = 1
			{	Array_X%ArtCount% := { (HeaderValue) . "" : Fields[ID] . "" }	; Array_X1["ArtNo":"00053"] - Create a new array at same time
				ArrayXY[Fields.1 . ""] := Array_X%ArtCount%						; Add 
			}
			else
				Array_X%ArtCount%[(HeaderValue . "")] := Fields[ID] .  ""
		}
		/*
		ShowArray(Array_X%ArtCount%, A_LineNumber)
		; Check the result - What work?
		MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "Array_X" ArtCount "`t" Array_X%ArtCount%.ArtNo	; The test works
		MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY["00053","Count"]							; The test works
		MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY["00053" . "","Count"]						; The test works
		ArtNumberTest = 00053
		MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY[ArtNumberTest . "","Count"]				; The test works
		MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY[00053 . "","Count"]						; The test works
		MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY[ Array_X%ArtCount%.ArtNo . "","Count"]		; The test works
		*/
		
		; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Fields[1]
		; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY[(Fields[1])][Count]						; The test does not work
		; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Fields[1] "`n- " ArrayXY["00053"][Count]			; The test does not work
		; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "- " Fields[1] "`n- " ArrayXY[00053 . ""][Count]		; The test does not work
		; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "- " Fields[1] "`n- " ArrayXY.001589-045-00.Count	; The test does not work
		; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "- " Fields[1] "`n- " Header[1] "`n- " ArrayXY.001589-045-00.Count	; The test does not work
	}
	Return ArrayXY
}



ReadData(InputData, AddHead, CallNo)
{	ArrayXY := {}	; Define the result array
	
	ST := A_TickCount	; Start Time
	
	; Create an array for each product (row)
	AddHead = Count	; Specifies the field name, containing the "Counts"
	; AddHead = 	; No field to count
	
	Loop Parse, InputData, `n	; Loop Parse, InputData, `n, `"
	{	ArtCount += 1
		StringSplit Row_%ArtCount%_, A_LoopField, `;, `"
		HeadCount := Row_%ArtCount%_0	; Remember the number of headers
		
		If ((StrLen(A_LoopField)+1 = Row_%ArtCount%_0) or (Row_%ArtCount%_0 = 0))	; Skip if all field is empty (;;;;;) OR empty lines ()
		{	ArtCount -= 1
			Continue
		}
		
		If (A_Index = 1)	; Handle the Header line
		{	Loop % Row_%ArtCount%_0
			{	Header_%A_Index% := Row_%ArtCount%_%A_Index%
				; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Header_%A_Index% 
				If (Row_%ArtCount%_%A_Index% = AddHead)
				{	CountFieldNo := A_Index	; Remember which field to add "Count"
					CountFieldExist = "Yes"
				}
			}
			; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "AddHead .: " AddHead "`nRow_%ArtCount%_0 = " Row_%ArtCount%_0 "`nCountFieldNo = " CountFieldNo "`nCountFieldExist = " CountFieldExist
			; If the header not exist and a counted field is desired
			If !CountFieldExist and AddHead
			{	MsgBox 16, Row.: %A_LineNumber% -> %A_ScriptName%, The CountField "%AddHead%" doesn't exist and can't be handled! `nThis program must stop.
				MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, The program ends!, 1
				ExitApp
			}
			ArtCount -= 1	; Don't count the header line
			Continue
		}
		Row_%ArtCount%_1 := "_" Row_%ArtCount%_1	; Add underline before the first field ("00053" => "_00053")
		
		; Check if the first field already exist
		Loop %ArtCount%
		{	 ; Compare with previous ArtNo - Does the first field, exist earlier?
			If (A_Index < ArtCount) and (Row_%ArtCount%_1 = Row_%A_Index%_1)	; YES - Add the selected field
			{	If !AddHead	; No field to calculate
				{	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "The Product ID .: ( " Row_%ArtCount%_1 " ) already exists! `nHow should it be handled?"
					; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Array_X%A_Index%.ArtNo "`n" Array_X%A_Index%.Count "`n + " Row_%ArtCount%_%CountFieldNo%
				}
				else
					Array_X%A_Index%[(AddHead)] += Row_%ArtCount%_%CountFieldNo%	; Calculate the field "AddHead"
				ArtCount -= 1	; Adjust the pointer
				Break
			}	
			
			; First field doesn't erlier exist - Create a "New array" and add that to the "Result array"
			If (A_Index = ArtCount)
			{	Loop % Row_%ArtCount%_0
				{	If A_Index = 1
					{	Array_X%ArtCount% := { (Header_%A_Index%) : Row_%ArtCount%_1 }	; Create a new array Array_X?? with first KEY and value {"ArtNo":"_00053"}
						ObjRawSet( ArrayXY, Row_%ArtCount%_1, Array_X%ArtCount% )	; Create ArrayXY := { "00053":Array_X1, "001589-045-00":Array_X2, .... }
					}
					else
					{	; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "Array .: Array_X" ArtCount "`n- " Header_%A_Index% "`nArtCount .: " ArtCount "`nA_Index .: " A_Index "`nRow_" ArtCount "_" A_Index ".: " Row_%ArtCount%_%A_Index%
						ObjRawSet( Array_X%ArtCount%, Header_%A_Index%, Row_%ArtCount%_%A_Index% )	; Add a new KEY and a Value to an existing Array
					}
				}
				/*
				ShowArray(Array_X%ArtCount%, A_LineNumber)
				; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Array_X%ArtCount%[(Fields[1])]["Count"]	; Fungerar inte
				MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY._00053.Count	; Fungerar
				MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY["_00053","Count"]	; Fungerar
				MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY["_00053" . "","Count"]	; Fungerar
				MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % Array_X%ArtCount%.ArtNo	; Fungerar
				MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % ArrayXY[ Array_X%ArtCount%.ArtNo . "","Count"]	; Fungerar
				*/
				
				; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "- " Header_%A_Index% "`nArtCount .: " ArtCount "`nA_Index .: " A_Index "`nRow_" ArtCount "_" A_Index ".: " Row_%ArtCount%_%A_Index%
				; ShowMatrix(ArrayXY, A_LineNumber)
				; MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "- " Fields[1] "`n- " ArrayXY[_00053 . ""][Count]
			}
		}
	}
	Return % ArrayXY
}


ErrorExit(Msg, JumpFromLine)
{	; Version .: 18 jan 2018
	Global Support
	MsgBox 16, Row.: %A_LineNumber% -> %A_ScriptName%,
	(LTrim Join
		ERROR! `t(Jump from line .: %JumpFromLine% )`n`n
		%Msg% `n`n
		Contact support .: %Support% `n`n
		This program will be terminated!
	)
	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, The program terminates!, 1
	ExitApp
}

ShowArray(ArrayName, JumpFromLine)
{	; Version .: 18 jan 2018
	For i, Value in ArrayName	; For "Key", "Value" i SimpleArray
		List .= "Loop .: " A_Index "`tKey . .: " i "`nValue . . . . . . . . . . . . . . . . .: " Value "`n`n"
	Text := List
	; Text := "Show the keys .: `n`n" List
	; FileAppend %Text%, ArtRegKey.txt
	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "Jump from Line .: " JumpFromLine "`nNumber of keys .: " ArrayName.Length() " pcs.`n`n" Text
}

ShowMatrix(ArrayName, JumpFromLine)
{	; Version .: 20 jan 2018
	MaxRows = 40	; Max antal poster som visas.
	For ID, FieldArray In ArrayName
	{	List := "Record: " ID " (of " ArrayName.Length() " Records) `tFrom Line .: " JumpFromLine "`n`n`t   Key .: `t`tValue.: `n"
		For FieldIndex, FieldValue In FieldArray
		{	If FieldIndex <= %MaxRows%
				List .= "Loop .: " A_Index "`t     " FieldIndex "   - - - - - - - -`t" FieldValue "`n"
			If FieldIndex = %MaxRows%
				List .= "...`n...`n`nMax " MaxRows " records is shown"
		}
	}
	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % List
}
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Get a value from an associative matrix

21 Jan 2018, 05:14

Albireo wrote:My desire is just to enter the name of the array, the article number and name of the header, to get a value.
In this case you won't be able to access the array using the object-syntax

Code: Select all

Result1 := ProdInfo.00053.Count
because all keys have to be passed as variables. You need to use the array-syntax using variables instead

Code: Select all

Result1 := ProdInfo[ArticleNumber, HeaderFieldName]
You should adjust your test scripts as follows:

Code: Select all

ArtNumber := 00053
FieldName := "Count"
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "00053 - Counts .: " ProdInfo[ArtNumber . "",FieldName]
ArtNumber := "GT101264-1"
FieldName := "Supplier"
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "GT101264-1 Supplier .: " ProdInfo[ArtNumber . "",FieldName]
If you access an array using the array-syntax you have to follow the expression syntax rules:
  • Pure numbers are treated as numbers.
  • Literal strings must be enclosed with double-quotes.
  • All other isolated strings are treated as variable names.
So in

Code: Select all

MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "00053 - Counts .: " ProdInfo[00053 . "","Count"]
00053 will be treated as a number whereas in

Code: Select all

MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % "GT101264-1 Supplier .: " ProdInfo[GT101264-1 . "","Supplier"]
GT101264-1 will be treated as the (invalid) name of a variable.

Code: Select all

Array := {"": "Sorry!", "GT101264-1": "Bingo!"} ; added an empty key
MsgBox, % Array[GT101264-1] . " - " . Array["GT101264-1"]
Albireo
Posts: 1747
Joined: 16 Oct 2013, 13:53

Re: Get a value from an associative matrix

21 Jan 2018, 10:56

Many thanks! I see the problem... (and understand your descriptions)
Wondering if it is the best to make function that handle the input problems that may occur, because I have hard to know how accurate the information is in the input file. (something like this)

Code: Select all

ArtNum = "00053"
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % GetArrValue(ProdInfo, ArtNum, "Count")

GetArrValue(ArrayName, Key, Value)
{	If InStr(Key, """")
		StringMid Key, Key, 2, StrLen(Key)-2
	If InStr(Value, """")
		StringMid Value, Value, 2, StrLen(Value)-2
	Return % ArrayName[Key . "", Value]
}
Interesting way to handle the (invalid) name of a variable.

To catch a misspelled "key" may this work?

Code: Select all

Color := {Blue: "0x0000FF", Yellow:"0xFFFF00"}
MsgBox % " Color .: " Color.Yellow

ArrName := "Color"
ArrKey := "Yellow"
MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % GetArrValue(ArrName, ArrKey)

MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, % GetArrValue("Color", "Green")

GetArrValue(ArrayName, Key)
{	; Version 21 jan 2018
	If InStr(Key, """")
		StringMid Key, Key, 2, StrLen(Key)-2

	If !%ArrayName%.HasKey(Key)
	{	MsgBox 64, Row.: %A_LineNumber% -> %A_ScriptName%, The Key .: %Key% `nDoes not exist in the Array .: %ArrayName% `n`nThis program is ended!
	 	ExitApp
	}
	Return % %ArrayName%[Key . ""]
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: tiska and 112 guests