Gilrim
|
(Fresh Scripter)
|
2006-04-24 11:56 AM
|
|
|
|
|
multidimentional arrays.
|
|
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?
|
Jochen
|
(KiX Supporter)
|
2006-04-24 12:09 PM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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
|
Gilrim
|
(Fresh Scripter)
|
2006-04-24 12:25 PM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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?
|
Jochen
|
(KiX Supporter)
|
2006-04-24 12:32 PM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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)
|
Gilrim
|
(Fresh Scripter)
|
2006-04-24 01:08 PM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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
|
Jochen
|
(KiX Supporter)
|
2006-04-24 02:43 PM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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
|
Gilrim
|
(Fresh Scripter)
|
2006-04-24 10:21 PM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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...
|
Jochen
|
(KiX Supporter)
|
2006-04-25 09:55 AM
|
|
|
|
|
Re: multidimentional arrays.
|
|
Allright,
I will create a csv file on your template and retest. My last reply was based totally on assumptions, stand by please...
|
Jochen
|
(KiX Supporter)
|
2006-04-25 10:18 AM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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] ]
|
|
Re: multidimentional arrays.
|
|
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.
|
Jochen
|
(KiX Supporter)
|
2006-04-25 11:04 AM
|
|
|
|
|
Re: multidimentional arrays.
|
|
Yeah,
I know that for sure ... but the point here is that he uses a udf from our library which returns unexpected results.
|
Jochen
|
(KiX Supporter)
|
2006-04-25 11:38 AM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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")
|
Jochen
|
(KiX Supporter)
|
2006-04-25 11:42 AM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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
|
|
Re: multidimentional arrays.
|
|
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
|
Gilrim
|
(Fresh Scripter)
|
2006-04-25 12:45 PM
|
|
|
|
|
Re: multidimentional arrays.
|
|
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"?
|
|
Re: multidimentional arrays.
|
|
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
|