Error message with Deleting srow' not defined -- how to fix this?

3209
7
05-19-2013 11:16 AM
DanielBrenner
Occasional Contributor
Not that I haven't worked with my professor on this, but really, this is insane. 

I simply want to use a script to show the Functional Classifications of roads in a county.  I have set up a definition query, and have set up a subroutine where rows are added to an array--srows.  The functional classification values are added to each row in another subroutine.   At the end of the script it is standard protocol to delete the rows to clean out the array.

My professor suggested using a smaller file to do a trial run on the script.  I was having problems getting it to run earlier, so I sent him a version of the script and a smalller file.   He got it to run with the smaller file, I saw what he did, but when I substituted my County-wide roads layer, I keep getting the same error message, of how srow and/or srows are not declared.

I even checked to see if srow was something he made up, but its not.   I have tried indenting the line 'del srow, srows' to make it line up with the script, but no dice.  



Do I have to rewrite the script altogether or what?   Maybe I'm not phrasing this entirely with the right language but its pretty basic stuff I would think. I am on my hands and knees.

I have attached the script, the error message, and a version of the layers I am trying to work with.

Thank you kindly,

Dan B
0 Kudos
7 Replies
by Anonymous User
Not applicable
Original User: Wayne_Whitley

I took a brief look at the 1st script you attached... your srows and srow pertain to cursor and row objects, respectively, and your error is simply where the obj doesn't exist anymore - looks like you're creating the cursor inside your if branch when this tests true:

if TOCLayer.longName == 'SON_COU_STS_UPD4'


...so, of course, when the longName of the layer is not 'SON_COU_STS_UPD4', then the cursor isn't created (or 're-created' as the case may be).  Not really a serious error and what you could do is make sure the object exists before you attempt to delete it, something like:

if srows:  del srows

Of course, not sure if you are otherwise having the expected output, anything else unexpected happening?

Enjoy,
Wayne
0 Kudos
DanielBrenner
Occasional Contributor
Wayne,

Thank you kindly for your response, and I actually did have a small degree of luck with the "if..." part that you suggested, but the issue is still there.

My professor actually did suggest in one of his emails that I should put the "del srow, srows" statement before the tElements part of the script, and it didn't occur to me to do that until recently.  It actually does make sense because everything in the tElements is static and not layer-based.

But the main thing is is that I DO NOT KNOW what I have to do to declare srow. 

Would you need the main roads layer that I'm trying to do the query on?

Please. 

I have tried everything I can think of, or so it seems. 

Thanks again,

Dan B
0 Kudos
by Anonymous User
Not applicable
Original User: Wayne_Whitley

sRow is your row object, correct?...and I think your only reference to it (other than the del statement) is when you enter your loop on the cursor, which is inside your 'if' block as well --- with 1 minor exception, sRow is 'implicitly' declared with the statement 'for sRow in sRows'.  You don't need to declare it in the sense you speak of, neither with sRows.

Actually, your code won't fail if you don't include the del statement, just that is ordinarily good practice to help 'clean up' lingering object references and free up memory, etc.  If you want, I suppose you could also enter the statement, if sRow:  del sRow, at the end of your script.  If you're having any other error messages, you have a different problem.  Provide more details if that is the case.

Enjoy,
Wayne

EDIT:  If you're just stuck and want to test the rest of your code, you may comment out the del line for now and get on with your work:

# del srow, srows

Have you been having any problems with your text elements, if you've executed that part yet? -- you didn't actually name an element 'FUNCTIONAL CLASSIFICATION = ', as this 'if' statement in your code, did you?:

if tElement.name == 'FUNCTIONAL CLASSIFICATION = ':
0 Kudos
DanielBrenner
Occasional Contributor
Wayne:

See attached. 

I should comment (!) that I commented out the 'del srow, srows' line and I at last did not have the error message that had been driving me nuts, but at the same time I almost wonder if I still need it.

I did discuss with my professor what I needed to do to make the script cycle through to print out (create pdfs) of the various FUNC values for the county roads layer.   I thought I had things taken care of with the Definition Query for the layer and changing the text Element value to the correct field, but all I got was one map and nothing else.   Even when I changed the Definition Query to something other than the first one ("FUNC" = 3) to "FUNC" = 0, I still couldn't get the map itself to change.

Just so you know:   FUNC is the field name, FUNCTIONAL CLASSIFICATION is the 'text element' that the script references.  I took out the '=', but that didn't make any difference.  

