Page 1 of 1 1
Topic Options
#161061 - 2006-04-24 11:56 AM multidimentional arrays.
Gilrim Offline
Fresh Scripter

Registered: 2005-07-19
Posts: 20
i've been trying to parse a csv file for some time now, and cant figure out how it's done...

I've loaded the csv into a array, using the readFile() UDF, but as soon as I start doing stuff like:

Code:

$serverlist = readfile("serverliste.csv")
$dimen = Ubound($serverlist)
logLine("Filen har: $dimen linjer")

dim $blah[$dimen,2]
$currrow = 0

For Each $row In $serverlist
logLine("$row")
$temp = split($row,";")
$blah[$currrow,0] = $temp[0]
$blah[$currrow,1] = $temp[1]
$blah[$currrow,2] = $temp[2]
$currrow = $currrow +1
Next



I keep getting "array reference out of bounds!", even though is should be "in bounds" afaik...

Anyone see what's wrong here?

Top
#161062 - 2006-04-24 12:09 PM Re: multidimentional arrays.
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
what is $temp[0] ?

I think you should give us a little bit more of the script in question, if not the whole.
Plus maybe parts of/the whole csv file
_________________________



Top
#161063 - 2006-04-24 12:25 PM Re: multidimentional arrays.
Gilrim Offline
Fresh Scripter

Registered: 2005-07-19
Posts: 20
I could, but because I'm using kixforums, it's got ~220 lines :P

here's a sample line from the csv: shnh-dc;192.168.241.200;SHNH
and $temp is filled from the split on the line in front of it

is there a dropbox somewhere, I could post the full .kix?

Top
#161064 - 2006-04-24 12:32 PM Re: multidimentional arrays.
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
Well,

it doesn't matter if you use kixforms or not and as far as I remember 220 lines are also no problem. Just make sure to post the code between CODE-Tags (Instant UBB Code) to preserve formatting (and maybe break long lines for readability)
_________________________



Top
#161065 - 2006-04-24 01:08 PM Re: multidimentional arrays.
Gilrim Offline
Fresh Scripter

Registered: 2005-07-19
Posts: 20
Code:



Break On
$System = CreateObject("Kixtart.System")

;KD START

;************* Form **************
$Form = $System.Form()
$Form.BackColor = 212,208,200
$Form.FontSize = 8,25
$Form.FormBorderStyle = 3
$Form.Height = 566
$Form.Left = 119
$Form.MaximizeBox = "False"
$Form.Text = "Automagisk RDP fil generator"
$Form.Top = 78
$Form.Width = 400
;**************************************

;************* Label1 **************
$Label1 = $Form.Controls.Label()
$Label1.BackColor = 212,208,200
$Label1.FontSize = 8,25
$Label1.Height = 18
$Label1.Left = 15
$Label1.Text = "Brukernavn:"
$Label1.ToolTipText = "Brukernavn som sendes til serveren. Standard innlogget bruker + _adm"
$Label1.Top = 15
$Label1.Width = 89
;**************************************

;************* user **************
$user = $Form.Controls.TextBox()
$user.AcceptsTab = "True"
$user.FontSize = 8,25
$user.Height = 20
$user.Left = 111
$user.MaxLength = 128
$user.Text = @UserID + "_adm"
$user.Top = 15
$user.Width = 174
;**************************************

;************* progress **************
$progress = $Form.Controls.ProgressBar()
$progress.BackColor = 212,208,200
$progress.Height = 23
$progress.Left = 9
$progress.Step = 1
$progress.Top = 219
$progress.Value = 0
$progress.Width = 288
;**************************************

;************* browseButton **************
$browseButton = $Form.Controls.Button()
$browseButton.FontSize = 8,25
$browseButton.Height = 25
$browseButton.Left = 300
$browseButton.Text = "..."
$browseButton.Top = 79
$browseButton.Width = 33
$browseButton.OnClick = "selectDirectory()"
;**************************************

;************* generer **************
$generer = $Form.Controls.Button()
$generer.FontSize = 8,25
$generer.Height = 25
$generer.Left = 300
$generer.Text = "Generer Filer"
$generer.Top = 219
$generer.Width = 83
$generer.OnClick = "save()"
;**************************************

