- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hey everyone:
Some of you have helped me in the past with a piece of iLogic code that I was working on to assign a preset tolerance to holes from the part modeling environment. I'm having some trouble with the code, which I'll post below.
The idea is to select some or all holes in the feature list, then run this iLogic rule and have it assign a hole tolerance to the feature based on its size.
I'll also upload an IPT file that I'm using as my example. It has four holes in it.
If I select all four holes, the rule works great.
If I select no holes, it barks at me and quits, which is great.
If I select Hole 1, it adds the tolerance to only that hole, which is great.
If I select Hole 1 and Hole 3, I get an error, "Error in rule: Class B Hole Tolerance, in document: iLogic Class B Hole Tolerance.ipt
Object reference not set to an instance of an object." This is obviously a problem.
If I pick all features, I get a big long error. This I don't understand as the code should be skipping the extrusion feature since it's not a hole. Here it is:
"Error in rule: Class B Hole Tolerance, in document: iLogic Class B Hole Tolerance.ipt
Unable to cast COM object of type 'System.__ComObject' to interface type 'Inventor.HoleFeature'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{ABA7FFC5-E604-498E-B1B1-B829D4E059EC}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))."
Can anyone help me trouble shoot the errors?
Thanks!
Dim oDoc As Document
oDoc = ThisApplication.ActiveEditDocument
Dim i As Integer
i = 1
Dim FeatureCount As Integer
Dim HoleModCount As Integer
Dim Proceed As Integer
If ThisDoc.Document.SelectSet.count <1 Then ' Verify the total number of selected features
q = MessageBox.Show("You must select at least one hole.", "iLogic Error", MessageBoxButtons.OK, MessageBoxIcon.asterisk, MessageBoxDefaultButton.Button1)
Exit Sub
End If
Dim OriginalUnits as Integer
OriginalUnits = oDoc.unitsofmeasure.LengthUnits ' Get the current units of measure
If oDoc.unitsofmeasure.LengthUnits <> 11272 Then oDoc.unitsofmeasure.LengthUnits = 11272 'Set to inches
FeatureCount = ThisDoc.Document.SelectSet.count ' Store the total number of selected features
x = MessageBox.Show(FeatureCount & " Holes in the Current Selection. ", "My iLogic Dialog", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1)
HoleModCount = 0 ' Zero the counter for modified holes
'For Each CurrentHole As HoleFeature In oDoc.ComponentDefinition.Features.HoleFeatures ' Run on ALL Holes
For Each CurrentHole As HoleFeature In ThisDoc.Document.SelectSet ' Run on SELECTED Holes
'For Each CurrentHole In ThisDoc.Document.SelectSet ' Run on SELECTED Features
'If CurrentHole.Suppressed = False Then Proceed = 0 'Run command on suppressed features
If CurrentHole.Type = ObjectTypeEnum.kHoleFeatureObject Then ' Check to make sure this feature is a hole
Proceed = 1 ' Green light
If CurrentHole.Tapped = True Then Proceed = 0 ' Cancel if a tapped hole
If Proceed = 1 Then
'x = MessageBox.Show(CurrentHole.HoleType, "My iLogic Dialog", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1)
Select Case CurrentHole.HoleType
'kCounterBoreHole 21507 Hole Is counterbored.
'kCounterSinkHole 21506 Hole Is countersunk.
'kDrilledHole 21505 Hole Is drilled (no countersink Or counterboring).
'kSpotFaceHole 21508 Hole Is spotfaced.
Case 21505 'Hole Is drilled (no countersink Or counterboring)
Dim oDef As PartComponentDefinition
oDef = oDoc.ComponentDefinition
Dim oHole(i) As HoleFeature
oHole(i) = oDef.Features.HoleFeatures.Item(i)
Dim oDiamParam(i) As Parameter
oDiamParam(i) = oHole(i).HoleDiameter
Dim CurrDiam
CurrDiam = oDiamParam(i).Value / 2.54
'x = MessageBox.Show(CurrDiam, "My iLogic Dialog", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1)
Dim oTol(i) As Tolerance
oTol(i) = oDiamParam(i).Tolerance
If CurrDiam < 0.062 Then oTol(i).SetToDeviation("0.003 in", "-0.001 in")
If CurrDiam > 0.06201 And CurrDiam <= 0.250 Then oTol(i).SetToDeviation("0.010 in", "-0.004 in")
If CurrDiam > 0.25001 And CurrDiam <= 0.500 Then oTol(i).SetToDeviation("0.012 in", "-0.004 in")
If CurrDiam > 0.50001 And CurrDiam <= 0.750 Then oTol(i).SetToDeviation("0.016 in", "-0.006 in")
If CurrDiam > 0.75001 And CurrDiam <= 1.000 Then oTol(i).SetToDeviation("0.020 in", "-0.006 in")
If CurrDiam > 1.00000 Then oTol(i).SetToDeviation("0.020 in", "-0.010 in")
HoleModCount = HoleModCount + 1
InventorVb.DocumentUpdate() ' Update Doc
oDoc.Update()
Case 21507 'Hole Is counterbored
'Do the Through Hole Work First
Dim oDef As PartComponentDefinition
oDef = oDoc.ComponentDefinition
Dim oHole(i) As HoleFeature
oHole(i) = oDef.Features.HoleFeatures.Item(i)
Dim oDiamParam(i) As Parameter
oDiamParam(i) = oHole(i).HoleDiameter
Dim CurrDiam
CurrDiam = oDiamParam(i).Value / 2.54
'q = MessageBox.Show(CurrDiam, "My iLogic Dialog", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1)
Dim oTol(i) As Tolerance
oTol(i) = oDiamParam(i).Tolerance
If CurrDiam < 0.062 Then oTol(i).SetToDeviation("0.003 in", "-0.001 in")
If CurrDiam > 0.06201 And CurrDiam <= 0.250 Then oTol(i).SetToDeviation("0.010 in", "-0.004 in")
If CurrDiam > 0.25001 And CurrDiam <= 0.500 Then oTol(i).SetToDeviation("0.012 in", "-0.004 in")
If CurrDiam > 0.50001 And CurrDiam <= 0.750 Then oTol(i).SetToDeviation("0.016 in", "-0.006 in")
If CurrDiam > 0.75001 And CurrDiam <= 1.000 Then oTol(i).SetToDeviation("0.020 in", "-0.006 in")
If CurrDiam > 1.00000 Then oTol(i).SetToDeviation("0.020 in", "-0.010 in")
'Set a tolerance for the counterbore depth
Dim oCBDepParam(i) As Parameter
oCBDepParam(i) = oHole(i).CBoreDepth
Dim CurrCBoreDep
CurrCBoreDep = oCBDepParam(i).Value
Dim oCboreDepTol(i) As tolerance
oCboreDepTol(i) = oCBDepParam(i).Tolerance
oCboreDepTol(i).settodeviation("0.010 in", "0 in")
InventorVb.DocumentUpdate() ' Update Doc
oDoc.Update()
'For the Countebore
Dim oDiamCboreParam(i) As Parameter
oDiamCboreParam(i) = oHole(i).CboreDiameter
Dim CurrDiamCbore
CurrDiamCbore = oDiamCboreParam(i).Value / 2.54
'x = MessageBox.Show(CurrDiamCbore, "My iLogic Dialog", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1)
Dim oTolCbore(i) As Tolerance
oTolCbore(i) = oDiamCboreParam(i).Tolerance
If CurrDiamCbore < 0.062 Then oTolCbore(i).SetToDeviation("0.003 in", "-0.001 in")
If CurrDiamCbore > 0.06201 And CurrDiamCbore <= 0.250 Then oTolCbore(i).SetToDeviation("0.010 in", "-0.004 in")
If CurrDiamCbore > 0.25001 And CurrDiamCbore <= 0.500 Then oTolCbore(i).SetToDeviation("0.012 in", "-0.004 in")
If CurrDiamCbore > 0.50001 And CurrDiamCbore <= 0.750 Then oTolCbore(i).SetToDeviation("0.016 in", "-0.006 in")
If CurrDiamCbore > 0.75001 And CurrDiamCbore <= 1.000 Then oTolCbore(i).SetToDeviation("0.020 in", "-0.006 in")
If CurrDiamCbore > 1.00000 Then oTolCbore(i).SetToDeviation("0.020 in", "-0.010 in")
HoleModCount = HoleModCount + 1
Case 21506 ' Hole Is countersunk
Dim oDef As PartComponentDefinition
oDef = oDoc.ComponentDefinition
Dim oHole(i) As HoleFeature
oHole(i) = oDef.Features.HoleFeatures.Item(i)
Dim oDiamParam(i) As Parameter
oDiamParam(i) = oHole(i).HoleDiameter
Dim CurrDiam
CurrDiam = oDiamParam(i).Value / 2.54
'x = MessageBox.Show(CurrDiam, "My iLogic Dialog", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1)
Dim oTol(i) As Tolerance
oTol(i) = oDiamParam(i).Tolerance
If CurrDiam < 0.062 Then oTol(i).SetToDeviation("0.003 in", "-0.001 in")
If CurrDiam > 0.06201 And CurrDiam <= 0.250 Then oTol(i).SetToDeviation("0.010 in", "-0.004 in")
If CurrDiam > 0.25001 And CurrDiam <= 0.500 Then oTol(i).SetToDeviation("0.012 in", "-0.004 in")
If CurrDiam > 0.50001 And CurrDiam <= 0.750 Then oTol(i).SetToDeviation("0.016 in", "-0.006 in")
If CurrDiam > 0.75001 And CurrDiam <= 1.000 Then oTol(i).SetToDeviation("0.020 in", "-0.006 in")
If CurrDiam > 1.00000 Then oTol(i).SetToDeviation("0.020 in", "-0.010 in")
HoleModCount = HoleModCount + 1
InventorVb.DocumentUpdate() ' Update Doc
oDoc.Update()
End Select
End If
Else
Proceed = 0 ' Red light if the feature isn't a hole
End If
i = i + 1
Next CurrentHole ' Next Feature
ThisDoc.Document.Rebuild()
ThisApplication.CommandManager.ControlDefinitions.Item("AppUpdateMassPropertiesCmd").Execute
q = MessageBox.Show(HoleModCount & " hole(s) were updated", "iLogic Complete!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1)
oDoc.unitsofmeasure.LengthUnits = OriginalUnits
InventorVb.DocumentUpdate() ' Update Doc
oDoc.Update()
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
1. The method in which you were accessing the select set is very poor. You were calling it multiple times instead of storing the object
2. If you are using a for loop and declaring a variable within the loop ("For Each Hole as HoleFeature"), if the object does not match that type, the loop will fail. Either you need to do a pre-check to ensure everything it loops through is that feature, or declare it as a generic object (same as leaving it undeclared).
3. The way your code was written had it updating things multiple times which would slow things down.
4. Your code was very hard to read and to follow what it was doing.
All that said, I partially refactored it to split it up and re-write it in a manner that makes sense.
You will need to continue on converting the If Statements for setting tolerances to the Select Case structure to clean it up, but aside from that it should not have the same issues.
Let me know if you come across anything I may have missed.
Sub Main()
Dim oDoc As Document
oDoc = ThisApplication.ActiveEditDocument
Dim i As Integer
i = 1
oSS = oDoc.SelectSet
FeatureCount = oSS.count ' Store the total number of selected features
Dim oHoleColl As New Collection
Select Case FeatureCount
Case <1
q = MessageBox.Show("You must select at least one hole.", "iLogic Error", MessageBoxButtons.OK, MessageBoxIcon.asterisk, MessageBoxDefaultButton.Button1)
Exit Sub
Case >1
Dim HoleFeatureCount As Integer
For Each oItem in oSS
If oItem.Type = 83912192 'kHoleFeatureObject
oHoleColl.Add(oItem)
HoleFeatureCount = HoleFeatureCount + 1
End If
Next
x = MessageBox.Show(HoleFeatureCount & " Holes in the Current Selection. ", "My iLogic Dialog", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1)
Case = 1
If oSS.Item(1).Type = 83912192 'kHoleFeatureObject
oHoleColl.Add(oSS.Item(1))
Else
MsgBox("Object selected is not a hole")
Exit Sub
End If
End Select
Dim OriginalUnits as Integer
OriginalUnits = oDoc.unitsofmeasure.LengthUnits
If oDoc.unitsofmeasure.LengthUnits <> 11272 Then oDoc.unitsofmeasure.LengthUnits = 11272
'Process Here
Call ProcessHoleTolerances(oDoc, oHoleColl)
oDoc.Rebuild()
oDoc.Update
'ThisApplication.CommandManager.ControlDefinitions.Item("AppUpdateMassPropertiesCmd").Execute
oDoc.unitsofmeasure.LengthUnits = OriginalUnits
q = MessageBox.Show(HoleModCount & " hole(s) were updated", "iLogic Complete!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1)
End Sub
Private HoleModCount As Integer = 0
Sub ProcessHoleTolerances(oDoc As Document, oHoleFeatureColl As Collection)
Dim oDef As PartComponentDefinition
oDef = oDoc.ComponentDefinition
For Each CurrentHole As HoleFeature In oHoleFeatureColl ' Run on SELECTED Holes
If CurrentHole.Tapped <> True ' Cancel if a tapped hole
oDiamParam = CurrentHole.HoleDiameter
CurrDiam = oDiamParam.Value / 2.54
oTol = oDiamParam.Tolerance
Select Case CurrentHole.HoleType
'kCounterBoreHole 21507 Hole Is counterbored.
'kCounterSinkHole 21506 Hole Is countersunk.
'kDrilledHole 21505 Hole Is drilled (no countersink Or counterboring).
'kSpotFaceHole 21508 Hole Is spotfaced.
Case 21505 'Hole Is drilled (no countersink Or counterboring)
Select Case CurrDiam
Case < 0.062
oTol.SetToDeviation("0.003 in", "-0.001 in")
Case <= 0.250
oTol.SetToDeviation("0.010 in", "-0.004 in")
Case <=.500
oTol.SetToDeviation("0.012 in", "-0.004 in")
End Select
' If CurrDiam > 0.50001 And CurrDiam <= 0.750 Then oTol(i).SetToDeviation("0.016 in", "-0.006 in")
' If CurrDiam > 0.75001 And CurrDiam <= 1.000 Then oTol(i).SetToDeviation("0.020 in", "-0.006 in")
' If CurrDiam > 1.00000 Then oTol(i).SetToDeviation("0.020 in", "-0.010 in")
HoleModCount = HoleModCount + 1
Case 21507 'Hole Is counterbored
If CurrDiam < 0.062 Then oTol(i).SetToDeviation("0.003 in", "-0.001 in")
If CurrDiam > 0.06201 And CurrDiam <= 0.250 Then oTol(i).SetToDeviation("0.010 in", "-0.004 in")
If CurrDiam > 0.25001 And CurrDiam <= 0.500 Then oTol(i).SetToDeviation("0.012 in", "-0.004 in")
If CurrDiam > 0.50001 And CurrDiam <= 0.750 Then oTol(i).SetToDeviation("0.016 in", "-0.006 in")
If CurrDiam > 0.75001 And CurrDiam <= 1.000 Then oTol(i).SetToDeviation("0.020 in", "-0.006 in")
If CurrDiam > 1.00000 Then oTol(i).SetToDeviation("0.020 in", "-0.010 in")
'Set a tolerance for the counterbore depth
Dim oCBDepParam As Parameter
Dim CurrCBoreDep
Dim oCboreDepTol(i) As tolerance
oCBDepParam = CurrentHole.CBoreDepth
CurrCBoreDep = oCBDepParam.Value
oCBDepParam.Tolerance.SetTodeviation("0.010 in", "0 in")
'For the Countebore
Dim oDiamCboreParam As Parameter
Dim CurrDiamCbore
Dim oTolCbore As Tolerance
oDiamCboreParam = CurrentHole.CboreDiameter
CurrDiamCbore = oDiamCboreParam.Value / 2.54
oTolCbore= oDiamCboreParam.Tolerance
Select Case CurrDiamCbore
Case < 0.062
oTolCbore.SetToDeviation("0.003 in", "-0.001 in")
Case <= .250
Case <= .500
Case <= .750
Case <= 1
End Select
' If CurrDiamCbore < 0.062 Then oTolCbore.SetToDeviation("0.003 in", "-0.001 in")
' If CurrDiamCbore > 0.06201 And CurrDiamCbore <= 0.250 Then oTolCbore(i).SetToDeviation("0.010 in", "-0.004 in")
' If CurrDiamCbore > 0.25001 And CurrDiamCbore <= 0.500 Then oTolCbore(i).SetToDeviation("0.012 in", "-0.004 in")
' If CurrDiamCbore > 0.50001 And CurrDiamCbore <= 0.750 Then oTolCbore(i).SetToDeviation("0.016 in", "-0.006 in")
' If CurrDiamCbore > 0.75001 And CurrDiamCbore <= 1.000 Then oTolCbore(i).SetToDeviation("0.020 in", "-0.006 in")
' If CurrDiamCbore > 1.00000 Then oTolCbore(i).SetToDeviation("0.020 in", "-0.010 in")
HoleModCount = HoleModCount + 1
Case 21506 ' Hole Is countersunk
Select Case CurrDiam
Case < 0.062
oTol.SetToDeviation("0.003 in", "-0.001 in")
Case <= .250
Case <= .500
Case <= .750
Case <= 1
End Select
' If CurrDiam < 0.062 Then oTol(i).SetToDeviation("0.003 in", "-0.001 in")
' If CurrDiam > 0.06201 And CurrDiam <= 0.250 Then oTol(i).SetToDeviation("0.010 in", "-0.004 in")
' If CurrDiam > 0.25001 And CurrDiam <= 0.500 Then oTol(i).SetToDeviation("0.012 in", "-0.004 in")
' If CurrDiam > 0.50001 And CurrDiam <= 0.750 Then oTol(i).SetToDeviation("0.016 in", "-0.006 in")
' If CurrDiam > 0.75001 And CurrDiam <= 1.000 Then oTol(i).SetToDeviation("0.020 in", "-0.006 in")
' If CurrDiam > 1.00000 Then oTol(i).SetToDeviation("0.020 in", "-0.010 in")
HoleModCount = HoleModCount + 1
Case Else
MsgBox("Hole type not found!")
End Select
End If
Next CurrentHole ' Next Feature
End Sub
--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization
iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread
Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects
Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help
Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
This works well, and I like the use of the Select Case as opposed to the If/And's.
Thanks