LondonNDIB Posted January 14, 2006 Share Posted January 14, 2006 I need to read in some values from an INI file that looks something like this: [JOBS] JOB1 = whatever JOB2 = blah blah JOB3 = yadda [JOB1] INC1 = a INC2 = b INC3 = c [JOB2] INC1 = d INC2 = e INC3 = f INC4 = g [JOB 3] INC1 = h INC2 = i But each "JOB" section has an unknown number of entries, plus there are an unknown number of JOBS ("unknown" isn't the right word... "variable") My first thought is to use IniReadSection nested like this: $jobs = IniReadSection ( $INI, "JOBS" ) Global $NumJobs = $jobs[0][0] For $i = 1 To $NumJobs $includes = IniReadSection ( $INI, "JOB" & $i ) If Not @error Then $NumIncludes = $includes[0][0] Global $jobinclude[$NumJobs+1][$NumIncludes+1] For $j = 1 To $NumIncludes $jobinclude[$i][$j] = $includes[$j][1] Next EndIf Next MsgBox ( 0, "TEST", $jobinclude[2][2] ); answer should be "e" But I get problems with the array since the number of secondary elements varies. I thought from there I'd be able to grab any combination , say $jobinclude[2][2] would give me "e"... and $jobinclude[3][1] would be "h". It doesn't work though, at least not as I've scripted it... no error... just gives me a blank value unless I check within the nested loop... then it will give me the proper value at the corresponding iteration of the loop - but it does not seem to remember the values outside of the loop. I can't figure out why this is the case. So if I can't use a two-dimensional array, then I figured I could just use a bunch of variables, but I wouldn't know how many to declare or what syntax, if any, is appropriate. Eg. For $i = 1 to $x Dim $variable$i Next is the idea but won't work. Thoughts? Thanks. LD Link to comment Share on other sites More sharing options...
Valuater Posted January 14, 2006 Share Posted January 14, 2006 $INI = "C:\Temp\Myfile.ini" Dim $i, $j $jobs = IniReadSectionNames($INI) For $i = 1 To $jobs[0] $includes = IniReadSection ( $INI, $jobs[$i]) If Not @error Then For $j = 1 To $includes[0][0] MsgBox ( 64, $jobs[$i],"Key: " & $includes[$j][0] & @CRLF & " Value: " & $includes[$j][1]) Next EndIf Next MsgBox ( 0, "TEST", $includes[2][1] ); answer should be "i" - because $includes is in the loop of "jobs" and re-read on every "i" to $jobs 8) Link to comment Share on other sites More sharing options...
LondonNDIB Posted January 14, 2006 Author Share Posted January 14, 2006 You mean answer should be $i, no "i" - right? From my sample ini it would be "d". Thanks - I didn't think about using the IniReadSectionNames function. However, that reads in ALL section names so I'd have to introduce some control statements to weed out the non "JobX" sections. I also realized what I was doing wrong in my initial script. The line that read: Global $jobinclude[$NumJobs+1][$NumIncludes+1] of course was in side the For $i loop so it was constantly clearing the array... setting a value within it, and clearing it again, and so on. So I have to bring that outside of the for $i loop. Unfortunately, I would have no way of knowing what $NumIncludes was then (because it is generated within the loop) so instead I have to declare the variable like so: Global $jobincludes[$NumJobs+1][99] and do so before the For $i loop. I'd rather not do that, because I don't want to impose some artificial limit on the number of includes a job can have... Valuator's idea is pretty clean. So I'll either modify that (thank you!) or live with artificial limits. Thanks a lot for giving me something to go on. LD Link to comment Share on other sites More sharing options...
LondonNDIB Posted January 16, 2006 Author Share Posted January 16, 2006 Still having problems. After working with your code Valuator, I'm not sure it really solves it... I'm still stuck not knowing how large to declare the two-dimensional array. So can I declare the first dimension, and then the second dimension later? Probably not. Basically, I can tell how big $i will be - but I have no idea how big $j will be for each $i until after the fact... and unfortunately, the array[$i][$j] needs to be declared first with the number of elements in each. LD Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted January 16, 2006 Moderators Share Posted January 16, 2006 Hi London... do you have a test.ini to work with that you can upload? 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. Link to comment Share on other sites More sharing options...
LondonNDIB Posted January 16, 2006 Author Share Posted January 16, 2006 (edited) Posted at the top... pretty simple format really... the first section lists the jobs and the later sections named JOBx list the includes for each job. But anyway, I figured out the key to the problem... the "redim" function. original code:$jobs = IniReadSection ( $INI, "JOBS" ) Global $NumJobs = $jobs[0][0] For $i = 1 To $NumJobs $includes = IniReadSection ( $INI, "JOB" & $i ) If Not @error Then $NumIncludes = $includes[0][0] Global $jobinclude[$NumJobs+1][$NumIncludes+1] For $j = 1 To $NumIncludes $jobinclude[$i][$j] = $includes[$j][1] Next EndIf Next MsgBox ( 0, "TEST", $jobinclude[2][2] ); answer should be "e" working code: $jobs = IniReadSection ( $INI, "JOBS" ) Global $NumJobs = $jobs[0][0] Global $jobinclude[$NumJobs+1][1];Declare variable here with an arbitrary 2nd dimension. For $i = 1 To $NumJobs $includes = IniReadSection ( $INI, "JOB" & $i ) If Not @error Then $NumIncludes[$i] = $includes[0][0] If ($NumIncludes[$i] > $NumIncludes[$i-1]) Or $i = 1 Then Redim $jobinclude[$NumJobs+1][$NumIncludes[$i]+1] EndIf For $j = 1 To $NumIncludes[$i] $jobinclude[$i][$j] = $includes[$j][1] Next EndIf Next MsgBox ( 0, "TEST", $jobinclude[2][2] ); answer should be "e" This now works because before I was re-declaring the $jobinclude array and it was wiping out its contents on each iteration... with "Redim" (which keeps the "Global" scope, btw) it changes the size of the dimension without wiping out the contents! I add that last If statement because there's no reason to Redim unless the array is getting larger in the current iteration - if it is the same size (ie same number of includes as the previous job) then it doesn't have to be re-declared at all. I haven't fully tested this yet, but it seems to work. LD *edit* I also realized I was thinking of $NumIncludes as a scalar originally, when it is an array itself.... ie. $NumIncludes[1] = 3, $NumIncludes[2] = 4, $NumIncludes[3] = 2 (from the sample INI at the top) Edited January 16, 2006 by LondonNDIB Link to comment Share on other sites More sharing options...
Valuater Posted January 16, 2006 Share Posted January 16, 2006 (edited) this worked also expandcollapse popup#include <GuiConstants.au3> $INI = "C:\Temp\Myfile.ini" Dim $max = 7; number of maximum labels needed Dim $i, $j Dim $label[8] Dim $input[8] Dim $top = 50 $jobs = IniReadSectionNames($INI) $win = GUICreate("My GUI") $combo1 = GUICtrlCreateCombo("", 50, 10, 200, 20) for $p = 1 to $jobs[0] If $jobs[$p] = "JOBS" Then ContinueLoop GUICtrlSetData( $combo1, $jobs[$p] & "|", 1) Next $view = GUICtrlCreateButton("View List", 270, 10, 80, 20) for $t = 1 to $max; the max number of labels needed $label[$t] = GUICtrlCreateLabel("XXX", 20, $top, 100, 20) $input[$t] = GUICtrlCreateInput("", 150, $top, 150, 20) $top = $top + 50 Next GUISetState() While 1 $msg = GUIGetMsg() Select ; Main window controls Case $msg = $GUI_EVENT_CLOSE ExitLoop Case $msg = $View View() EndSelect WEnd Func View() $jobs = IniReadSectionNames($INI) For $i = 1 To $jobs[0] If $jobs[$i] = GUICtrlRead($combo1) Then $includes = IniReadSection ( $INI, $jobs[$i]) For $j = 1 To $includes[0][0] GUICtrlSetData($label[$j], $includes[$j][0]) GUICtrlSetData($input[$j], $includes[$j][1]) Next If $j < $max Then For $r = $j to $max GUICtrlSetData($label[$r], "") GUICtrlSetData($input[$r], "") Next EndIf Return EndIf Next EndFunc 1 this removes "JOBS" from the list 2 I am trying to show you that you dont NEED to set the $array length to use the info Hope that helps 8) Edited January 16, 2006 by Valuater Link to comment Share on other sites More sharing options...
LondonNDIB Posted January 16, 2006 Author Share Posted January 16, 2006 (edited) 1) I appreciate that! But in my particular case, I need the JOBS section any way for a bunch more info outside of this "includes" business. So for my purposes, its there anyway and was handy to use... but I agree it is not necessary to solve my problem as described. 2) Not really. Your method still has the distinct problem of not being valid outside of the loop. The include[j] values aren't persistent. In other words, add MsgBox ( 0, "", $includes[1][1] ) immediately before your "return" in the loop and you will see that it returns whatever the first value for that particular job is instead of the proper constant value of "a" (at least in the example INI posted at the top of this thread). Try to get $includes[2][2] and you get a fault in the code because the second dimension can never be higher than "1" in your code... thereby effectively making it a single-dimensional array. To make it truely multi-dimensional (instead of a single dimensional that constantly over-writes itself - the same problem I was struggling with to begin with) you need to either know/declare its size ahead of time, or use the Redim function as I "discovered" Thank you so very much for your efforts! LD Edited January 16, 2006 by LondonNDIB Link to comment Share on other sites More sharing options...
Valuater Posted January 16, 2006 Share Posted January 16, 2006 what is it you want to do... find a way to make this into a To make it truely multi-dimensional (instead of a single dimensional that constantly over-writes itself -or use the info, read it, update it, and rewrite it to the file????8) Link to comment Share on other sites More sharing options...
LondonNDIB Posted January 16, 2006 Author Share Posted January 16, 2006 Both, I suppose. As a multi-dimensional array, the data can be called up and used/modified whenever and wherever I want later on in the script. I feel its the better method for solving the problem of "variable variables"... your solution definately solves the specific example I posed. What I probably didn't clarify enough was that the example ini was really stripped down for this post - it doesn't resemble my actual situation at all - and it was the overall concept I needed help with - that of multidimensional arrays. Recall that from my first post, I wrote: But I get problems with the array since the number of secondary elements varies. I thought from there I'd be able to grab any combination , say $jobinclude[2][2] would give me "e"... and $jobinclude[3][1] would be "h". It doesn't work though, at least not as I've scripted it... no error... just gives me a blank value unless I check within the nested loop... then it will give me the proper value at the corresponding iteration of the loop - but it does not seem to remember the values outside of the loop. I can't figure out why this is the case. So I thought it was clear I would require a method for grabbing a specific $jobinclude[x][y] value. Redim, as it turns out, was the key to making that possible. LD Link to comment Share on other sites More sharing options...
Valuater Posted January 16, 2006 Share Posted January 16, 2006 (edited) Good luck 8) edit ( not sarcasticly ) Edited January 16, 2006 by Valuater Link to comment Share on other sites More sharing options...
LondonNDIB Posted January 16, 2006 Author Share Posted January 16, 2006 Thank you. And seriously.... thank you for your help! I didn't mean to belittle your efforts at all and I hope I didn't - I just think that my self-discovered solution worked better in my particular situation... but it was your original suggestion that led me in that direction anyway! I appreciate it. LD Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now