;************* log **************
$log = $Form.Controls.ListBox()
$log.FontSize = 8,25
$log.Height = 277
$log.Left = 12
$log.Top = 252
$log.Width = 370
;**************************************

;************* CheckBox1 **************
$CheckBox1 = $Form.Controls.CheckBox()
$CheckBox1.BackColor = 212,208,200
$CheckBox1.CheckAlign = 16
$CheckBox1.Checked = "True"
$CheckBox1.CheckState = 1
$CheckBox1.FontSize = 8,25
$CheckBox1.Height = 19
$CheckBox1.Left = 12
$CheckBox1.Text = "Torgnes"
$CheckBox1.Top = 192
$CheckBox1.Width = 71
;**************************************

;************* windowheight **************
$windowheight = $Form.Controls.TextBox()
$windowheight.FontSize = 8,25
$windowheight.Height = 20
$windowheight.Left = 111
$windowheight.Text = "750"
$windowheight.Top = 38
$windowheight.Width = 174
;**************************************

;************* Label2 **************
$Label2 = $Form.Controls.Label()
$Label2.BackColor = 212,208,200
$Label2.FontSize = 8,25
$Label2.Height = 19
$Label2.Left = 15
$Label2.Text = "Vinduhøyde:"
$Label2.ToolTipText = "Høyden på vinduet fra serveren"
$Label2.Top = 38
$Label2.Width = 90
;**************************************

;************* Label3 **************
$Label3 = $Form.Controls.Label()
$Label3.BackColor = 212,208,200
$Label3.FontSize = 8,25
$Label3.Height = 16
$Label3.Left = 15
$Label3.Text = "Vindubredde:"
$Label3.ToolTipText = "Bredden på vinduet fra serveren"
$Label3.Top = 60
$Label3.Width = 89
;**************************************

;************* windowwidth **************
$windowwidth = $Form.Controls.TextBox()
$windowwidth.FontSize = 8,25
$windowwidth.Height = 20
$windowwidth.Left = 111
$windowwidth.Text = "1000"
$windowwidth.Top = 60
$windowwidth.Width = 174
;**************************************

;************* Label4 **************
$Label4 = $Form.Controls.Label()
$Label4.BackColor = 212,208,200
$Label4.FontSize = 8,25
$Label4.Height = 18
$Label4.Left = 15
$Label4.Text = "Lagringssti"
$Label4.ToolTipText = "Sti hvor filene skal genereres"
$Label4.Top = 82
$Label4.Width = 92
;**************************************

;************* path **************
$path = $Form.Controls.TextBox()
$path.FontSize = 8,25
$path.Height = 20
$path.Left = 111
$path.Text = "c:\rdp\"
$path.Top = 82
$path.Width = 174
;**************************************

Function save()
$path = $path.text
$width = $windowwidth.Text
$height = $windowheight.Text
$name = $user.Text
logLine("Starter generering av filer. ")
logLine("Bruker katalogen $path, vindubredde: $width, høyde $height og brukernavn: $name")
logLine("og brukernavn: $name")
EndFunction

Function readfile($file)
Dim $lf, $f, $_, $t
$lf=chr(10)
$f=freefilehandle()
$_=open($f,$file)
if @error exit @error endif
do $t=$t+readline($f)+$lf until @error
$_=close($f)
$ReadFile=split(substr($t,2),$lf)
EndFunction

Function logLine($line)
$log.AddItem ("$line")
EndFunction

Function selectDirectory()
$dir = $System.FolderBrowserDialog()
$dir.RootFolder = $path.text
If ($dir.ShowDialog() = 0)
logLine("Fikk ikke valgt katalog. Feilkode: @ERROR")
Else
logLine("Valgte katalogen:"+ $dir.SelectedPath)
EndIf
$selDir=$dir.SelectedPath
$path.text = $selDir
EndFunction

;KD END

$serverlist = readfile("serverliste.csv")
$dimen = Ubound($serverlist)
logLine("Filen har: $dimen linjer")

dim $blah[$dimen,2]
$currrow = 0

For Each $row In $serverlist
logLine("$row")
$temp = split($row,";")
$blah[$currrow,0] = $temp[0]
; $blah[1,$currrow] = $temp[1]
; $blah[$currrow,2] = $temp[2]
$currrow = $currrow +1
Next


$Form.Show
While $Form.Visible
$=Execute($Form.DoEvents())
Loop
Exit 1


