It’s no secret that here at Razorleaf, we do a lot of DriveWorks implementations. And every implementation is always the start of something larger for our clients. There is no such thing as a completed automation project because you will always want to add new options, new products, new outputs, just adding more and more value. With every implementation being totally different, how can we help our clients to extend their implementations moving forward? Easy, we use intelligent, generic, reusable rules.
Use Generic, Reusable Rules
I can hear your question right now. You’re thinking, “OK, Paul, what in the blazes does that mean?” Fair enough. That does sound like a bunch of business lingo bingo. The bottom line is that if we intelligently plan for what we will want to change or grow, we can use functions in DriveWorks that are completely independent of the specific control or variable or SOLIDWORKS dimension that they are determining. Make these rules smart enough and Ctrl+C then Ctrl+V will be all you need to expand your implementation. So at this point, you’re either very curious or very confused. I’ll try to address both.
First of all, what do we mean by generic? And why do I ask so many questions when I’m supposed to be answering yours?
Well, generic rules and functions mean that they can be used for multiple calculations, without being changed. At the root of most of these is the function MyName(). Ever since invertebrates emerged from the primordial ooze, we have been asking for our DriveWorks rules to know who they are. MyName() will return to us (depending upon the rule context) the name of a variable, a control name AND property, or a component path and parameter. So if I want to control a macro button (look, location, function), I can write a rule that knows that button’s name and whether I’m looking for its top or width or tooltip text.
Well, that’s great, but I often don’t want to know something from MyName(), but rather SomeoneElsesName(). Three more functions exist to make this possible. Indirect() is a function brought over from Microsoft Excel that allows us to get the value of another variable. So if I have the value =DWVariableFlowArea, I could also get that using =Indirect(“DWVariableFlowArea”). Well, that’s pretty silly when it’s a static string, but this allows you to build a string because maybe you don’t know if you’re going to need the flow area or the flow volume or the flow speed. Indirect will allow us to build the name of the variable and return its value.
That is where my favorite function (EVER!) comes to light, Substitute(). We can use Substitute() to replace or remove a portion of a string. So I can use Substitute(MyName(), “.Left”, “.Width”) to change “DimensionImage.Left” into “DimensionImage.Width”. Put that inside of Indirect() and I can have the rule for my left location look for my width, critical if you want to center a control on your form.
And the final link in the chain is ExtractNumber(). If a string contains a number or numbers, ExtractNumber() can return just that number for use in another function. A second parameter exists in ExtractNumber() that allows you to tell the rule to retrieve the 2nd or 3rd (or 8th) number in a string, and with positive or negative, which direction to start counting. This means that ExtractNumber() can be used to parse a value like “Qty of 9 M8-1.25×45” to pull out any value that you like.
So this is where the intelligent planning comes in. Very often, we will want to write a rule that refers to n-1, that is, the variable or control before me. This could be a running total in a BOM or locating controls in a form, for example. Just link all of the components listed above and we can use Indirect() to return
the value of a control that has the “same name that I do”, except (here comes Substitute()) the number in the name (there’s ExtractNumber()) is one less than mine. Here is one of the most frequently used rules in my forms:
ExtractNumber(MyName(), -1) – 1)
ExtractNumber(MyName(), -1) – 1)
Don’t panic. We’ll walk through it.
This rule locates the top of a control based on the location and height of the control before it. The rule simply adds the top location of the previous control plus the height of the previous control plus a gap value.
Here’s how it works. We use indirect() twice, to get the top location value, then the height value. The value is MyName(), which let’s say is Button9, but we replace the number at the end of my name[ExtractNumber(MyName(), -1)]
with the number at the end of my name minus 1[ExtractNumber(MyName(), -1) – 1]
So that lets me (Button9.Top) get the top location value of the button before me (Button8.Top). To that, I’m going to add the height of the button above me. The method is the same, but this time, after we get the string “Button8.Top” the way that we did above, we’re going to use another substitute() to replace “.Top” with “.Height”. So now we have the top of the button before me plus the height of the button before me, which is the bottom of the button before me, and add in a little bit of a gap, and presto-magic, you now have this button tied to the button above.
This gets even more helpful when you realize that doing a COPY/PASTE of a control or variable that ends with a number, will create a new control or variable with the number at the end incremented. And since our rule is completely generic, it will automatically work with the new control. Do you need a field of 60 macro buttons? Just create one with all the right rules, and paste away.
(Note: If you copy/paste controls and they do not update properly, save and reload your project. This will often reset the values and make everything right with the world.)
The rules are longer this way. The rules take a bit of thought until you get used to them. But you only need to write them once and you are done. All our implementations use a group table with settings from fonts to paths to colors and database information. Reusing a single rule allows us to retrieve any setting by just having the name of the setting match the name of the variable. So, get started with utilizing generic rules to make your implementation more flexible and more scalable. And extra credit if you combine it with a calculation table. But that’s another discussion altogether.