COD Scripting Resources Updated

I have updated the Autodesk Fabrication COD Scripting resources. Resources have also been reorganized. Everything is still there but you may have to navigate to it differently.

Most of the updates are additions to the COD Scripting reference. They now include all the information that was in my Advanced Scripting sessions at MEP Force and Autodesk University.

A complete list of all COD Scripting resources can be found here. The COD Language reference is a complete list of all properties, functions, operators, keywords, and anything else scripting that I’m aware of. Everything I know about COD Scripting both documented and undocumented is located here. If you notice properties or functions in COD scripts of yours or from others that is not listed here, please let me know. I’d love to add anything new you find.


Here’s a list of the changes…

COD Script Library – Links Fixed

If you’re attempted to download any of my COD Script libraries over the last couple weeks, you may have found the links were bad.

This should now be corrected. The issue was caused when the site was moved to a new hosting provider. Their newer WordPress setup used a different character set than was originally used when the site was originally setup.

Let me know if you notice any issues. There are still a few character anomalies in other pages and tables that will be fixed as I have time.

COD Script Updates – 2019.11.10

I’ve made a couple updates to the Autodesk Fabrication script libraries. If you use them, you can download updated versions from here.

Scripts Updated

  • Job Items
    • All Scripts updated to now include the Item Number which makes it easier to track back report entries to ITM’s in your job.
    • Fix a couple syntax issues in a few scripts which caused errors.
  • Revit Support Report
    • Added Reporting on Revit 2020 status
    • Changed CID/Pattern # 1175 from NO to YES.

Known Issues

End Location properties appear to be crashing 2020.1 Versions of Fabrication. Other versions may/may not crash as well.

DOS – Still Relevant

Not only is DOS still relevant, its often one of the quickest ways to get some things done.

On XtraCAD.com, someone recently asked how to get the system Date and Time in an Autodesk Fabrication COD script. I provided a solution that uses DOS commands inside a COD script. That solution is explained in more detail here.

DOS’s “Date” Command

Using DOS, we can use the “DATE” command with the “/T” Switch to output the current date to a DOS prompt.

The information given by this simple command is all we need. A script can easily read the data if the output is redirected to a data file.

We’ll get a little more ambitious and get particular on the formatting. We’ll remove the “Tue” and format the date in the format “yyyy.mm.dd”.

To do this, we can use the “FOR” command in DOS.

for /F "tokens=2-4 delims=/- " %A in ('date /T') do echo %C.%A.%B

The Red circled area is the command. It takes the data from the Date command and breaks it apart by the delimiters (DELIMS) which is spaces ( ), forward slashes (/) and dashes (-). You’ll note that the Date doesn’t actually contain any dashes so it’s just ignored.

The TOKENS specifies we want the 2nd thru 4th items of data. They will be assigned sequentially to variables starting with “%A”. The Green circled area is the resulting output ECHO’d to the DOS Window in the format we want.

  • %A = 2nd piece of data (month)
  • %B = 3rd piece of data (day)
  • %C = 4th piece of data (year)

Sending Data to a File

Now that have our DOS command, the next step is to send the output to a file on disk. Doing this will allow the COD script to read it back later.

For this purpose, we use a re-director to pump the data to a file. We simply append a suffix like this…

for /F "tokens=2-4 delims=/- " %A in ('date /T') do echo %C.%A.%B>"C:\Temp\COD Data.Txt"

A few notes about redirecting data to a file….

  1. We use double quotes around the file path and name in case it contains spaces. This way, DOS doesn’t interpret the space as a separator between commands.
  2. The Greater-Than (>) symbol is used to redirect output to a file. If the file already exists, it will be overwritten.
  3. Double Greater-Than (>>) symbols can be used to “append” to the end of an existing file. This is handy if you want to add more data to the same file. If the file doesn’t already exist, it will be created.

We Have DOS, Now for the COD Script

Now that we have our DOS syntax down, we can start writing out COD Script. To start, I typically generate a few variables that help me format things.

REM ------------------------------
REM DQ = Double Quote Character
REM CR = Carriage Return Character
REM ST = Single Tab Character
REM WF = Working File
REM ------------------------------

