|
POST
|
You would assign the hot key by setting the Text property of your button, so you would be in control of that. An end user can not create their own hot key, that I am aware of. I wasn't refering to whether or not a hot key had been set up. I was asking if I can detect that the hot key event was activated by the user as distinguished from the button press event? I suppose that I could just run through the full control collection to see which object had focus and force the Leave event to fire on any object other than the button that was active, rather than having to validate all of the objects that had previously been validated through their Leave events.
... View more
08-29-2012
09:19 PM
|
0
|
0
|
3707
|
|
POST
|
You would be able to submit a form button without the leave event triggering if your button has a hot key assigned to it, such as the Text property of your button reads: &Submit That would submit your form with no values, assuming you have a hot key assigned to your button, which you probably don't. But also means that if you wanted one, you would be forced to validate your input for all text boxes in the event the form is submitted without any values. Given that validating the input data is the primary function of my form I would not assign a hot key to let the user submit the form without firing the Leave event. If I did, you are correct that I would have to find another location (the submit button) to do the validation. Is there a way to detect that a hot key was used? If so the additional validation would only need to occur if the hot key was triggered. Probably the best compromise would be to create separate Subs of Functions that placed the validation contents currently within the Leave event outside of that event. That way the method could be called from both the Leave event and the Submit button. Then the validation would always occur with whichever event fired earliest, which is my preference.
... View more
08-29-2012
04:37 PM
|
0
|
0
|
2145
|
|
POST
|
Your code is only checking for "leave" events, which you hope the user enters a value and leaves that text box. What if the user enters junk into a text box and doesn't do anything to trigger the leave event before they submit? I have not encountered any case where I have been able to execute a button that submits the form's data for execution without first triggering the Leave event of the Textbox (whether or not I changed anything in the Textbox), so unless you can show me a way to submit without triggering the Leave event I don't think your second comment applies. Therefore I have every reason to believe that the KeyPress and Leave events are all that is required to ensure that a valid entry will be in the Textbox when the user has finished with that field and wants to submit their results for execution. So at this point I plan on amending my original code to add a check in the Leave event for the allowable maximum value and to provide a notification prior to execution of the form to the user to let him know when his entry was rejected, what the invalid value was that he entered, and that the value was replaced with a default minimum or maximum value so that he is aware of his error and can optionally correct it before proceeding with execution. I also plan to revise the code to use globalization methods that will use the decimal character that conforms to a users local cultural settings for the benefit of programmers working in other cultures that would want to use my code (although that code may need to have its behavior verified by a programmer in another culture before putting it in use). Finally, I plan on determining the local setting for the thousands separator and parsing it out of an entry that was pasted into the textbox so that it will be treated as a valid number and accepted in the field (subject to the other checks).
... View more
08-29-2012
10:57 AM
|
0
|
0
|
2145
|
|
POST
|
Here's a subroutine I found that I usually put in my text box KeyPress functions when I want to restrict what's being typed in. This doesn't account for hex values, but I doubt that the users would even know what they are... When using this with numbers, I have additional checks to make sure there's not more than one decimal place or negative sign, in addition. Here's an example for a group of textboxes that can be decimal degree or degree minutes seconds or just numbers... It took me a while to understand how the mask worked, but the second example of the decimal degrees or degrees minutes seconds helped me figure it out. I assume you have other checks that would deal with minutes and seconds being between 0 and 59 that you did not publish, or did I miss something? You also designed this with multiple textboxes for the Degrees Minutes Seconds input. Do you have any idea how it would be written to work as a single Textbox. Say that the user set a checkbox to specify the format mask they were entering so that one Textbox could accept a variety of formats depending on user preference at the time of data entry and that internal code would convert it to match the format specifications of a database field. (I realize the check box could expose different sets of Textbox fields to handle and preparse each format, which would be a safer design, but I am trying to explore the limits of what a Textbox can do in this discussion thread).
... View more
08-29-2012
09:12 AM
|
0
|
0
|
2145
|
|
POST
|
I don't want to be known for beating a dead horse, but I don't see where you are testing the validity of an integer value. What if user enters this: 9,223,372,036,854,775,808 (which is larger than the maximum integer size by one) into your integer checking leave event? Using the keyboard this number could only be entered as: 9223372036854775808 according to my intentional disallowance of the thousands separator. Assuming the Leave event triggered this value would be replaced by 1 as an invalid value, since it would not parse to a valid Long value, but that is not a problem, because it is far beyond the valid maximum number my form can use. The maximum number for my form's Long value is well below the one you have suggested, being at most 7 digits long for any real world AADT. The Leave event already has tests for numbers that are too small (anything below 1 for the Long field example), and adding additional tests for the total number of characters entered for a Long value would be an easy test to add to restrict the number to a valid maximum range. Exceeding the maximum number would be corrected by replacing the input with the maximum value allowed instead of the minimum value. I would definitely have other tests specific to my application that would also ensure that the distances entered actually kept the event on my real roads, none of which is anywhere near this long in any standard units of measure I use. Testing for character length of the Double value on each side of the decimal place would also be an easy test to add for the Double Textbox, and thank you for alerting me to this ommision. Regardless of where I put it, the code I have used in the Leave event is the minimum validation code I need to have executed, whether it occurs there or in an execute button or whereever. So I just need to find the best place to put it to make it fire. My desire is to have it tested as soon as possible upon a user finishing with his entry, which in most cases should be long before the user gets to the point of trying to execute the form if they are filling it in normally (12 completed fields are required for execution in my case). At this stage I would be inclined to keep the Leave event in my code (with the addition of a maximum value validation) and just add a double check routine to be executed just prior to form execution to ensure that the user did not find a way around triggering the Leave event.
... View more
08-29-2012
08:38 AM
|
0
|
0
|
2145
|
|
POST
|
I'm not doing a good job of being clear. Let me try again. While trying to limit what a user can enter into an input control is fine, you should also validate that input before you use it. Example: Esri's map scale tool. You can type letters in there, but when you hit enter, you'll get a message indicating that what you typed is junk. [ATTACH=CONFIG]17329[/ATTACH] I concur with this practice of the warning (not the typing of invalid characters from the keyboard), provided that the invalid data would be immediately replaced by valid data and that the warning would only serve to notify the user that: "You typed - 12.345.678 - which not a valid Base 10 Double Number. Your invalid entry has been replaced by the default value of 1." This warning (which is better than a generalized failure notice) would allow the user to recover from their error by recopying their failed entry and pasting it back into the form at which point they could make appropriate corrections according the form's requirements (i.e. 12345.678). I feel certain that the keyboard for my Textbox is bulletproof (and can be made that way for alternative requirements through the KeyPress method), but I definitely would like to have a more foolproof set of behaviors for the responding to the paste option. While in my particular case I do not want thousands separators in the Textbox on my form, I would prefer to add a subroutine that would accept pasted numbers with thousands separators as valid numbers and that would reformat them as numbers without thousands separators. The key to solving this appears to be to find the events that always fire when the paste occurs and when the user is done entering their text by whatever method (perhaps Losing Focus). I could really use a flowchart outlining the order of more events than just KeyDown, KeyPress, and KeyUp to understand my options. I will continue looking into the options.
... View more
08-29-2012
07:55 AM
|
0
|
0
|
2145
|
|
POST
|
The problem with putting it into the TextChanged subroutine is that the user can put in invalid characters into the text box, whereas the KeyPress validation won't put those invalid characters there to begin with. Using the code from the MS example, you can still see something like this [ATTACH=CONFIG]17327[/ATTACH] It looks like the Masked Textbox requires more user interaction with decimal numbers, requiring them to position the cursor at the correct location to put in a number that has fewer numbers than the maximum number. I concur on both statements. The Keypress operation does the best job of ensuring keyboard actions cannot result in unwanted characters and can even restrict certain characters to a certain number of occurrances (as my code has shown) or even to specific positions (were I to use a negative sign I could write a KeyPress routine that ensured the negative sign only occurred once at the beginning of the number and that any attemp to type numbers to the left of it would result in the numbers being placed after the negative sign, without requiring the user to move their cursor to that position). Restricting cursor movements within the textbox to specific locations that match a mask are unacceptable to me. Text entry needs to be like normal typing, with all standard editing operations, such as select and overwrite abilities, allowed using intelligent character ordering through the keyboard keypress operation. Pasting is the sole path to entering garbage in the Textbox and I have no problem discouraging that practice and penalizing a user for careless use of that data entry method if they do not care to conform to the form's business rules. When Federal and State Transportation Agencies, State Engineering and Surveying Licensing Boards, and my Department's policy formally adopt standards to accomdate document submissions and field data recordings using hex values and escape codes I will revise my Textbox to accomodate such numbers. But until then, such entries will be treated as the junk that they are.
... View more
08-29-2012
07:27 AM
|
0
|
0
|
2145
|
|
POST
|
Imagine if you had to debug this code and had to switch between the form and the code to trace your way through those events. lol. The code I wrote does have such a problem in that the code is fully self contained to operate within a single method that has an obvious connection to the behavior of the Textbox. And even if it did cause a problem it is not that much code or difficult to interprete with the commenting I have added. Tracing your suggested code involving multiple boolean variables accessed across the entire form is much more likely to miss a code path, because I have to set and trap these flags all over the form, keeping track between methods that fire in orders that I have no control over or clear understanding of. It is easy to set the flag to a condition indicating one or more conditions fails to pass the test for execution, but nearly impossible to set the flag to indicate that widely dispersed operations all combine to allow final form execution without a centeralize check method that queries every relavant part of the form. Attempting to write such a centralize check is much more likely to result in impossible code traces of branching if then else statements and in debug nightmares that isolating each part of the form to play its part in ensuring valid input. Were I to use your suggested set of boolean variables I would be sure that they affected the enabled status of the execute button, so that I could eliminate the user's ability to proceed on that path until the variables are set correctly for execution and visually see on the form what the boolean variable state was for any given set of user actions to assist me in debugging the ever expanding code paths. But I have gone down that road before and have always regretted it when I want to make additions or modifications to the forms behaviors. Every new option affecting the boolean variables seems to result in an exponential growth of code paths and unexpected combinations of conditions that I have to spend a lot of time tracing out. I still am not convinced that using default values to replace obvious garbage that can only be generated through rare user actions is a bad idea. Have you actually run my code to see for yourself how it works? I have been running the code you have referenced.
... View more
08-29-2012
07:02 AM
|
0
|
0
|
6147
|
|
POST
|
A very big thank you to you SIR!!!! Once again you are the main man. You solved yet another problem for me! Glad to help. Consider adding a point to the response so that others will recognize that it was helpful to you.
... View more
08-29-2012
06:28 AM
|
0
|
0
|
2689
|
|
POST
|
Looking at your code I see a lot of wasted lines related to your cursors that did not use the previous advice I gave. If you mean to read values from all rows you need different indents and logic. You do not need a cursor for each field. You only need a new cursor for each feature class. Since you are only dealing with one feature class you only need one cursor, but many (4) getValue calls when reading each row. Here is my attempt to clean it up a bit fc = "Parcels"
field = "LGA"
field1 = "District"
field2 = "Block_No"
field3 = "Plot_No"
cursor = arcpy.SearchCursor(fc)
for row in cursor:
# do not use 4 cursors on the same feature class, only 1 cursor is needed.
# read every cursor row and get all 4 field values in a single read of the row
val = row.getValue(field)
print (row.getValue(field))
val1 = row.getValue(field1)
print (row.getValue(field1))
val2 = row.getValue(field2)
print (row.getValue(field2))
val3 = row.getValue(field3)
print (row.getValue(field3))
# The lines below must also be in the loop to use the values read from each row.
outName = str(val) + "_LGA" + "(" + str(val1) + " _Area" + ")"
outName1 = "Plot_" + str(val3) + "(" "Block_" + str(val2) + ")"
outName2 = "Block_" + str(val2) + "_Plot_" + str(val3) + "_" + str(val1) + "_Area_of_" + str(val) + "_LGA" + ".pdf"
arcpy.CreateFolder_management("C:\\ARA_STATE\\", outName)
arcpy.CreateFolder_management("C:\\ARA_STATE\\"+ outName,outName1)
arcpy.mapping.ExportToPDF(mxd,r"C:\ARA_STATE\TDP_For_" + outName2) Since you are just learning Python, try to test smaller amounts of code to make sure you get results you expect. It is much harder to issolate problems when you do a lot of lines of code before testing. I assumed you meant to use outName2 for the pdf rather than outName1, since outName2 ends with the .pdf extension. I think however, that you also meant to have the pdfs go into the new folders you are creating. If so, for the last line you need something like: arcpy.mapping.ExportToPDF(mxd,r"C:\ARA_STATE\\" + outName + "\\" + outName1 + "\\" + "TDP_For_" + outName2) You may also need to include some logic to do "Exists" testing on your directories, since you cannot create a directory that is already created without causing an error.
... View more
08-28-2012
10:33 PM
|
0
|
0
|
2689
|
|
POST
|
arcpy.CreateFolder_management("C:\\ARA_STATE\\", outName)
arcpy.CreateFolder_management("C:\\ARA_STATE\\"+ outName,outName1)
arcpy.mapping.ExportToPDF(mxd,"C:\ARA_STATE\TDP_For_" + outName1) my final pdf output is not going into something like this arcpy.mapping.ExportToPDF(mxd,"C:\ARA_STATE\TDP_For_" + outName,outName1) What do you think? You switched from using double slashes to single in the PDF export line. Double slashes are required for all paths in all methods unless you are place an "r" directly in front of the string to let Python know the string is to be read "raw" or unparsed. So make your last line read either: arcpy.mapping.ExportToPDF(mxd,"C:\\ARA_STATE\\TDP_For_" + outName,outName1) or arcpy.mapping.ExportToPDF(mxd,r"C:\ARA_STATE\TDP_For_" + outName,outName1) Also, even if you use the "r" option, if the last character in the string is a "\" the Python help says it must always end with a double slash "\\". So r"C:\ARA_STATE\" will cause an error, but r"C:\ARA_STATE\\" will work (note the single slash in the middle of the string is fine in both, but the double slash is required at the end of the string.)
... View more
08-28-2012
10:14 PM
|
0
|
0
|
2689
|
|
POST
|
I wasn't thinking about locking a user into a text box before they can move on, rather, a label next to the text box indicating the value entered is invalid. What happens if your user enters more than one decimal point? Such as: ......... Yes, searches only help if you have the right keywords. I googled: msdn restrict textbox to numbers. First link. Run my code. Entering more than 1 decimal point in the Double Textbox is impossible with the keyboard. The only way to cause this problem is with pasting (which is not the data entry method users of my form will normally use). If the user insisted on pasting in such a value the code would replace it with the default value if a user insists on exiting the textbox before correcting that entry. A more likely problem would be that they meant to paste over a decimal and instead pasted before or after it and thereby entered two decimal points without realizing it. When they left the Textbox such an entry would be replaced by the default value. I see the point of using a label to notify them about such replacements, but I generally would not let faulty input go uncorrected hoping the user would go back and correct it before pressing the execute button. The alternative would be to disable the execute button until all entries were valid and use labels to highlight errors. I assume that is the approach you are recommending. I thought I had seen some kind of Validator class that could add error symbols and messages directly to controls (rather than having to generate my own labels all over the form), but I may be misremembering and mixing languages and interfaces. I will try searching for it (wish me luck). Speaking of funky searches, I had that problem with the Python website too. I was trying to find a Python based method for closing a Windows program. Nowhere was the word "close" associated with that action and I never got any hits in my search. Later another user pointed out that the Python term you need to use for closing a Window was "Kill". But if you search "python kill" you get a lot of articles about deaths in the Amazon and not much on the python language. Sigh.
... View more
08-28-2012
09:59 PM
|
0
|
0
|
6147
|
|
POST
|
What if the user pastes in a hex or unicode escape sequence for a number? Something like 0x0039 or 9 http://msdn.microsoft.com/en-us/library/aa664669(v=vs.71).aspx Also, rather than trap for correct input and settle for defaults, you can test the values of the text boxes for numeric and prompt the user for correct input. Your code is only checking for "leave" events, which you hope the user enters a value and leaves that text box. What if the user enters junk into a text box and doesn't do anything to trigger the leave event before they submit? Did you find this example? http://msdn.microsoft.com/en-us/library/ms229644(v=vs.80).aspx#Y0 I hate the approach of locking a user into a field. I won't do it for myself or them. I don't ever want a prompt. So that is not the way I will design my interface. The pasting example may be a worry to programmers that work in the public shpere, but I only work for in house Engineers, who don't even know that hex codes or escape codes exist. So far I have been unable to submit anything without leaving the dialog except by closing the dialog without posting, which I want to allow. Anyway, I have my preferences and if they don't work for others, that is fine. This is working the way I described and the way I want. Anyway, I did not see the help you pointed to and it probably does help to make improvements over my code. I searched for 3 hours on msdn and never hit on the search terms that brought that back. Search systems are a failure more and more everywhere (especially microsoft's). Edit: Something seems to be missing from the example. I got it to compile and it allows the keystrokes it says it will. However, I cannot use an InputPanel in an Add-In form and there is no obvious indentification of where to implement the IntValue or DecimalValue to correct the user's input. It lets the user put in multiple decimal points and negative signs, which I have prevented. With the keyboard a user cannot enter junk in my Textbox or an invalid base 10 number, but a user can in this example. Only pasting creates junk in my Textbox, which is a rare occurance for my particular users. Based on the entries I can type in I would expect errors to arise from the IntValue and DecimalValue properties if I did access them. Again, I understand that for programmers in the public sphere more possibilities need to be handled, but they simply are not worth an hour of my time for my users. Edit 2: I see the potential of the leave event not being fired. Triggering that code in the Submit method is one of the options. If you know of a better event that must fire before a user can execute a command button I would like to know about it. It seems you are suggesting to validate it in the command button itself, which I can do to clean up junk. There is no right way to do this (which is the key reason I love the Python script tool interface. This stuff is built in with one click and it just works without me coding anything. Unfortunately the script tool is slow to load and execute when too much code gets added, which is why I am fighting my frustrations and building it in VB.Net.)
... View more
08-28-2012
07:55 PM
|
0
|
0
|
6147
|
|
POST
|
How about something like this: ***untested code*** import arcpy
myFC = r"C:\temp\test.shp"
yearField = "YEAR"
countyField = "COUNTY_CD"
sequenceField = "SEQUENCE" #Integer
concatField = "CONCAT" #text of sufficient length
trackingDict = {}
updateRows = arcpy.UpdateCursor(myFC)
for updateRow in updateRows:
yearValue = updateRow.getValue(yearField)
countyValue = updateRow.getValue(countyField)
if (yearValue, countyValue) in trackingDict:
trackingDict[(yearValue, countyValue)] = trackingDict[(yearValue, countyValue)] + 1
else:
trackingDict[(yearValue, countyValue)] = 1
sequenceId = trackingDict[(yearValue, countyValue)]
updateRow.setValue(sequenceField, sequenceId)
updateRow.setValue(concatField, str(yearValue) + "-" + str(countyValue) + "-" + str(sequenceId))
updateRows.updateRow(updateRow)
del updateRow, updateRows This code will definitely be faster, provided that the assignment of the sequential ID has no relationship to the order of any other field that is not included in the concatenated name. That never applies for my needs (the sequential number always represents the order of one or more fields that are not included in the concatenation, such as dates, street names, or street names and measure), but if it did this would be faster.
... View more
08-28-2012
06:35 PM
|
0
|
0
|
988
|
|
POST
|
I want to use an if else statement to pass a condition and it's not returning any of the two values what im i doing wrong? fc = "Parcels" field = "GeneratedN" cursor = arcpy.SearchCursor(fc) for row in cursor: row.getValue(field) Val = row.getValue(field) if Val == 1: print "Done" else: print "Not Done" Any suggestions please Your indentation is wrong for the Val = row.getValue(field) line. It occurs only after every record is read and should produce an error. It needs to replace the row.getValue(field) line at the same indentation level. fc = "Parcels" field = "GeneratedN" cursor = arcpy.SearchCursor(fc) for row in cursor: Val = row.getValue(field) if Val == 1: print "Done" else: print "Not Done" As rewritten the code will only say done if the actual value in the field is 1. Otherwise it says Not Done. However, only the last record read will be compared for your if statement at this indentation level. All other records will be read, but ignored for the test. So I doubt this is what you really want to test. Normally you would put the if test in the loop and break out of it when you find the value you want. To do that the code would be: fc = "Parcels" field = "GeneratedN" cursor = arcpy.SearchCursor(fc) for row in cursor: Val = row.getValue(field) if Val == 1: print "Done" break; else: print "Not Done"
... View more
08-28-2012
06:24 PM
|
0
|
0
|
2689
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 03-24-2026 11:37 PM | |
| 1 | 03-24-2026 08:01 PM | |
| 6 | 02-23-2026 08:34 AM | |
| 1 | 03-31-2025 03:25 PM | |
| 1 | 03-28-2025 06:54 PM |
| Online Status |
Offline
|
| Date Last Visited |
yesterday
|