Cancelling an inputbox loop

Cancelling an inputbox loop

f_nicolle
Contributor Contributor
622 Views
9 Replies
Message 1 of 10

Cancelling an inputbox loop

f_nicolle
Contributor
Contributor

Hi, I'm trying to create an iLogic rule that allows the user to create a set number of custom iProperties. The properties are always the same. Right now my rule will ask for each property individually, but I want the whole rule to stop running as soon as the user clicks on "cancel" and everything that has been typed so far to be deleted.

 

The last two values are booleans, which for whatever reason even though the first radio box button should be "true" returns false so I inverted the labels, which I am not happy about.

 

customPropertySet = ThisDoc.Document.PropertySets.Item("Inventor User Defined Properties")

Dim iprop(8) As String
iprop(1) = "Part Number"
iprop(2) = "Part code"
iprop(3) = "Ø1"
iprop(4) = "Ø2"
iprop(5) = "Total length"
iprop(6) = "Pitch"
iprop(7) = "Cone"
iprop(8) = "Watercooling"

For k = 1 To 6
Dim prop(k) As String
    Try
        prop(k) = iProperties.Value("Custom", iprop(k))
    Catch
        'Assume error means not found
        customPropertySet.Add("", iprop(k))
        iProperties.Value("Custom", iprop(k)) = "null"
    End Try
Next

For j = 1 To 6
    Dim var(j) As String
    If iProperties.Value("Custom", iprop(j)) = "null" Then
        var(j) = InputBox("Input a value " & iprop(j), "warning", "")
        iProperties.Value("Custom", iprop(j)) = var(j)
    End If
	
Next

For k = 7 To 8
Dim prop(k) As Boolean
    Try
        prop(k) = iProperties.Value("Custom", iprop(k))
    Catch
        'Assume error means not found
        customPropertySet.Add("", iprop(k))
        iProperties.Value("Custom", iprop(k)) = "null"
    End Try
Next

For j = 7 To 8
    Dim var(j) As Boolean
    If iProperties.Value("Custom", iprop(j)) = "null" Then
        var(j) = booleanParam = InputRadioBox(iprop(j), "No", "yes", booleanparam, Title := "warning")
        iProperties.Value("Custom", iprop(j)) = var(j)
    End If

 

 

I used this code that I ever so slightly modified : https://forums.autodesk.com/t5/inventor-programming-ilogic/ilogic-create-custom-ipropertie/td-p/2953... 

0 Likes
Accepted solutions (1)
623 Views
9 Replies
Replies (9)
Message 2 of 10

WCrihfield
Mentor
Mentor

Hi @f_nicolle.  The first thing that may be messing with you is the Index system of arrays.  The first element of an array is always zero (0), instead of one (1).  And when specifying the 'size/capacity' of an array, you always specify one less than needed, due to the first element being at Index of zero.  So, I decided to switch that to a 'List(Of String)' type variable, which is less strict, but still has its first element at zero, but no need to specify its size/capacity.  Then I condensed the code a bit, to be more efficient and more under control.  Give this a try, and see if this works better for you.

Dim oDoc As Inventor.Document = ThisDoc.Document
If Not oDoc.IsModifiable Then
	MsgBox("Current Document is not modifiable!", vbCritical, "Not Modifiable")
	Return
End If
'cutsom iProperties set, always exists, and always at Index of 4
Dim oCProps As Inventor.PropertySet = oDoc.PropertySets.Item(4)

Dim iPropNames As New List(Of String)
iPropNames.Add("Part Number") '0
iPropNames.Add("Part code") '1
iPropNames.Add("Ø1") '2
iPropNames.Add("Ø2") '3
iPropNames.Add("Total length") '4
iPropNames.Add("Pitch") '5
iPropNames.Add("Cone") '6
iPropNames.Add("Watercooling") '7

For i As Integer = 0 To 5
	Dim oCProp As Inventor.Property = Nothing
	Dim sPropName As String = iPropNames.Item(i)
    Try 'try to find existing
        oCProp = oCProps.Item(sPropName)
    Catch 'create it if not found
		Dim sVal As String = InputBox("Input a value for " & sPropName, "warning", "")
        oCProp = oCProps.Add(sVal, sPropName)
    End Try
Next

For i As Integer = 6 To 7
	Dim oCProp As Inventor.Property = Nothing
	Dim sPropName As String = iPropNames.Item(i)
    Try 'try to find existing
        oCProp = oCProps.Item(sPropName)
    Catch 'create it if not found
		Dim bVal As Boolean = InputRadioBox(sPropName, "Yes", "No", False)
        oCProp = oCProps.Add(bVal, sPropName)
    End Try