DIM DQ = ascii(34)
DIM CR = ascii(10)
DIM ST = ascii(9)
DIM WF = "C:\Temp\COD Data.Txt"

Because some of our syntax contains double quotes, and because strings (text) in a COD script also contain double quotes, having multiple double quotes in a row can be confusing. Additionally, sometimes the script has trouble understanding where one string ends vs what’s a string containing a double quote.

To handle this, I set a variable (DQ) that will represent any double quote within a COD Script string. I also use a Carriage Return (CR) variable and a Single Tab (ST) variable for formatting purposes that you’ll see later.

Lastly, I also set a variable for the data file. It’s at the beginning, it’s easy to find and change without having to get in the middle of a lot of confusing formatted string data later.

Executing DOS From the Script

To execute an external command from a script, we can use the EXEC function.

EXEC(<“command”>, <execution mode>, <“command data/arguments”>)

Here’s the 3 pieces of data we’ll need…

  1. <command> = “CMD.EXE”
    This is the DOS Command Interpreter
  2. <execution mode> = exec_wait + exec_show_min
    These are a couple variables that tell the external program to “Wait” until finished before proceeding with the rest of the script and to minimize the Window.
  3. <command/arguments> = The Prior DOS Syntax (with modifications) goes here.

The CMD.EXE program takes an argument of “/C” followed by the command it’s going to execute which is our DOS Syntax. Pay close attention, because here’s where we’re going to have to break up the DOS commands and embed our variables for the embedded double quotes.

The below is a single “String” with double quotes on each end. It also has a lot of double quotes inside the text which will confuse you and your script. This below syntax is WRONG and needs to be corrected….

"/C for /F "tokens=2-4 delims=/- " %A in ('date /T') do echo %C.%A.%B>"C:\Temp\COD Data.Txt""

To do this, it’s easier to illustrate in color. We’re going to take one very long complicated string, and break it into several smaller strings when there’s double quotes within the string.

That is, where ever there’s a double quote within the string, we’re going to make a smaller string before and after, and piece them back together and use our DQ variable to embed the double quote between them.

This works for the first two double quotes. But at the end of the string, we’re going to do something a little different. Here, we want to remove file name and use the WF variable we set earlier to store the file name. And because the filename may have a path, we surround it with DQ variables to embed it in double quotes.

The next piece of code should look like this when we’re done. This will run our DOS command and dump the date to a file,

REM ---------------------
REM Get Date (yyyy.mm.dd)
REM ---------------------

