Sign in to follow this  
Followers 0
sfresher

Does AutoIt support multi-demension array?

10 posts in this topic

Here is my question:

I have a file "Test.csv", looks like:

a1, b1, c1

a2, b2, c2

All I need to do is to read each values in my script.

"," is the delimiter, then how can I read the csv file to arrays - something like:

array[1][1] = a1

array[1][2] = b1

...

array[2][2] = b2

array[2][3] = c2

Share this post


Link to post
Share on other sites



Here is my question:

I have a file "Test.csv", looks like:

a1, b1, c1

a2, b2, c2

All I need to do is to read each values in my script.

"," is the delimiter, then how can I read the csv file to arrays - something like:

array[1][1] = a1

array[1][2] = b1

...

array[2][2] = b2

array[2][3] = c2

Read the help file on "varibles", which includes a description of AutoIt arrays.

Read the help file on FileReadLine() and StringSplit() to see how to read lines and split them into arrays.

If you get stuck, post what you've got and ask for more help... but it all starts with the help file.

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I guess I am just not a good coder. I had put plenty of time in looking the help and searching the forum. For the problem, here is what I got:

The TestInput.csv is like:

a1|b1|c1

a2|b2|c2

When I run this, I got error: "Array variable has incorrect number of subscript dimension range exceeded.

If I change output to $arrary[1], the output is blank, not "a1".

#include <Constants.au3>

$hTestInput = FileOpen (@ScriptDir & "\TestInput.csv", 0)

; Check if file opened for reading OK
If $hTestInput = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

; Read in lines of text until the EOF is reached
While 1
    $line = FileReadLine($hTestInput)
    If @error = -1 Then ExitLoop
    MsgBox(0, "Line read:", $line)
Wend

FileClose($hTestInput)

dim $array = StringSplit($line, "|", 1)
MsgBox (0, "", "The array1 is " & $array[1][1])

Read the help file on "varibles", which includes a description of AutoIt arrays.

Read the help file on FileReadLine() and StringSplit() to see how to read lines and split them into arrays.

If you get stuck, post what you've got and ask for more help... but it all starts with the help file.

:)

Edited by sfresher

Share this post


Link to post
Share on other sites

StringSplit() returns a single dimensioned array. You're trying to check it with a multi-dimension. You can't just do magic like that unfortunately :) ...


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Thanks for your clarification. The multi-dimension is must for me, can anyone point me an UDF or method to solve this?

Let's say the file is CSV, not .xls (no Excel on the computer).

StringSplit() returns a single dimensioned array. You're trying to check it with a multi-dimension. You can't just do magic like that unfortunately :) ...

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Thanks for your clarification. The multi-dimension is must for me, can anyone point me an UDF or method to solve this?

Let's say the file is CSV, not .xls (no Excel on the computer).

It's something you'd have to create on your own, as it's not something most would utilize for themselves.

Steps I'd take are probably:

(Remember, this is not tested at all)

Func _MyCSVCustomFunc($s_csv_file, $s_delimiter = ",")
    Local $s_read = FileRead($s_csv_file)
    Local $a_split_lines = StringSplit(StringStripCR($s_read), @LF)
   
    ; How many elements will our 2nd dimension have?
   
    ; Create 2D array
    Local $a_ret[$a_split_lines[0] + 1][1]
    Local $a_split, $i_add = 0, $i_last_ub = 1
   
    ; Populate 2D array
    For $i = 1 To $a_split_lines[0]
        If $a_split_lines[$i] Then
            $i_add += 1
            $a_split = StringSplit($a_split_lines[$i], $s_delimiter)
            If $i_last_ub < $a_split[0] Then
                $i_last_ub = $a_split[0]
                Redim $a_ret[$a_split_lines[0] + 1][$a_split[0] + 1]
            EndIf
            For $n = 1 To $a_split[0]
                $a_ret[$i_add][$n] = $a_split[$n]
            Next
        EndIf
    Next
   
    ; If there are no matches, set error and return
    If $i_add = 0 Then Return SetError(1, 0, 0)
    ; Reset array with correct dimensions (we only want data, not blank lines)
    ReDim $a_ret[$i_add + 1][$i_last_ub + 1]
    $a_ret[0][0] = $i_add
    Return $a_ret
EndFunc
Edited by SmOke_N
Edited function to make up for silly CSV creators

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

I guess I am just not a good coder. I had put plenty of time in looking the help and searching the forum. For the problem, here is what I got:

The TestInput.csv is like:

a1|b1|c1

a2|b2|c2

When I run this, I got error: "Array variable has incorrect number of subscript dimension range exceeded.

If I change output to $arrary[1], the output is blank, not "a1".

#include <Constants.au3>

$hTestInput = FileOpen (@ScriptDir & "\TestInput.csv", 0)

; Check if file opened for reading OK
If $hTestInput = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

; Read in lines of text until the EOF is reached
While 1
    $line = FileReadLine($hTestInput)
    If @error = -1 Then ExitLoop
    MsgBox(0, "Line read:", $line)
Wend

FileClose($hTestInput)

dim $array = StringSplit($line, "|", 1)
MsgBox (0, "", "The array1 is " & $array[1][1])
Your handling of the lines needs to be inside the loop. This creates a 2D array for output with a row for every line, and dynamically updates the number of columns along the way:

Test1.csv:

a|b|c
d|e
f|g|h|i|j
k|l|m

Test1.au3:

#include <File.au3>
#include <Array.au3>

Global $sDelim = "|"; delimiter
Global $sTestInput = @ScriptDir & "\Test1.csv", $hTestInput
Global $iCnt = _FileCountLines($sTestInput)
Global $avOutput[$iCnt + 1][1] = [[$iCnt]]; 2D output array

; Check if file opened for reading OK
$hTestInput = FileOpen($sTestInput, 0)
If $hTestInput = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf

; Read in lines of text until the EOF is reached
For $iLine = 1 To $iCnt
; Read line
    $sLine = FileReadLine($hTestInput)
    If @error Then ExitLoop
    
; Split line at delimiter
    $avTemp = StringSplit($sLine, $sDelim)
    
; Resize output array if required
    If $avTemp[0] > UBound($avOutput, 2) Then
        ReDim $avOutput[UBound($avOutput)][$avTemp[0]]
    EndIf
    
; Copy data
    For $n = 1 To $avTemp[0]
        $avOutput[$iLine][$n - 1] = $avTemp[$n]
    Next
Next
FileClose($hTestInput)
$avOutput[0][1] = UBound($avOutput, 2)

_ArrayDisplay($avOutput, "$avOutput")

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Guys, highly appreciated!

PsaltyDS's method is more suitable to my work, as it reads the array item dynamically.

Thanks a lot to both of you.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Guys, highly appreciated!

PsaltyDS's method is more suitable to my work, as it reads the array item dynamically.

Thanks a lot to both of you.

:) ok... >_<

Edit:

Ahh, you're saying you have a screwed up CSV file, and whomever created it was stupid enough not to make sure each line on the CSV file had the same delimeters.

Edit2:

There, edited my function above... was only a 4 line add in.

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Actually, I tested this one...

; Start array on element 1 of the 2nd dimension
$a_array_one = _MyCSVCustomFunc("some.csv")
_ArrayDisplay($a_array_one)

; Start array on element 0 of the 2nd dimension
$a_array_two = _MyCSVCustomFunc("some.csv")
_ArrayDisplay($a_array_two, ",", 0)

Func _MyCSVCustomFunc($s_csv_file, $s_delimiter = ",", $i_base = 1)
    Local $s_read = FileRead($s_csv_file)
    Local $a_split_lines = StringSplit(StringStripCR($s_read), @LF)
   
    ; Create 2D array
    Local $a_ret[$a_split_lines[0] + 1][1]
    Local $a_split, $i_add = 0, $i_last_ub = 1
   
    ; Populate 2D array
    For $i = 1 To $a_split_lines[0]
        If $a_split_lines[$i] Then
            $i_add += 1
            $a_split = StringSplit($a_split_lines[$i], $s_delimiter)
            If $i_last_ub < $a_split[0] Then
                $i_last_ub = $a_split[0]
                Redim $a_ret[$a_split_lines[0] + 1][$a_split[0] + 1]
            EndIf
            For $n = 1 To $a_split[0]
                $a_ret[$i_add][($n - 1) + $i_base] = $a_split[$n]
            Next
        EndIf
    Next
   
    ; If there are no matches, set error and return
    If $i_add = 0 Then Return SetError(1, 0, 0)
    ; Reset array with correct dimensions (we only want data, not blank lines)
    ReDim $a_ret[$i_add + 1][$i_last_ub + 1]
    $a_ret[0][0] = $i_add
    Return $a_ret
EndFunc
Works fine.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
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
Sign in to follow this  
Followers 0