What is the purpose of the loop for checking to see if the number already exists?
You can set a validation rule that requires unique values if you want to prevent duplicates. You can also specify "existing values" if you only want to permit entering values that are already present in the table. You can also write your own validation calculations if such are needed.
You also can perform finds or use a relationship instead of a loop to check and see if the value entered already exists.
The field that I'm searching is an un-editable serial number field. When I create the record I use validation for unique values and auto-incrementalization, but for this script it's more of a look-up function. I'm not creating a record, I'm "finding" a record so that I can edit it. The perform find works but it's not as elegant as a custom dialogue that prompts the user for the info and provides a spot to input. If I just used perform find the user would have to know which field to input, etc.
The other reason I'd like to do it this way is because I'm trying to learn more and become more familiar with FileMaker and scripting. Solving this could come in handy with other calcuations I'm trying to attmempt. Can you point me in the right direction for writing my own validation calculation? I believe that's the only thing I'm missing but I don't know which function will do what I need. Thanks.
I'm not creating a record, I'm "finding" a record so that I can edit it. The perform find works but it's not as elegant as a custom dialogue that prompts the user for the info and provides a spot to input. If I just used perform find the user would have to know which field to input, etc.
This is not the case. Your script can set up and perform the find instead of the user. You can also use a relationship to find a record with a matching value.
Both options avoid using a loop--which could produce major performance delays if you have a lot of records to loop through just to find one with a matching value.
I think I'm trying to write a script that will perform the find. The loop solely exists so that if the number the user gives is not valid it will "loop" and ask them to try again. That's the only reason I've included the loop.
If I can do it without a loop that would be fine too. As I said in my original post, I had it working fine using a script that produced a custom dialog, searched, and found the record, but it didn't allow for an incorrect response. If the input was not a valid number it would say no records met the search criteria, and if I selected 'modify search parameters' (or whatever it says) it would go to the first field in the layout (not the field I want to search with). This is where I'd like it to re-issue the dialog so the user isn't looking for the right spot to click and input. If it won't work like that then I'm probably as far along as I need to be. If not, can you elaborate any more on setting up a script or using a relationship? I might understand the technical aspect if I can understand the philosophy.
The hardest aspect I've had trying to learn FileMaker is getting my head around how it wants to work and not how I want to work. This basic "philosophy" is something that the more I grasp, the easier it gets to make things happen. Thanks.
Ok, that answers my initial question: "Why use a loop?"
What kind of data might the user enter that is "invalid"? (What makes it invalid?)
You can keep the "no records found" dialog from interrupting your script if you use Set Error Capture [on] like this:
Set Error Capture [on]
You can use get ( FoundCount ) or get ( lastError ) in an If step immediately after the script to check on the results of the find.
The data would be "invalid" if it's not a serial number that already exists. Since the button and script is purely for editing an existing record, they must input the unique serial for an existing record for it to work. The fact that it must be existing also rules out any posibility of the user inputting the wrong type of data, etc.
The Set Error Capture feature worked well. Thanks.
get ( FoundCount ) also worked in the If statement. The script still works well if you put in the right data the first time around. If not, I tried using an Else If and it sort of worked, but not perfectly. I tried a few other things and now am so far removed from where I was it's hard to remember. The issue that kept recurring no matter what variables I changed was that after an incorrect entry, the layout was showing zero results (or records), so when it would search again it wouldn't find anything, even if it was a correct value. If I backed out of the script and hit 'Show All' and re-ran it would work. I tried to get around this by using 'Show All Records' before 'perform find' but it didn't work. The same thing happened. Attached is a screenshot of my current setup. How do I get the Else If (or Else) statements to work appropriately. The If seems to be working fine. Thanks!
First of all, the last Else will never take place. If you think about what tests you are doing in the If and Else If steps, there is no way the final Else will ever happen as all find results will produce either a found count that = 1 or a found count that does not equal 1.
I see several potential problems that have nothing to do with the If, Else-IF and Else steps however.
What kind of field are you using as the input field for the custom dialog? The best option is to use a field with global storage. Global fields retain their values when the window enters find mode where non global fields will go blank so that you or your script can enter find criteria. I suspect that's why you are having trouble when you loop around and give the user another chance to enter the number.
I'd write the script like this, using a field named gNumber with global storage specified in field options as the input field:
Show Custom Dialog ["Enter the CTS ID..."]
IF [Get (LastMessageChoice ) = 1 //OK was clicked ]
Enter Find mode  -->clear the pause check box
Set Field [Inventory::kf_CTS_ID ; Inventory::gNumber ]
Set Error Capture [on]
Perform Find 
IF [Get ( FoundCount ) //at least one record was found ]
Exit Loop If [True]
Set Field [Inventory::gNumber ; "" ] ---> clears the field of the invalid value thus entered
Show Custom Dialog ["An invalid CTS..."]
#Cancel was clicked
Set Variable [$Cancel ; value: True ]
Exit Loop If [True ]
If [Not $Cancel]
Go To Field[Inventory::Description]
But I wouldn't necessarily use a loop with Show Custom Dialog for this. If you format a field with a drop down list or pop up menu, you can give it a value list of CTS_ID numbers with the description listed as the second field. This limits the user to being only able to enter/select valid ID numbers and provides additional info to help them select the correct value. Since such a field format is not possible inside a custom dialog, you'd have to do this directly on a layout, but you can use the New Window script step to open a small modal window to serve in place of the custom dialog and then you can use a value list format on your field.
If you have trouble with Set Field:
When Setting up Set Field, there are two Specify buttons that must be clicked. To get Set Field [Table::Field ; Expression], add set field to your script and click the first button (specify target field). Select Table::Field from the list of fields. Do not click the specify button next to the repetition box. Click OK to close this dialog box. Now click the lower specify button (calculated result) and create the expression to the right of the semicolon (;). Do not try to type in the semicolon.
If you'd like to see other ways set field can be used to specify search criteria, see the post near the beginning of this thread: http://forums.filemaker.com/posts/ba7347f58a
I had used that last Else based on the recommendation of a FileMaker book I'm also using. It just said it never hurts to have an Else in case some weird thing happens and you wind up with something you didn't expect.
I had actually tried the global storage field before because that seemed logical to me as well. Where I was really falling short was the verbiage associated with some of the commands. I didn't know you could just write 'True' or 'Not ...', and you also showed me a couple of functions that I hadn't come across yet such as get(LastMessageChoice). That was all very helpful.
In summary, it works well except for the same issue I mentioned before. I can get in and out of the loop and If statements fine. The only issue is when an invalid entry happens, it clears out the "available" records for the next search, so then even if you put something valid in you get no results. Attached is what I see at the top of the screen. It shows 0/5 records to search from the second go-around. How do I prevent this from happening? I guess it's carrying through with the original "find" and because I have the error dialog turned off it's just blanking the records as if the find went through. If I hit 'Show All' I get my existing records back and the next search will work. Ideas?
I'm so close!
Nevermind, I just got it. In my second custom dialogue I was re-prompting for input, but with the way this script is set up that wasn't working well. Now it's just a notification and it goes back to the original dialog and it works! Thanks very much.
You are correct that if you perform a find and no records are found, you'll get a found set of 0 records as you show. But with a global field, this should not affect how the script works. You should still be able to enter a new value into the global find and perfom another find to pull up the records.
If, for cosmetic reasons, you don't want the screen to go nearly blank due to a found set of 0 records, you can include a Show All Records step after you test Get (FoundCount) to see if anything was found or not--but this is not needed in order for the loop to repeat the show custom dialog, get a new number and try again.