The other weird thing is that I couldn't get my name to print next to "Produced by" and the current date to print out next to "Printed on".   This hurts because I know I put in the correct date format and used the correct introductory statement earlier in the script.

The bottom line is is that the map and the script aren't communicating with each other.   Part of me wonders if I still have to type in individual queries in the Definition Query (for each Functional Class)?  

Thanks again,

Dan B
0 Kudos
by Anonymous User
Not applicable
Original User: Wayne_Whitley

Oh I see part of your confusion...

- For text elements, I see the one you pictured is named FUNC and I think you're trying to call it by the text entered?  List the text elements, use the wildcard parameter if you want in order to limit your return using the name.  A list of text element objects are returned.  You can loop through them to find the FUNC (which is the name property; you were using the text property).  Or if you've sufficiently limited the listing to a single element you can retrieve it by specifying the 1st member with index 0, i.e., [0].
Of course, once you've targeted a text element, you'll want to change the text property.

- For changing your definition query, I didn't look at your script this morning but you could at least for testing purposes create a static list of functional values and loop on that list to create your maps.  So that would look something like:
TheList = ['func1', 'func2, 'func3']
for func in TheList:
     (Form the query def and set it on the layer, then process your exports)


Hope that gets you started!  Troubleshooting is a great way to learn.


Wayne
0 Kudos
DanielBrenner
Occasional Contributor
Wayne:

I know you meant well with the above suggestion, but really, I needed something that cut to the chase in terms of what did I have to do with the Definition Query and Text Elements.     As in, what exactly did I have to do? 

I thought maybe you could have run the script with the layers I was giving you?

Not to sound overly dependent but you do not know how fried I was on this stuff.

At the same time I do thank you for reaching out and for the help you did give me.  Honest.  I will do my best to take it to heart in the future.

Dan
0 Kudos
by Anonymous User
Not applicable
Original User: Wayne_Whitley

Try out the attached py... hope you now understand what was going awry --- if not I'll try to elaborate a little on the more critical points. I tried not to edit your script much and part of what I did someone else could probably do better but mainly I wanted to leave it mostly intact as you left it in order to 'see' the changes better. Here goes:

- You need 3 text elements already in your map layout. Although you can 'clone' elements at 10.1, I don't think you can create new ones --- at any rate, the 3 elements you should create in your map document should be named:

PRODUCEDBY
PRODUCEDON
PRODUCEDFUNC

You can save names with the elements (create the elements, save and close the map)...a wildcard, "PRODUCED*", is used in the script to 'fetch' the 3 text element objects. 2 of them are preprocessed before entering the export loop; the 1 that changes is of course PRODUCEDFUNC and done in the 'for' loop because (as the name denotes) it is changing as FUNC is in the list generated from your searchcursor on the streets fc.


- Your 1st 'for' loop searched for the street layer; you can exit that loop when the layer is found....you can do that with 'break'. You may want to take this out if you want to print the rest of the layers, but this has nothing to do with the rest of script function, so I chose to 'break out' once the StreetLayer variable was set.

- TOCLayers = ListLayers(mxd, '', dataframe) --- the use of your 'dataframe' variable wasn't mandatory, but since you established it to access and print the extent, it makes sense to 'tighten' the code and use it.

- Your search cursor has a single purpose: to read in unique func vals -- so you can del the cursor and row obj when finished reading (or you can choose to do that at the end of the script along with deleting other objects, it is up to you....I inserted the statement to punctuate the fact it is needed no longer.)


Those are the high notes I guess...simple script, just be careful with your 'for' loops and indention -- your 2 biggest errors I'd say were indenting too much of your code within the 1st 'for' loop and not getting a proper handle on your text elements. Oh yeah, and I didn't see the purpose of 'repositioning' the 1 text element, but if you need it go ahead...

Any further questions let me know -- hope the script works...I tested it, but it can always fail if I forgot to change back to run on your system, etc.

Enjoy,
Wayne


*OOPS:
I see a potential source of error -- see this line which will fail if you intend to fetch the layer from a group layer:

if TOCLayer.longName == 'SONOMA COUNTY STREETS':

This following line will work if you don't need to specify the group layer--

if 'SONOMA COUNTY STREETS' in TOCLayer.longName:


Otherwise, if the 'name' will suffice, simply use--

if TOCLayer.name == 'SONOMA COUNTY STREETS':


Hope that is clear...
0 Kudos