I would like to ask some questions about programming in iLogic.
If I assign a variable that I want to pass to a function or sub, can I keep the variable name the same? For example 'oDoc as Document' I want to pick up in different subs to do something with it.
Always a different name or not?
What exactly is the difference between a Public Function and a Function without Public?
I'm working on a rule/application that 'pulls apart' our entire project and puts it in our folder structure.
Finally, we end up with different welding compositions, whether or not based on Phantom or Normal assemblies, whether or not Under Class Approval, etc.
At the end of this process, it is the intention that the Parts that remain will be placed in a folder 'Other Parts', subdivided into Steel and Stainless Steel.
This in itself is going well.
I want to add the quantity of the part or assembly after the file name (step, pdf, dwg and jpg).
I mean for a part the required number with regard to the welding assemblies and of the welding assemblies the total number with regard to the main assembly.
In short, our supplier can easily see from the file name how many times he has to make something.
In itself it works fine to take the assemblies apart recursively and to get them in the desired folder.
I want to determine the numbers for the individual components using:
partQty = oCompDef.Occurrences.AllReferencedOccurrences(oDoc).Count
At the beginning of the rule I go through all the components to make lists of them for learning, entertainment and finally to determine the policy.
At the same time I put all components in a List from which the totals can be retrieved.
I am now looking for a smart way to subtract these totals when the components are processed in the different assemblies.
In other word, I wanna know what's left at the end of this process.
Can I do this through a List, do I have to use a Dictionary for it, or does iLogic have much smarter ways to do it?
I would like to ask some questions about programming in iLogic.
If I assign a variable that I want to pass to a function or sub, can I keep the variable name the same? For example 'oDoc as Document' I want to pick up in different subs to do something with it.
Always a different name or not?
What exactly is the difference between a Public Function and a Function without Public?
I'm working on a rule/application that 'pulls apart' our entire project and puts it in our folder structure.
Finally, we end up with different welding compositions, whether or not based on Phantom or Normal assemblies, whether or not Under Class Approval, etc.
At the end of this process, it is the intention that the Parts that remain will be placed in a folder 'Other Parts', subdivided into Steel and Stainless Steel.
This in itself is going well.
I want to add the quantity of the part or assembly after the file name (step, pdf, dwg and jpg).
I mean for a part the required number with regard to the welding assemblies and of the welding assemblies the total number with regard to the main assembly.
In short, our supplier can easily see from the file name how many times he has to make something.
In itself it works fine to take the assemblies apart recursively and to get them in the desired folder.
I want to determine the numbers for the individual components using:
partQty = oCompDef.Occurrences.AllReferencedOccurrences(oDoc).Count
At the beginning of the rule I go through all the components to make lists of them for learning, entertainment and finally to determine the policy.
At the same time I put all components in a List from which the totals can be retrieved.
I am now looking for a smart way to subtract these totals when the components are processed in the different assemblies.
In other word, I wanna know what's left at the end of this process.
Can I do this through a List, do I have to use a Dictionary for it, or does iLogic have much smarter ways to do it?
Hello
You can use the same name or something completely different. You don't transfer a variable, you (simplified) transfer an object. This object can be transferred itself (ByRef) so any change in you subroutine changes the original or you can transfer a copy (ByVal) where changes doesn't impact the original.
Here's an ultra primitive example. The only diffenrence between i and j is the way they are transferred to the subroutine ByRef/ByVal.
Private Sub Main
Dim i As Integer = 1
Dim j As Integer = 1
Subroutine(i,j)
MsgBox("i: " & i & vbCrLf & "j: " & j)
End Sub
Private Sub Subroutine(ByRef i As Integer, ByVal j As Integer)
i = + 10
j = + 10
End Sub
In addition, you can create a shared variable in iLogic for use in different rules, especially for use between different documents. Let's say you open document A and capture a current parameter value. Save it to the shared variable and close Document A. Now open document B and there's a OnOpenDocument triggered rule that checks for the shared variable and takes the value to do something.
Shared variables need to be handled more carefully. They are destroyed when Inventor is closed, not when a rule is finished. So it's up to you control that a shared variable is deleted when no longer used.
Access levels in VB.Net --> Link
A function without any access level is a private function. It is possible to not explicitly write this, but your code would be better readable and interpretable for yourself and others. Another shortening is the Dim statement. "Dim" without any access level means "Dim private".
Don't use the componentoccurrences collection. You would need
- to take care of the BOMstructure (purchased, inseparable, phantom...) by yourself
- check for manual qty. overrides in the BOM
- ... something BOM structure changing more I forgot
Your way will only work if none of them is used. Otherwise you will get a lot of wrong information and there's no blinking light noticing you. If your supplier is not able to read the qty. from a parts list and use the corresponding drawing, get another supplier? Remember, it's your fault if the ordered qty. (on your pdf, dwg, jpg) is wrong. There's a real big potential to burn a huge amount of money.
I think it would be easier to traverse the BOM (model view), set all assembly and part rows to phantom which are irrelevant to the supplier. This would assume there's an unique identifier for the weld assemblies. the resulting structured BOM view with all levels can be exported to an Excel file.
From this structured view it should also be possible to easily get your quantity info "part per weld assembly" and "weld assembly per main assembly", cause all other levels are "phantomized".
Hello
You can use the same name or something completely different. You don't transfer a variable, you (simplified) transfer an object. This object can be transferred itself (ByRef) so any change in you subroutine changes the original or you can transfer a copy (ByVal) where changes doesn't impact the original.
Here's an ultra primitive example. The only diffenrence between i and j is the way they are transferred to the subroutine ByRef/ByVal.
Private Sub Main
Dim i As Integer = 1
Dim j As Integer = 1
Subroutine(i,j)
MsgBox("i: " & i & vbCrLf & "j: " & j)
End Sub
Private Sub Subroutine(ByRef i As Integer, ByVal j As Integer)
i = + 10
j = + 10
End Sub
In addition, you can create a shared variable in iLogic for use in different rules, especially for use between different documents. Let's say you open document A and capture a current parameter value. Save it to the shared variable and close Document A. Now open document B and there's a OnOpenDocument triggered rule that checks for the shared variable and takes the value to do something.
Shared variables need to be handled more carefully. They are destroyed when Inventor is closed, not when a rule is finished. So it's up to you control that a shared variable is deleted when no longer used.
Access levels in VB.Net --> Link
A function without any access level is a private function. It is possible to not explicitly write this, but your code would be better readable and interpretable for yourself and others. Another shortening is the Dim statement. "Dim" without any access level means "Dim private".
Don't use the componentoccurrences collection. You would need
- to take care of the BOMstructure (purchased, inseparable, phantom...) by yourself
- check for manual qty. overrides in the BOM
- ... something BOM structure changing more I forgot
Your way will only work if none of them is used. Otherwise you will get a lot of wrong information and there's no blinking light noticing you. If your supplier is not able to read the qty. from a parts list and use the corresponding drawing, get another supplier? Remember, it's your fault if the ordered qty. (on your pdf, dwg, jpg) is wrong. There's a real big potential to burn a huge amount of money.
I think it would be easier to traverse the BOM (model view), set all assembly and part rows to phantom which are irrelevant to the supplier. This would assume there's an unique identifier for the weld assemblies. the resulting structured BOM view with all levels can be exported to an Excel file.
From this structured view it should also be possible to easily get your quantity info "part per weld assembly" and "weld assembly per main assembly", cause all other levels are "phantomized".
Thank you very much Krieg for this explanation, very clear.
Thanks also for your warning, the extraction I want to make must indeed be a reflection of the BOM as such with a production release date.
For many suppliers, translating the drawing into production numbers/material/material thickness, etc. remains a manual task.
In this way we think we can reduce the margin of error on both sides.
See screenshot as such a picture could look like, a QR code also seems useful to me.
I once programmed a QR code on documents in the past, does iLogic understand that too?
Just your comment about 'don't use the componentoccurrences collection'.
Do you mean not to use it by definition?
Or not for the purpose.
I'm using 'componentoccurrences' to recursively iterate through the assemblies and get the underlying components, isn't that a correct method?
The way I now get the total numbers, by going through the BrowserPane, I also get the numbers of the Phantoms in the main assembly, as far as I know I don't come across those in a BOM when they are Phantom.
How do you see that?
Thank you very much Krieg for this explanation, very clear.
Thanks also for your warning, the extraction I want to make must indeed be a reflection of the BOM as such with a production release date.
For many suppliers, translating the drawing into production numbers/material/material thickness, etc. remains a manual task.
In this way we think we can reduce the margin of error on both sides.
See screenshot as such a picture could look like, a QR code also seems useful to me.
I once programmed a QR code on documents in the past, does iLogic understand that too?
Just your comment about 'don't use the componentoccurrences collection'.
Do you mean not to use it by definition?
Or not for the purpose.
I'm using 'componentoccurrences' to recursively iterate through the assemblies and get the underlying components, isn't that a correct method?
The way I now get the total numbers, by going through the BrowserPane, I also get the numbers of the Phantoms in the main assembly, as far as I know I don't come across those in a BOM when they are Phantom.
How do you see that?
Hello
There are some QR code generating class libraries out there, which returns an PNG image. Or, if your own code is vb.net, it should be possible to use it in iLogic.
Don't use it in this purpose. The componentoccurrences collection does not "know" anything about BOM quantity overrides. You can use it to traverse the assembly structure, but (in my opinion) you can not count the occurrences and expect the same result as shown in BOM. Let's make a simple example. Assuming an assembly with 3 occurrences of part "A". Part "A" has BOM structure "Phantom". Your code returns a count of 3 and the BOM says "there is no such part".
If you use your way, you need respect the BOM structure of the document. And you'll have to find a way read the BOM qty. override or deceide that BOM qty. overrides aer forbidden.
I depends on which BOM you are. In the mode BOM view, you'll see phantoms too. In the structured and parts only view you'll see the result of all BOM influencing options (BOM structure, Qty. override, base unit and so on). The phantom component is removed in this views.
As the BOM view only consist of BOM rows for components, it's much easier to traverse then the browser pane.
Hello
There are some QR code generating class libraries out there, which returns an PNG image. Or, if your own code is vb.net, it should be possible to use it in iLogic.
Don't use it in this purpose. The componentoccurrences collection does not "know" anything about BOM quantity overrides. You can use it to traverse the assembly structure, but (in my opinion) you can not count the occurrences and expect the same result as shown in BOM. Let's make a simple example. Assuming an assembly with 3 occurrences of part "A". Part "A" has BOM structure "Phantom". Your code returns a count of 3 and the BOM says "there is no such part".
If you use your way, you need respect the BOM structure of the document. And you'll have to find a way read the BOM qty. override or deceide that BOM qty. overrides aer forbidden.
I depends on which BOM you are. In the mode BOM view, you'll see phantoms too. In the structured and parts only view you'll see the result of all BOM influencing options (BOM structure, Qty. override, base unit and so on). The phantom component is removed in this views.
As the BOM view only consist of BOM rows for components, it's much easier to traverse then the browser pane.
Thank you for this insight Krieg, good to know.
May I ask you for a hint:
At what time and by means of which code would you determine the required number of components/sub assemblies?
The moment may not matter?
And most importantly, the number of parts that remain after I know what is needed in all sub assemblies.
How would you find out?
Btw, do you know how I can open a text-log file and jump to the last addition?
I try this:
https://www.dreamincode.net/forums/topic/56497-go-to-a-particular-line-in-a-text-file-using-vbnet/
But get an error message in which I lack knowledge, see screenshot.
Thank you for this insight Krieg, good to know.
May I ask you for a hint:
At what time and by means of which code would you determine the required number of components/sub assemblies?
The moment may not matter?
And most importantly, the number of parts that remain after I know what is needed in all sub assemblies.
How would you find out?
Btw, do you know how I can open a text-log file and jump to the last addition?
I try this:
https://www.dreamincode.net/forums/topic/56497-go-to-a-particular-line-in-a-text-file-using-vbnet/
But get an error message in which I lack knowledge, see screenshot.
Hello
I'm not sure I understand the first three questions. Can you please explain a bit more in detail?
I can not see where _fileName is declared and which value it has. Error message says it is of type object, should be a string. If you want to append to your textfile like in a logfile, here's an alternative way:
Imports System.IO
Dim strFile As String = "C:\Temp\Log.txt"
Dim sw As StreamWriter
Try
If (Not File.Exists(strFile)) Then
sw = File.CreateText(strFile)
Else
sw = File.AppendText(strFile)
End If
sw.WriteLine("%%% PLACE YOUR LOG MESSAGE HERE %%%")
sw.Close()
Catch ex As IOException
MsgBox("Error writing to log file.")
End Try
Hello
I'm not sure I understand the first three questions. Can you please explain a bit more in detail?
I can not see where _fileName is declared and which value it has. Error message says it is of type object, should be a string. If you want to append to your textfile like in a logfile, here's an alternative way:
Imports System.IO
Dim strFile As String = "C:\Temp\Log.txt"
Dim sw As StreamWriter
Try
If (Not File.Exists(strFile)) Then
sw = File.CreateText(strFile)
Else
sw = File.AppendText(strFile)
End If
sw.WriteLine("%%% PLACE YOUR LOG MESSAGE HERE %%%")
sw.Close()
Catch ex As IOException
MsgBox("Error writing to log file.")
End Try
Thanks Krieg, I'll try the code after explaining my questions.
I take a quick look at it, append writing to a text file works fine.
I would like to jump to the last 'appended' part when the file is opened.
My questions in more detail:
For example:
I walk through the browsernodes and come across a phantom or normal assembly that contains weldment(s).
Phantom or normal and containing weldment(s) is a condition to have these assemblies + the underlying parts in a separate folder.
I managed to detect + collect this.
I like the quantity for each part in these assemblies.
How would you determine that?
Then I come to the end of the browser pane and I have had all the phantom weldment assemblies and normal weldment assemblies and put them in the correct folders, so fine.
I then make a subdivision of the parts that remain (FE/SS/non metal) to be able to put them in separate folders.
I want to know the quantity in these collections for each part.
It is possible that a part occurs in both a weldment and this collection.
That for me now the tricky part.
So the question is, how often do I need these parts.
Simply put, the total number minus those in the weldments.
How do I do that in a smart way?
Can I use the BOM functionality for that?
And if so how.
Thanks in advance.
Thanks Krieg, I'll try the code after explaining my questions.
I take a quick look at it, append writing to a text file works fine.
I would like to jump to the last 'appended' part when the file is opened.
My questions in more detail:
For example:
I walk through the browsernodes and come across a phantom or normal assembly that contains weldment(s).
Phantom or normal and containing weldment(s) is a condition to have these assemblies + the underlying parts in a separate folder.
I managed to detect + collect this.
I like the quantity for each part in these assemblies.
How would you determine that?
Then I come to the end of the browser pane and I have had all the phantom weldment assemblies and normal weldment assemblies and put them in the correct folders, so fine.
I then make a subdivision of the parts that remain (FE/SS/non metal) to be able to put them in separate folders.
I want to know the quantity in these collections for each part.
It is possible that a part occurs in both a weldment and this collection.
That for me now the tricky part.
So the question is, how often do I need these parts.
Simply put, the total number minus those in the weldments.
How do I do that in a smart way?
Can I use the BOM functionality for that?
And if so how.
Thanks in advance.
Hello
Do you want to read the last line to display it? Assuming you take my last example to write the file, you can read and display the last line like this:
Imports System.IO
Dim strFile As String = "C:\Temp\Log.txt"
Dim sr As Streamreader
Try
If File.Exists(strFile) Then
sr = System.IO.File.OpenText(strFile)
End If
MsgBox(File.ReadLines(strFile).Last())
sr.Close()
Catch ex As IOException
MsgBox("Error reading logfile.")
End Try
You should use the BOM (model view) instead the browser pane. The browser pane have a lot of nodes that are irrelevant and need to be identified and filtered out. You have to "solve" occurrence patterns (count visible occurrences) by yourself. That's all not necessary in the BOM. You can traverse the same way as the browser pane by looping through every BOMrow and get the referenced document. Then you can check the the BOM structure (Phantom/Normal) of this row and get the quantity of the assembly/part in the assembly one level above. If the BOMrow has ChildRows you can dive down a level. Optional you can commit the quantity ByVal and multiplicate it with the item quantity in the sublevel. This way you get the absolute quantity with respect to the main assembly.
I would divide as per BOM structure Normal weldment/Phantom weldment/ Others in three different dictionaries and collect there each FullFileName and quantity. Every key in a dictionary is unique, so you can (in a try-catch) try to add a key/value pair and if it throws an error (cause an entry with the same key already exists) sum up the new quantity to the existing entry in the catch.
At the end you will have 3 dictionaries with the counts you need and no further calculating needed. You can also use this dictionaries to copy your files in your folder structure.
Hello
Do you want to read the last line to display it? Assuming you take my last example to write the file, you can read and display the last line like this:
Imports System.IO
Dim strFile As String = "C:\Temp\Log.txt"
Dim sr As Streamreader
Try
If File.Exists(strFile) Then
sr = System.IO.File.OpenText(strFile)
End If
MsgBox(File.ReadLines(strFile).Last())
sr.Close()
Catch ex As IOException
MsgBox("Error reading logfile.")
End Try
You should use the BOM (model view) instead the browser pane. The browser pane have a lot of nodes that are irrelevant and need to be identified and filtered out. You have to "solve" occurrence patterns (count visible occurrences) by yourself. That's all not necessary in the BOM. You can traverse the same way as the browser pane by looping through every BOMrow and get the referenced document. Then you can check the the BOM structure (Phantom/Normal) of this row and get the quantity of the assembly/part in the assembly one level above. If the BOMrow has ChildRows you can dive down a level. Optional you can commit the quantity ByVal and multiplicate it with the item quantity in the sublevel. This way you get the absolute quantity with respect to the main assembly.
I would divide as per BOM structure Normal weldment/Phantom weldment/ Others in three different dictionaries and collect there each FullFileName and quantity. Every key in a dictionary is unique, so you can (in a try-catch) try to add a key/value pair and if it throws an error (cause an entry with the same key already exists) sum up the new quantity to the existing entry in the catch.
At the end you will have 3 dictionaries with the counts you need and no further calculating needed. You can also use this dictionaries to copy your files in your folder structure.
Thanks Krieg, very instructive again.
I'm going to delve into it.
It works reasonably well, I'll try to show you tonight what I have in the hope of some tips.
As for the log file, I actually mean a txt file that opens and jumps to the beginning of the last addition.
For example, each new append starts with date, time and a separator like ''______''.
I'm looking for a piece of code that finds the last separation and jumps to it.
Thanks Krieg, very instructive again.
I'm going to delve into it.
It works reasonably well, I'll try to show you tonight what I have in the hope of some tips.
As for the log file, I actually mean a txt file that opens and jumps to the beginning of the last addition.
For example, each new append starts with date, time and a separator like ''______''.
I'm looking for a piece of code that finds the last separation and jumps to it.
Can't find what you're looking for? Ask the community or share your knowledge.