Top
#161066 - 2006-04-24 02:43 PM Re: multidimentional arrays.
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
I think the error sits here :

Code:

$serverlist = readfile("serverliste.csv")



unless serverliste.csv isn't placed in the current directory the function won't find the file.

You can verify this with the following (using kix32.exe):

Code:

$serverlist = readfile("serverliste.csv")
? @error + " - " + @serror



If this returns other than "0 - The command completed successfully" you should add a path to the filename
_________________________



Top
#161067 - 2006-04-24 10:21 PM Re: multidimentional arrays.
Gilrim Offline
Fresh Scripter

Registered: 2005-07-19
Posts: 20
serverlist.csv is in the current directory, and this is the default, expected behaviour. Besides, the script runs nicely and reads the file just fine, until
either of
; $blah[$currrow,1] = $temp[1]
; $blah[$currrow,2] = $temp[2]
is un-commented.

So the problem is something to do with the dim $blah[$dimen,2] thingie, I think? sorta new to multidimentional arrays in kix so...

Top
#161068 - 2006-04-25 09:55 AM Re: multidimentional arrays.
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
Allright,

I will create a csv file on your template and retest.
My last reply was based totally on assumptions, stand by please...
_________________________



Top
#161069 - 2006-04-25 10:18 AM Re: multidimentional arrays.
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
The problem you have with your script is caused by Radimus' readfile udf.

It returns always 2 additional empty array elements. [edit: the original udf from the library returns only 1 additional empty!!]
So in the loop you try to split an empty element to 3 chunks and of course fail with "array reference out of bounds" referencing the non-existant elements of $temp.

[edit: oh, by the way in your posted script you have puzzled the elements of $blah, the one referencing $temp[1] ]


Edited by Jochen (2006-04-25 10:25 AM)
_________________________



Top
#161070 - 2006-04-25 10:45 AM Re: multidimentional arrays.
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
You should have some error checking for array boundaries when using split, it will save you a lot of pain.

An alternative method is just to ensure that you have sufficient delimiters. If you change your split to read:
Code:
    $temp = split($row+";;",";")



You will always have at least three elements and will avoid the error. You should still check for missing data though.

Top
#161071 - 2006-04-25 11:04 AM Re: multidimentional arrays.
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
Yeah,

I know that for sure ... but the point here is that he uses a udf from our library which returns unexpected results.
_________________________



Top
#161072 - 2006-04-25 11:38 AM Re: multidimentional arrays.
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
Additional information:

the ammount of elements (or lines) is not equal to the upper bound of the array, it is of course ubound+1, so this will for example be neccessary:

Code:

logLine("Filen har: " + ($dimen + 1) + " linjer")

_________________________



Top
#161073 - 2006-04-25 11:42 AM Re: multidimentional arrays.
Jochen Administrator Offline
KiX Supporter
*****