Exec("cmd.exe", exec_wait + exec_show_min, "/C for /F " + DQ + "tokens=2-4 delims=/- " + DQ + " %A in ('date /T') do echo %C.%A.%B>" + DQ + WF + DQ

Reading Our Data File

Now that we’ve dumped the data file to disk, we can read it back in from the COD script using the following code…

DIM myDate
Object myFile as File (WF, forinput+istext)
myDate = myFile.Readline()
myFile.Close()

This code opens the file and reads its data and saves it to a variable. You’ll also note that this code doesn’t add extra double quotes around the WF “Working File” variable. That’s because they aren’t needed here, and will in fact cause problems. The COD Script language is actually better at handling files with and without spaces because it uses a comma (,) as it’s data separator between the file name and file read modes.

Displaying Our Data

Last, we can display the data in a simple debug dialog. Here, you’ll see I make use of the ST variable to place a single tab between the data purely for formatting purposes.

Debug "Date:" + ST + myDate

The Bigger Picture

The following code takes all the above principals and goes a little further. With everything you’ve learned, you should be able to figure out what it’s doing and how. It’s doing all the same things plus a little extra…

  1. Also writing TIME and the USERNAME of the currently logged in Windows User to the data file.
  2. It’s “Appending” the TIME and USERNAME using “>>” instead of “>” that DATE uses.
  3. It’s reading 3 lines of our data file
  4. The data file is deleted after it’s read leaving our system clean of temporary files.
  5. The data is displayed by also using the CR (Carriage Return) variable to start new lines for the additional pieces of data.
REM ------------------------------
REM DQ = Double Quote Character
REM CR = Carriage Return Character
REM ST = Single Tab Character
REM WF = Working File
REM ------------------------------

DIM DQ = ascii(34)
DIM CR = ascii(10)
DIM ST = ascii(9)
DIM WF = "C:\Temp\COD Data.Txt"

REM ---------------------
REM Get Date (yyyy.mm.dd)
REM Get Time (hh:mm)
REM Get User (login name)
REM ---------------------

Exec("cmd.exe", exec_wait + exec_show_min, "/C for /F " + DQ + "tokens=2-4 delims=/- " + DQ + " %A in ('date /T') do echo %C.%A.%B>" + DQ + WF + DQ)
Exec("cmd.exe", exec_wait + exec_show_min, "/C for /F " + DQ + "tokens=1-2 delims=: " + DQ + " %A in ('time /T') do echo %A:%B>>" + DQ + WF + DQ)
Exec("cmd.exe", exec_wait + exec_show_min, "/C echo %username%>>" + DQ + WF + DQ)

REM ---------
REM Read Data
REM ---------

DIM myDate
DIM myTime
DIM myUser

Object myFile as File (WF, forinput+istext)

myDate = myFile.Readline()
myTime = myFile.Readline()
myUser = myFile.Readline()
myFile.Close()

REM ----------------
REM Delete Data File
REM ----------------
Exec("cmd.exe", exec_default + exec_show_min, "/C DEL " + DQ + WF + DQ)

REM ------------
REM Display Data
REM ------------

Debug "Date:" + ST + myDate + CR + "Time:" + ST + mytime + CR + "User:" + ST + myUser

Whole program can be downloaded here…

COD Script Updates – Part 2

I didn’t plan up updating scripts again so soon but I found a couple more undocumented properties. I thought I’d post them sooner rather than later.

The two ITM properties I found are “BOX” and “E-Tag“.

BOX is only visible from CAMduct. It’s intended purpose appears to be for specifying a “Box” for the ITM in question for shipping purposes but you could use it or anything. Despite it being visible only in CAMduct, using COD Scripts, you can read and write it from ESTmep or CADmep too.

E-TAG is visible from any of the Fabrication products. It’s used for Equipment Tags. You can see both properties from here if in CAMduct or only E-Tag is ESTmep or CADmep.

Scripts Updated

  • All Debug Scripts – Nothing major, just formatting in the comments section.
  • WriteAll_Props (Job).cod – Updated to support BOX & E-TAG properties.
  • WriteAll_Props (Library).cod – Updated to support BOX & E-TAG properties.

Scripts Added

  • Debug ITEM Box.cod
  • Debug ITEM E-Tag.cod
  • WriteAllBox (Job).cod
  • WriteAllETag (Job).cod
  • WriteAllBox (Library).cod
  • WriteAllETag (Library).cod

You can download the *current* versions here.

Scripting property reference has also been updated here.

COD Script Updates

I’ve made a couple updates to the Autodesk Fabrication script libraries. If you use them, you can download updated versions from here.

Scripts Updated

  • Debug
    • Debug ITEM Library.cod
    • Debug ITEM Sealant.cod
  • Job Items
    • WriteAllLibrary (Job).cod
    • WriteAllSealant (Job).cod
    • WriteAll_Props (Job).cod
  • Library Items
    • WriteAllLibraries (Library).cod
    • WriteAllSealant (Library).cod
    • WriteAll_Props (Library).cod

Issues Corrected

Issue 1: Scripts accessing the “Library” property were failing on CID/Pattern 2199. Scripts have been updated to watch for this and report it as an ‘Unknown‘ Library.

Issue 2: Some CID/Patterns can be configured to be pipework or duct work depending on the “Pipework” option’s “Yes/No” status. Scripts were updated to properly report or ignore this property depending on the Sealant value being present.

If the option is set to “Yes“, the pattern is a pipework item. If set to “No”, the pattern is a sheet metal item. Sheet metal items contain the “Sealant” property where as Pipework items do not.

This condition is present in the following CID/Patterns…

149838 902110112381239
12401241124212471248

Special thanks to Kyle Speropoulos of MMC Contractors in Kansas City for alerting me to this issue.

COD Scripting References Added

Under the resources menu for Autodesk Fabrication, the COD Scripting section has been updated. This now points to another sub-menu of additional COD Scripting reference information.

The link to the COD scripting libraries has also moved one level deeper so if you have a bookmark and it comes up blank, you many need to re-link it.

I still have more information to add that I’ve not previously documented. These are more advanced functions or other undocumented functions. I’ll post notices as I update them.

You can find the additional COD Scripting information compiled here. Direct links to all the scripting reference information is below…




Autodesk Fabrication COD Script Libraries

Over the years, I’ve written a number of scripts helpful for managing an Autodesk Fabrication configuration. I’ve given them away in my Autodesk University session I’ve taught so they’ve circulated around a bit.

I’ve rewritten most, streamlined them, made enhancements, added others, etc, etc. Because I’m always updating and changing them, I thought I’d host them here too. I can then just post when I update them.

There’s are 2 sets of scripts covering the following topics…

  • Debugging Properties Scripts
  • Job Item Scripts
  • Library Item Scripts

One set is for use in 2019.0 and earlier versions (but work in any version), the others are designed for 2019.1 and later when Autodesk added support for the Pattern Number property.

You can get to the scripts from the menu or click here. The scripts are free to use for all except employees of ENGworks or anyone working on the behalf of ENGworks. (contractors, consultants, etc.) who are prohibited from use.

Defensive Driving for Coders

Disclaimer: I’m not a professional coder. Just a good hack, script kiddie, amateur, whatever you want to call me. But I’ve been doing it for a while and I tend to be good at finding ways to make things less error prone. I also pickup tricks from industry peers who humble me with their ability.

If you aren’t a professional programmer, you’ve likely never been told either. So I’m telling you as its helped me and I’m sure it’ll help you too if you’re an amateur like me. 

This works regardless of language. Whether you code in Visual Basic, AutoLISP, Java, C# or any other language the concepts are the same but the syntax will be different. For this reason, I’ll use pseudo code…that is, syntax that isn’t any particular language but uses terms obvious to describe what’s going on.

The Issue with Strings (Text)

A common activity in any programming is reading text, often called String data types. You read the value from somewhere else like a property or have the user type the data. You then need to test the data in a conditional statement to see if the data is valid. You may also be testing to see which action to take depending on what was typed. 

The problem when doing this is you don’t always know the case used when typing. Most conditional testing on string data is CaSe SeNsItIvE. Take the following examples….

MyValue = "Elephant"
if MyValue = "Elephant" then
MessageBox "Yes - There's an Elephant in the room"
end if

This code works because the case of the text strings is identical. But what about this….


MyValue = "elephant"
if MyValue = "Elephant" then
MessageBox "Yes - There's an Elephant in the room"
end if

In the above code, the test fails because the “E” in “Elephant” is now lower case.  This is very simple to solve and is obvious once it’s pointed out.

To resolve this, when you test a String value, use code to force the value to either UPPER (or lower) case and test against that. Now look at the following code…

MyValue = "Elephant"
if
Upper(MyValue) = "ELEPHANT" then
MessageBox "Yes - There's an Elephant in the room"
end if

  …or this example…. 

MyValue = "Elephant"
if
Lower(MyValue) = "elephant" then
MessageBox "Yes - There's an Elephant in the room"
end if

In either of these examples, we take the value we want to test, force it’s case one way or the other and test against that case. Now it doesn’t matter what case is typed by a user or returned when reading a value, the test is now essentially inoculated from case differences by forcing it one direction or the other. 

A Less Obvious (but related) Tip

Another common mistake I see people do is not use this technique when they know the software better. For example, lets say you wanted to retrieve the type of AutoCAD object and noticed that AutoCAD ALWAYS returns the name in mixed case….”Line”. 

It’s common for less experienced programmers but very smart and observant coders to ignore the tip I just suggested. I’d advise you to NOT do that…always use a forced case when testing text strings. Even when you’re sure the value you are reading and testing is always a particular way.

Why? What happens if…that pesky if…AutoCAD or whatever you are using changes? Autodesk sees a lot of programmers…maybe they overhaul AutoCAD code and object types are now returned upper or lower or a mix? You’ve now put in the hands of someone else if your program will break in the future. As unlikely as it seems, it’ll eventually happen. The key to writing resilient code is tricks like this. Think of it as a coder’s version of “Defensive Driving”. Anticipating future inconsistencies and planning for them makes your code more resilient and less likely to break on your next upgrade.