Next

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 10

f_nicolle
Contributor
Contributor

Thanks ! But it appears your code does pretty much the same thing as mine and clicking "cancel" on any input box does not prevent the following ones to appear, making the user have to cancel them all one by one if they made a mistake or just want to exit...

0 Likes
Message 4 of 10

Stakin
Collaborator
Collaborator
customPropertySet = ThisDoc.Document.PropertySets.Item("Inventor User Defined Properties")

Dim iprop(8) As String
iprop(1) = "Part Number"
iprop(2) = "Part code"
iprop(3) = "Ø1"
iprop(4) = "Ø2"
iprop(5) = "Total length"
iprop(6) = "Pitch"
iprop(7) = "Cone"
iprop(8) = "Watercooling"

For k = 1 To 6
Dim prop(k) As String
    Try
        prop(k) = iProperties.Value("Custom", iprop(k))
    Catch
        'Assume error means not found
        customPropertySet.Add("", iprop(k))

        iProperties.Value("Custom", iprop(k)) = "null"
    End Try
Next

For j = 1 To 6
    Dim var(j) As String
    If iProperties.Value("Custom", iprop(j)) ="null" Or iProperties.Value("Custom", iprop(j)) ="" Then
        var(j) = InputBox("Input a value " & iprop(j), "warning", "")
        iProperties.Value("Custom", iprop(j)) = var(j)
    End If
	
Next

For k = 7 To 8
Dim prop(k) 
    Try
        prop(k) = iProperties.Value("Custom", iprop(k))
    Catch
        'Assume error means not found
        customPropertySet.Add("", iprop(k))
        iProperties.Value("Custom", iprop(k)) = "null"
    End Try
Next

For j = 7 To 8
    Dim var(j) As Boolean
    If CStr(iProperties.Value("Custom", iprop(j)))= "null"  Or CStr(iProperties.Value("Custom", iprop(j))) ="False" Then
        var(j) = InputRadioBox(iprop(j), "Yes", "No", False, Title := "warning")
        iProperties.Value("Custom", iprop(j)) = var(j)
    End If
	Next
	
0 Likes
Message 5 of 10

WCrihfield
Mentor
Mentor

Must have been going to fast and forgot about that main detail.  Generally, when using an InputBox dialog, I specify an empty String as the 'default' value.  Then, on the very next line of code, I check the value of the variable that the InputBox was supposed to set the value of, to see if it is still an empty String, using [=""], and if that is the case, I use the code phrase 'Exit For' to exit a For type loop, or 'Exit Do' if it is a Do...Loop type of loop, or 'Exit While' if it is that type of loop, and so on.  We can also use something like 'Continue For' to skip to the next item in a loop, without taking any further actions on the current item in the loop, but that lets the loop continue.  So, in my code example, that would have needed to be injected between Line 25 & Line 26.  But when using an InputRadioBox, there is no way of knowing if the user clicked one button or the other, so no obvious way to escape the loop, unless you actually prompted the user with a another similar dialog or question, to ask them if they want to continue.

Edit:  We can also use something like 'Exit Sub' or 'Return', but that would exit out of the whole Sub routine (Sub Main) block of code, not just the loop.

Edit2:  It may also be useful to know that the 'default' value of a Boolean type variable is False, which can also be represented as the Integral value of zero (0).  So, if the Boolean variable was created and/or its initial value is set within the loop, just before using the InputRadioBox to set its value, then set the 'default' of the InputRadioBox (fourth input) to the same value, then when checking that variables value in the next line of code after the InputRadioBox you get the other value would indicate that the user clicked the other button.  But when the default value is returned, there is no way of knowing if it is because of user interaction or not.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 10

J-Camper
Advisor
Advisor
Accepted solution

@f_nicolle,

Try This:

Dim oDoc As Inventor.Document = ThisDoc.Document
If Not oDoc.IsModifiable Then
	MessageBox.Show("Current Document is not modifiable!", "Nothing Happened")
	Return
End If

Dim iPropStringNames As New List(Of String)
iPropStringNames.AddRange({"Part Number", "Part code", "Ø1", "Ø2", "Total length", "Pitch"})
Dim iPropBooleanNames As New List(Of String)
iPropBooleanNames.AddRange({"Cone", "Watercooling"})

Dim iPropInputMap As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap

For Each s As String In iPropStringNames
	Dim userInput As String = InputBox("Input a value " & s, "iProperty Value Input", String.Empty)
	If userInput = String.Empty Then MessageBox.Show("No Value input for """ & s & """. No iProperties will be made.", "Nothing Happened") : Exit Sub
	iPropInputMap.Add(s, userInput)
Next
For Each s As String In iPropBooleanNames
	Dim userInput As DialogResult = MessageBox.Show("Select Value for """ & s & """. [Yes = True | No = False]", "iProperty Value Selection", MessageBoxButtons.YesNoCancel)
	If userInput <> DialogResult.Yes And userInput <> DialogResult.No Then MessageBox.Show("No Value input for " & s & ". No iProperties will be made.", "Nothing Happened") : Exit Sub
	If userInput = DialogResult.Yes
		iPropInputMap.Add(s, True)
	Else If userInput = DialogResult.No
		iPropInputMap.Add(s, False)
	End If
Next

If iPropInputMap.Count <> iPropStringNames.Count+iPropBooleanNames.Count Then MessageBox.Show("Incorrect number of answers recorded. No iProperties will be made.", "Nothing Happened") : Exit Sub

'cutsom iProperties set, always exists, and always at Index of 4
Dim oCProps As Inventor.PropertySet = oDoc.PropertySets.Item(4)
For i = 1 To iPropInputMap.Count
	Try
		Dim invProperty As Inventor.Property = oCProps.Item(iPropInputMap.Name(i))
		If invProperty.Value = iPropInputMap.Value(iPropInputMap.Name(i)) Then Continue For
		invProperty.Value = iPropInputMap.Value(iPropInputMap.Name(i))
	Catch
		oCProps.Add(iPropInputMap.Value(iPropInputMap.Name(i)), iPropInputMap.Name(i))
	End Try
Next

 

It has an escape path after each user interaction and won't make any changes without getting an answer to every question.  It also splits the value types into different lists you you don't need to hard code indexing.

Let me know if you have any questions, or if this is not working as intended

Message 7 of 10

Stakin
Collaborator
Collaborator
customPropertySet = ThisDoc.Document.PropertySets.Item("Inventor User Defined Properties")
Dim iprop As New List(Of String) From {"Part Number", "Part code", "Ø1", "Ø2",
																"Total length", "Pitch", "Cone", "Watercooling" }
Dim prop(7) , var(7) As Object
For k = 0 To 7
    Try
        prop(k) = iProperties.Value("Custom", iprop(k))
    Catch 
		customPropertySet.Add("", iprop(k))
        iProperties.Value("Custom", iprop(k)) = ""
		prop(k)=iProperties.Value("Custom", iprop(k))
    End Try
Next
Dim result As DialogResult
Dim  oresult As Boolean
For j = 0 To 7    
    If j<6  Then
        var(j) = InputBox($"Input or modify '{iprop(j)}' value: {Vblf}{Vblf}'{iprop(j)}' Current value = {iif(prop(j)="","null",prop(j))}{Vblf}Press OK to confirm!", "Change value warning", prop(j),,)
		oresult =(StrComp(var(j), prop(j), CompareMethod.Text)<>0)
	Else 
        var(j) = InputRadioBox(iprop(j), "Yes", "No", False, Title := "'{iprop(j)}' value select")
		oresult=(CStr(var(j))<>CStr(prop(j)))
    End If
	Dim oMsgtext1 As String = $"'{iprop(j)}' value from  '{iif(Cstr(prop(j))="","null",prop(j))}'  changed to   '{iif(Cstr(var(j))="","null",var(j))}'  "
	Dim oMsgtext2 As String =$"{Vblf}{Vblf}Confirm the modification press the OK , {Vblf}otherwise Canceled?"
	If oresult Then result=MessageBox.Show(oMsgtext1 & oMsgtext2, "Title",MessageBoxButtons.YesNo)
    iProperties.Value("Custom", iprop(j)) = IIf(result = DialogResult.Yes ,var(j), prop(j))
Next

Try this one,good luck.

0 Likes
Message 8 of 10

f_nicolle
Contributor
Contributor

This works really well actually, above and beyond what I needed but I'm not complaining lol. I'm just trying to figure out what exactly  the last part of code is doing, starting with "custom iproperties set..." 

 

Thank you !

0 Likes
Message 9 of 10

Stakin
Collaborator
Collaborator
customPropertySet = ThisDoc.Document.PropertySets.Item("Inventor User Defined Properties")
Dim iprop As New List(Of String) From {"Part Number", "Part code", "Ø1", "Ø2",
																"Total length", "Pitch", "Cone", "Watercooling" }
Dim oprop As New List(Of String)
For i As Integer = 1 To customPropertySet.Count
	oprop.Add(customPropertySet.Item(i).Name)
Next
Dim intersection As List(Of String) = iprop.Intersect(oprop).ToList()
Dim oList As New List(Of String) 
oList .AddRange( iprop)
oList.Insert(0, "ALL") 
Dim oUserInput As String 
If intersection.Count <>iprop.Count Then
	oUserInput = "ALL"
Else
 	oUserInput = InputListBox("Select property need modify ", oList, oList(0), "Property Selection Box", "Property List")
End If
Dim oSt ,oEnd As Integer
If oUserInput = "ALL" Then
	oSt = 0 : oEnd = iprop.Count-1
Else
	oSt =iprop.IndexOf(oUserInput) : oEnd = oSt
End If
Dim prop(iprop.Count-1), var(iprop.Count-1) As Object
For k =oSt To oEnd
    Try
        prop(k) = iProperties.Value("Custom", iprop(k))
    Catch 
		customPropertySet.Add("", iprop(k))
        iProperties.Value("Custom", iprop(k)) = IIf(k<6,"",True)
		prop(k)=iProperties.Value("Custom", iprop(k))
    End Try
Next
Dim result As DialogResult
Dim oresult As Boolean
	
For j = oSt To oEnd    
    If j<iprop.Count-2  Then
        var(j) = InputBox($"Current value:{iprop(j)}= {iif(prop(j)="","null",prop(j))} {Vblf}Press OK to confirm!", $"Input or modify '{iprop(j)}' value", prop(j),,)
	Else 
        var(j) = InputRadioBox(iprop(j), "Yes", "No", False, Title := $"'{iprop(j)}' value select")
    End If
	oresult =(StrComp(CStr(var(j)), CStr(prop(j)), CompareMethod.Text)<>0)
	Dim oMsgtext1 As String = $"The value '{iif(Cstr(prop(j))="","null",prop(j))}' will be changed to '{iif(Cstr(var(j))="","null",var(j))}'"
	Dim oMsgtext2 As String =$"{Vblf}Confirm the modification press the OK,{Vblf}otherwise Canceled?"
	If oresult Then result=MessageBox.Show(oMsgtext1 & oMsgtext2, $"'{iprop(j)}' value change warning",MessageBoxButtons.YesNo)
    iProperties.Value("Custom", iprop(j)) = IIf(result = DialogResult.Yes ,var(j), prop(j))
Next
0 Likes
Message 10 of 10

J-Camper
Advisor
Advisor

@f_nicolle,

I added some comments to the iProperties section:

'custom iProperties set, always exists, and always at Index of 4
Dim oCProps As Inventor.PropertySet = oDoc.PropertySets.Item(4)
'When using a namevaluemap, you need to use and indexed loop since there is both a name and value for
'each entry.  NameValueMap Indexing starts at 1 so the last index is equal to the Count of entries
For i = 1 To iPropInputMap.Count
	'This is a for of error handling.  The rule will only process the "Try" statement unless it
	'encounters an error.  On error the try statement is abandoned and the catch statement gets run
	Try 
		'"Try" to get an iProperty from the document by name.  This will throw and error if one doesn't exist
		Dim invProperty As Inventor.Property = oCProps.Item(iPropInputMap.Name(i))
		'If there was no error, then we know the iProperty exists.
		'Now we check if the iProperty value is already what the user wants it to be. 
		'If it already matches then it will skip the next line and move on with the loop [Continue For].
		If invProperty.Value = iPropInputMap.Value(iPropInputMap.Name(i)) Then Continue For
		'Here we have th iProperty in the document we want, and the value is not what we want, so we set the value.
		invProperty.Value = iPropInputMap.Value(iPropInputMap.Name(i))
	Catch
		'This will only process if there is an error in the Try section.  The only thing in there that should be
		'able to throw an error is the attempt to get an existing iProperty.  With that in mind we can safely assume
		'this statement running means no iProperty with the intended name exists, so we will make it
		oCProps.Add(iPropInputMap.Value(iPropInputMap.Name(i)), iPropInputMap.Name(i))
	End Try
Next

It is looping through a NameValueMap, which is a collection object that tracks a name linked to a value.  Inside the loop is a Try/Catch block for error handling.  This is use to test if the document already has an iProperty with the mapped name, set the value if it needs to, but create a new iProperty if there is not already one.

Let me know if you have any other questions.

0 Likes