Registered: 2000-03-17
Posts: 6380
Loc: Stuttgart, Germany
here is a working version (borrowed an adapted {redim ubound-1} Readfile udf by Cristophe Melin, hope you don't mind Cristophe )


Code:

Break On
$System = CreateObject("Kixtart.System")

;KD START

;************* Form **************
$Form = $System.Form()
$Form.BackColor = 212,208,200
$Form.FontSize = 8,25
$Form.FormBorderStyle = 3
$Form.Height = 566
$Form.Left = 119
$Form.MaximizeBox = "False"
$Form.Text = "Automagisk RDP fil generator"
$Form.Top = 78
$Form.Width = 400
;**************************************

;************* Label1 **************
$Label1 = $Form.Controls.Label()
$Label1.BackColor = 212,208,200
$Label1.FontSize = 8,25
$Label1.Height = 18
$Label1.Left = 15
$Label1.Text = "Brukernavn:"
$Label1.ToolTipText = "Brukernavn som sendes til serveren. Standard innlogget bruker + _adm"
$Label1.Top = 15
$Label1.Width = 89
;**************************************

;************* user **************
$user = $Form.Controls.TextBox()
$user.AcceptsTab = "True"
$user.FontSize = 8,25
$user.Height = 20
$user.Left = 111
$user.MaxLength = 128
$user.Text = @UserID + "_adm"
$user.Top = 15
$user.Width = 174
;**************************************

;************* progress **************
$progress = $Form.Controls.ProgressBar()
$progress.BackColor = 212,208,200
$progress.Height = 23
$progress.Left = 9
$progress.Step = 1
$progress.Top = 219
$progress.Value = 0
$progress.Width = 288
;**************************************

;************* browseButton **************
$browseButton = $Form.Controls.Button()
$browseButton.FontSize = 8,25
$browseButton.Height = 25
$browseButton.Left = 300
$browseButton.Text = "..."
$browseButton.Top = 79
$browseButton.Width = 33
$browseButton.OnClick = "selectDirectory()"
;**************************************

;************* generer **************
$generer = $Form.Controls.Button()
$generer.FontSize = 8,25
$generer.Height = 25
$generer.Left = 300
$generer.Text = "Generer Filer"
$generer.Top = 219
$generer.Width = 83
$generer.OnClick = "save()"
;**************************************

;************* log **************
$log = $Form.Controls.ListBox()
$log.FontSize = 8,25
$log.Height = 277
$log.Left = 12
$log.Top = 252
$log.Width = 370
;**************************************

;************* CheckBox1 **************
$CheckBox1 = $Form.Controls.CheckBox()
$CheckBox1.BackColor = 212,208,200
$CheckBox1.CheckAlign = 16
$CheckBox1.Checked = "True"
$CheckBox1.CheckState = 1
$CheckBox1.FontSize = 8,25
$CheckBox1.Height = 19
$CheckBox1.Left = 12
$CheckBox1.Text = "Torgnes"
$CheckBox1.Top = 192
$CheckBox1.Width = 71
;**************************************

;************* windowheight **************
$windowheight = $Form.Controls.TextBox()
$windowheight.FontSize = 8,25
$windowheight.Height = 20
$windowheight.Left = 111
$windowheight.Text = "750"
$windowheight.Top = 38
$windowheight.Width = 174
;**************************************

;************* Label2 **************
$Label2 = $Form.Controls.Label()
$Label2.BackColor = 212,208,200
$Label2.FontSize = 8,25
$Label2.Height = 19
$Label2.Left = 15
$Label2.Text = "Vinduhøyde:"
$Label2.ToolTipText = "Høyden på vinduet fra serveren"
$Label2.Top = 38
$Label2.Width = 90
;**************************************

;************* Label3 **************
$Label3 = $Form.Controls.Label()
$Label3.BackColor = 212,208,200
$Label3.FontSize = 8,25
$Label3.Height = 16
$Label3.Left = 15
$Label3.Text = "Vindubredde:"
$Label3.ToolTipText = "Bredden på vinduet fra serveren"
$Label3.Top = 60
$Label3.Width = 89
;**************************************

;************* windowwidth **************
$windowwidth = $Form.Controls.TextBox()
$windowwidth.FontSize = 8,25
$windowwidth.Height = 20
$windowwidth.Left = 111
$windowwidth.Text = "1000"
$windowwidth.Top = 60
$windowwidth.Width = 174
;**************************************

;************* Label4 **************
$Label4 = $Form.Controls.Label()
$Label4.BackColor = 212,208,200
$Label4.FontSize = 8,25
$Label4.Height = 18
$Label4.Left = 15
$Label4.Text = "Lagringssti"
$Label4.ToolTipText = "Sti hvor filene skal genereres"
$Label4.Top = 82
$Label4.Width = 92
;**************************************

;************* path **************
$path = $Form.Controls.TextBox()
$path.FontSize = 8,25
$path.Height = 20
$path.Left = 111
$path.Text = "c:\rdp\"
$path.Top = 82
$path.Width = 174
;**************************************

Function save()
$path = $path.text
$width = $windowwidth.Text
$height = $windowheight.Text
$name = $user.Text
logLine("Starter generering av filer. ")
logLine("Bruker katalogen $path, vindubredde: $width, høyde $height og brukernavn: $name")
logLine("og brukernavn: $name")
EndFunction

;adapted CMReadfile() by Cristophe Melin
Function readfile($file)
Dim $handle

$handle=freefilehandle
$=open($handle,$file)
if @error exit @error endif

redim $readfile[1024]
dim $nb

$nb=-1
do
$nb = $nb + 1
if $nb>UBound($readfile)
redim preserve $readfile[UBound($readfile)*2]
endif
$readfile[$nb]=readline($handle)
until @error
$=close($handle)
if $nb=1
exit 1024
else
redim preserve $readfile[$nb-1]
endif
EndFunction


Function logLine($line)
$log.AddItem ("$line")
EndFunction

Function selectDirectory()
$dir = $System.FolderBrowserDialog()
$dir.RootFolder = $path.text
If ($dir.ShowDialog() = 0)
logLine("Fikk ikke valgt katalog. Feilkode: @ERROR")
Else
logLine("Valgte katalogen:"+ $dir.SelectedPath)
EndIf
$selDir=$dir.SelectedPath
$path.text = $selDir
EndFunction

;KD END

$serverlist = readfile("serverliste.csv")
$dimen = Ubound($serverlist)
logLine("Filen har: " + ($dimen + 1) + " linjer")
dim $blah[$dimen,2]
$currrow = 0

For Each $row In $serverlist
logLine("$row")
$temp = split($row,";")
$blah[$currrow,0] = $temp[0]
$blah[$currrow,1] = $temp[1]
$blah[$currrow,2] = $temp[2]
$currrow = $currrow + 1
Next


$Form.Show
While $Form.Visible
$=Execute($Form.DoEvents())
Loop
Exit 1

_________________________



Top
#161074 - 2006-04-25 12:26 PM Re: multidimentional arrays.
ChristopheM Offline
Hey THIS is FUN
*****

Registered: 2002-05-13
Posts: 309
Loc: STRASBOURG, France
No problem, Jochen (i posted an answer in udf forum ).

Gilrim, in the main loop, you should add a test :
Code:
if $row
$temp = split($row,";")
...
endif

_________________________
Christophe

Top
#161075 - 2006-04-25 12:45 PM Re: multidimentional arrays.
Gilrim Offline
Fresh Scripter

Registered: 2005-07-19
Posts: 20
Thanks guys!
From your hints and suggestions, I rewrote the readFile to the following readCSV (it now returns a ready to use array of servers, their ip and servergroup:) ) :

