16 Replies Latest reply on Nov 14, 2017 10:17 PM by Josh Brady

    Mathematically modifying custom properties

      My boss wants me to modify our company's titleblock to have a "Quantity per assembly" field and a "total quantity for the job" field (in the frequent case that we build more than one of an assembly). These fields have to be on the part drawing, which is why I posted it in this category.

      It would be ideal if SW could get this information from the top-level assembly drawing and link it back to the parts, but I see no way of doing this. I figure the only way to do this is by having the "quantity per assembly" field manually filled out, then fill out some multiplier value through Task Scheduler to tell it how many builds there are for the project and use SW to multiply the two custom properties together to get what I'm after.

      When I add a custom property, it gives me the option of what type of property it is (Text, Number, etc). I figure that there must be a way to manipulate the numbers but SW help isn't too helpful in this instance and I can't find anything on the forums for this. Any help would be appreciated.
        • Mathematically modifying custom properties
          Josh Brady
          This is a bad idea in general. It sounds handy on the surface, but can only cause problems later on. What happens when you want to make just one of them? The machine shop work order doesn't match the drawing quantity. What happens when you change the quantity of that part in the assembly? You have to issue a revised copy of the part drawing at the same time.

          On the SW side, there really isn't any way to link a part's properties to its quantity in the assembly. This is because a single part/assembly could be used in many different assemblies.
          • Mathematically modifying custom properties
            Eh, Steve! (I'm'a call you Josh),

            I actually read your comments regarding this in another forum and voiced these concerns with my boss. He says he's fine with issuing a revision each time we re-release a drawing with a different quantity (grrr...), probably due to the fact that we have to reprint the drawing anyways because the shop has lost the first one (grrrr again).

            What my actual question was is whether or not it is possible to manipulate the numbers in the custom properties mathematically. I guess it could also be done in the drawing notes, but I don't know whether or not SW can do this.
            • Mathematically modifying custom properties
              Josh Brady
              What do you mean by "mathematically?" Which version of SW are you running?
              • Mathematically modifying custom properties
                I mean, if I have a custom property called "A" and another custom property called "B", can I multiply them together?

                I'm running SW2009 Pro.
                • Mathematically modifying custom properties
                  Charles Culp
                  No, when data is brought into custom properties like this, it is always as text, not as an "integer". I don't believe any math is actually possible, either. I would suggest using an equation, then pulling in the result of that equation any time you need to do math that goes into a custom property. Of course, with item quantities you can't use equations (that I know of?) so you're out of luck there, too.
                  • Mathematically modifying custom properties
                    Aha! At first, it looked like I was going to have to write a macro, but using the SW Equations function (as suggested by Charles) I was able to get it to do what I wanted: multiply two custom properties together. Here's how:

                    1) Create 2 custom properties ("A" and "B"), set both to "Number" type. Assign arbitrary values.
                    2) Go to Tools -> Equations
                    3) Click "Add" to add a new equation.
                    4) By clicking on the double-down arrows, you can find a list of the custom properties.
                    5) Type in "AB" (with quotation marks), click "=", click on the "A" variable listed below, click "*", click "B" variable listed below. The equation line should read:
                    "AB" = "A" * "B"
                    6) Click "OK" You should see your equation with a green checkmark beside it and an "Equates to" column displaying the calculated value.
                    7) Add a new custom property (called "AB"), set the type to "Text" and from the dropdown where it says to input the value, select "AB". It'll put something to the effect of "AB@Part.SLDPRT" into the field and you'll think all is lost, but when you add that field to your drawing as a note ($PRPSHEET:"AB"), you'll find that it displays your answer.

                    Keeping in mind, though, that "A" and "B" have to be manually set (or set through Task Scheduler). I didn't seriously expect to be able to extract the quantity from the assembly, nor would I have wanted to (for reasons pointed out by Josh), but thanks to these forums, I'm on my way again. Thanks, everyone!
                    • Mathematically modifying custom properties
                      Josh Brady
                      OK, here is some freaky stuff. Once again, this is unsupported. However, there is a way using VBA in equations to control a custom property of child components from an assembly. Here are the steps (all in the main assembly):

                      1. Create a non-configuration-specific custom property in the main assembly called "Cfg4Qty". In that property put the name (case-sensitive) of the configuration of the main assembly that you want to use to drive the quantity.
                      2. Create two non-configuration-specific custom properties, one called "code" and the other called "code2". They should be text type properties. Just for now, put the numbers "1" and "2" into them.
                      3. Create the equation:

                      "Dummy" = "code""code2"

                      If you've done this right so far, the value of "Dummy" should be 12.

                      4. Go back to the custom properties. Click in the box for the "code" custom property such that it highlights the "1" that's in there.
                      5. Paste the following code into that property:

                      1
                      Dim myAsy As AssemblyDoc
                      Dim myCmps
                      Dim Cfg As String
                      Dim CmpDoc As ModelDoc2
                      Dim i As Long
                      Dim j As Long
                      Dim cCnt As Long
                      Dim NoUp As Long
                      Dim myCmp As Component2
                      Dim tCmp As Component2
                      dim tm as double
                      tm = timer
                      Set myAsy = Assembly
                      If Assembly.ConfigurationManager.ActiveConfiguration.Name <> Assembly.CustomInfo2("", "Cfg4Qty") Then
                      Assembly.Extension.ShowSmartMessage "Qtys not updated due to config", 1000, True, True
                      Exit Sub
                      End If
                      NoUp = 0
                      myCmps = myAsy.GetComponents(False)
                      For i = 0 To UBound(myCmps)
                      Set myCmp = myCmps(i)
                      If (myCmp.GetSuppression = 3) Or (myCmp.Get

                      Make sure you don't copy any blank lines before or after this code.

                      6. Do the same thing for the "code2" property,using the following code:

                      Suppression = 2) Then
                      cCnt = 0
                      Set CmpDoc = myCmp.GetModelDoc
                      Cfg = myCmp.ReferencedConfiguration
                      For j = 0 To UBound(myCmps)
                      Set tCmp = myCmps(j)
                      If tCmp.GetSuppression <> 0 Then
                      If tCmp.GetModelDoc2 Is CmpDoc Then
                      If tCmp.ReferencedConfiguration = Cfg Then
                      cCnt = cCnt + 1
                      End If
                      End If
                      End If
                      Next j
                      CmpDoc.AddCustomInfo3 Cfg, "AutoQty", 30, ""
                      CmpDoc.AddCustomInfo3 Cfg, "QtyIn", 30, ""
                      CmpDoc.CustomInfo2(Cfg, "AutoQty") = cCnt
                      CmpDoc.CustomInfo2(Cfg, "QtyIn") = Assembly.GetTitle & " Cfg " & Assembly.ConfigurationManager.ActiveConfiguration.Name
                      Else
                      NoUp = NoUp + 1
                      End If
                      Next i
                      Assembly.Extension.ShowSmartMessage NoUp & " Parts not updated due to lightweight (" & timer - tm & "s)", 10000, True, True

                      This will create two config-specific custom properties in every component part file/configuration referenced in the main assembly. The one called "AutoQty" will contain the counted number of parts. The one called "QtyIn" will contain the name of the main assembly and the configuration they are counted in. The AutoQty property will be updated every time the configuration specified in "Cfg4Qty" is rebuilt.
                      • Mathematically modifying custom properties
                        Josh Brady
                        Additional note: Quantities will not be updated for lightweight components!
                          • Mathematically modifying custom properties
                            Josh Brady
                            Attached is a sample assembly that uses this method. Whenever the "Default" configuration of the assembly is rebuilt, the AutoQty and QtyIn properties of the parts are updated. If you change the Cfg4Qty custom property of the assembly to "ConfigWithExtraParts" then the parts will be updated with the quantities from that configuration. I've included a drawing with a BOM just for reference to show how the properties update.

                            Of course, the automatic updating adds time to the rebuild, and it gets more noticeable with large assemblies. You can easily disable the code by un-checking the "active" box for the "Dummy" = "code""code2" equation.
                          • Mathematically modifying custom properties
                            Josh,

                            I'm actually rather surprised that there is a way to write to the custom properties of every component in an assembly. However, it doesn't surprise me that it would tend to bog down one's system. It looks as though the code could be easily enough converted into a macro that one could run on demand which would solve both the problem of long rebuild times and would prevent accidental overwriting of custom properties. You should consider posting it to the API board (along with your warnings of the problems associated with putting quantities on detail drawings).

                            Actually, on that note, I convinced my boss to add a "Verified Quantity" field that we have to initial on each detail drawing. It'll create more tedious paperwork (me and my big mouth), but it should prevent incorrect quantities from being released to the shop floor.
                            • Mathematically modifying custom properties
                              Josh Brady
                              As far as creating a functional macro, all you have to do is put the code together, add the Sub and End Sub part, and declare/initialize the variables swApp and Assembly as noted below. As written it still requires the Cfg4Qty custom property in the main assembly. This prevents the macro from accidentally being run while the wrong config is active.

                              Sub UpdateQtys()
                              Dim swApp as SldWorks.SldWorks 'added this line
                              Dim Assembly as ModelDoc2 'added this line
                              Dim myAsy As AssemblyDoc
                              Dim myCmps
                              Dim Cfg As String
                              Dim CmpDoc As ModelDoc2
                              Dim i As Long
                              Dim j As Long
                              Dim cCnt As Long
                              Dim NoUp As Long
                              Dim myCmp As Component2
                              Dim tCmp As Component2
                              dim tm as double
                              tm = timer
                              Set swApp = Application.Sldworks 'added this line
                              Set Assembly = swApp.ActiveDoc 'added this line
                              Set myAsy = Assembly
                              If Assembly.ConfigurationManager.ActiveConfiguration.Name <> Assembly.CustomInfo2("", "Cfg4Qty") Then
                              Assembly.Extension.ShowSmartMessage "Qtys not updated due to config", 1000, True, True
                              Exit Sub
                              End If
                              NoUp = 0
                              myCmps = myAsy.GetComponents(False)
                              For i = 0 To UBound(myCmps)
                              Set myCmp = myCmps(i)
                              If (myCmp.GetSuppression = 3) Or (myCmp.GetSuppression = 2) Then
                              cCnt = 0
                              Set CmpDoc = myCmp.GetModelDoc
                              Cfg = myCmp.ReferencedConfiguration
                              For j = 0 To UBound(myCmps)
                              Set tCmp = myCmps(j)
                              If tCmp.GetSuppression <> 0 Then
                              If tCmp.GetModelDoc2 Is CmpDoc Then
                              If tCmp.ReferencedConfiguration = Cfg Then
                              cCnt = cCnt + 1
                              End If
                              End If
                              End If
                              Next j
                              CmpDoc.AddCustomInfo3 Cfg, "AutoQty", 30, ""
                              CmpDoc.AddCustomInfo3 Cfg, "QtyIn", 30, ""
                              CmpDoc.CustomInfo2(Cfg, "AutoQty") = cCnt
                              CmpDoc.CustomInfo2(Cfg, "QtyIn") = Assembly.GetTitle & " Cfg " & Assembly.ConfigurationManager.ActiveConfiguration.Name
                              Else
                              NoUp = NoUp + 1
                              End If
                              Next i
                              Assembly.Extension.ShowSmartMessage NoUp & " Parts not updated due to lightweight (" & timer - tm & "s)", 10000, True, True
                              end sub
                              • Mathematically modifying custom properties
                                Josh Brady
                                Yes, it's 2009. It is not possible in 2008. And it's totally not supported either. I'm a bit curious as to how many people at SW know that this technique is possible. VBA in equations has always been possible as long as I can remember. However, it's been limited to what you can do in a single line of valid VBA code. No looping, branching, etc. 2009 introduced the capability of using custom properties in equations. It seems as though one of the first things the equation parser does is go through and replace any custom property name in quotes with the value of that custom property. Somehow this has enabled putting multiple lines of VBA code into a custom property that in turn gets evaluated in VBA. Pretty screwy.
                                  • Re: Mathematically modifying custom properties
                                    Riccardo Mattioli

                                    Hi Josh,

                                     

                                    this macro is absolutely brilliant and I'm going to use it as soon as I undestand this... Why you make it check this:

                                     

                                    If Assembly.ConfigurationManager.ActiveConfiguration.Name <> Assembly.CustomInfo2("", "Cfg4Qty") Then

                                    Assembly.Extension.ShowSmartMessage "Qtys not updated due to config", 1000, True, True

                                    Exit Sub

                                    End If

                                     

                                    Is it possible to GET the active configuration and pass it to Cfg4Qty directly? If yes, how to?

                                     

                                    Regards

                                     

                                    Riccardo