[CODE]
;adapted CMReadfile() by Cristophe Melin
Function readCSV($file)
Dim $handle
$handle=freefilehandle
$=open($handle,$file)
if @error exit @error endif
redim $readfile[1024]
dim $nb
$nb=-1
do
$nb = $nb + 1
if $nb>UBound($readfile)
redim preserve $readfile[UBound($readfile)*2]
endif
$readfile[$nb]=readline($handle)
until @error
$=close($handle)
if $nb=1
exit 1024
else
redim preserve $readfile[$nb-1]
endif
reDim $readCSV[Ubound($readfile),2]
$i = 0
For Each $row In $readfile
;logLine("Linje $i: $row")
$temp = split($row,";")
$readCSV[$i,0] = $temp[0]
$readCSV[$i,1] = $temp[1]
$readCSV[$i,2] = $temp[2]
$i = $i + 1
Next
EndFunction
[/CODE]

I'm not so sure of what you meant with that check tho Christophe. Your suggesting a check as to wherther the row is "splitable"?

Top
#161076 - 2006-04-25 01:48 PM Re: multidimentional arrays.
ChristopheM Offline
Hey THIS is FUN
*****

Registered: 2002-05-13
Posts: 309
Loc: STRASBOURG, France
when you split $row, you suppose "it's OK" and you try to read 3 elements in the array.

if $row is empty, split($row,";") returns an array with only one element ($temp[0]) and $temp[1] fails with "array reference out of bounds". This is normal.

With the test, you bypass incorrect lines.

An other solution is to add a test after splitting, to verify that the array has enough elements :

Code:
For Each $row In $readfile
$temp = split($row,";")
if UBound($temp) < 2
;-- bad line --
else
$readCSV[$i,0] = $temp[0]
$readCSV[$i,1] = $temp[1]
$readCSV[$i,2] = $temp[2]
endif
$i = $i + 1
Next

_________________________
Christophe

Top
Page 1 of 1 1


Moderator:  Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart 
Hop to:
Shout Box

Who's Online
1 registered (Allen) and 466 anonymous users online.
Newest Members
gespanntleuchten, DaveatAdvanced, Paulo_Alves, UsTaaa, xxJJxx
17864 Registered Users

Generated in 0.066 seconds in which 0.022 seconds were spent on a total of 12 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org