Script Library Updated / Enhanced

COD Script Library was updated for JOB and LIBRARY Scripts. You can download them for free here. Here’s a summary of changes.


Script Consolidation

In the past, there were 69 to 75 COD Scripts to export all the various properties to separate TXT files. Properties that have multiple entries per ITM like Connectors or Seams are still exported to separate files because the data columns don’t line up between them and there are multiple lines per ITM.

All other properties where it’s a single property per ITM like Spool or Material have all been consolidated to a single script and single TXT file. The WriteAllMiscProperties(Job).cod and WriteAllMiscProperties(Library).cod scripts are where you can extract all other properties so no matter what combination of properties you want, there’s less data files to sort through or scripts to run.


Improved Script Properties Display

The properties scripts were displayed script settings before running the script. They still are but additional properties are displayed where appropriate along with some additional properties the scripts now support (both covered later). In addition to the additional items, you’ll note that clicking the No button no longer cancels the script. Instead, clicking No takes you to the Advanced Configuration (also covered later) where you can change some of those settings.


Advanced Configuration – Scan Folder (LIBRARY Scripts Only)

By default, the script looks to the root of your ITM Library folder of your database. This value can now be changed to point anywhere else. You may want to point to a folder of ITM’s outside your Configuration if that’s where you store your ITM’s. You can also scan further down the folder structure so you can perhaps skip exporting Duct ITMs but instead scan and export Piping ITMs.

Here’s what this looks like. Note that the path may use forward slashes ( / ). You can however paste a new path that uses backslashes ( \ ) and it should still work. There’s no option in COD Scripts to allow you to browse to a folder so make sure you type or copy/paste carefully.


Advanced Configuration – Export File (JOB and LIBRARY Scripts)

Similar to the Scan folder configuration, you can now also change the default export file name and location. Specifications for specifying paths are the same as above.

Also note that while you CAN specify “CSV” as the file extension, I recommend using “TXT“. When Excel sees a CSV file, it just opens it without giving you the ability to specify how data is interpreted. Using a “TXT” extension makes Excel prompt you for “How” the file should be read like which character is used as the delimiter or defining which columns are Text vs other data types.

Some numerical data or values can be interpreted incorrectly by Excel if you don’t explicitly tell Excel to treat them like Text. A good example of this is the size 1-1/2″ or 1-1/4″. Excel thinks these are dates and will display them as 1/1/2012 or 1/1/2014 respectively if you don’t explicitly tell Excel to treat them as Text. Using that “TXT” extension on the export file is a safe guard against this issue.

A lot more detail that you likely wanted but hopefully it’s helpful, here’s what that looks like….

Note you may see an extra slash character between the path and file name. This is can happen if your MAP.INI (Edit Configuration Utility) includes or doesn’t include an ending slash. I may add code to clean this up later but COD Scripts and Fabrication seem tolerant of this extra slash so no need to worry about it (or edit it out if you like).


Advanced Configuration – Folder/Path Wildcard (LIBRARY Scripts Only)

Instead of editing the folder you’re going to scan, alternatively you can specify a wildcard to use to limit which folders to export data from. As an example, you could specify *WELDBEND* and properties will only be extracted for ITM’s within folders containing the name “Weldbend”. Wildcard specification is not CaSe SeNsItIvE. By default, the wildcard is ( * ) to extract from all folders. Here’s what that looks like…


Advanced Configuration – File Wildcard (LIBRARY Scripts Only)

Just like the Folder/Path Wildcard specification, you can specify a wildcard for which ITM files to extract properties from. As an example, you could enter *PIPE* and you would export only from ITM files that contained the work “Pipe”. Again, the wildcard is not CaSe SeNsItIvE. You can use both Folder and File wildcards to very narrowly specify your data export scope. Default wildcard is an ( * ) to extract from all ITM files. Here’s what that looks like…


Advanced Configuration – Delimiter (JOB and LIBRARY Scripts)

Data exports by default use a Comma ( , ) to create a Comma Separated Value file. If your Fabrication Database uses commas in folder names or ITM file names this can cause data fields to shift in Excel when opening the export file. If this is the case for you, you can specify a different character to use to separate the data fields in the export file. The Pipe ( | ) character is always a good “rarely used” character for this purpose.

As a side note, it’s not a good practice to have commas in folder or file names. You can read more about that here. This option is really here in case you’re stuck with commas and haven’t fixed them yet.


Advanced Configuration – Max Custom Data Index (Only Scripts that export Custom Data)

Only used for scripts that export Custom Data, you can specify the maximum Custom Index value. Unfortunately, COD scripts have no ability to determine how many custom data entries you have or which index numbers are used without jumping through some hoops. To work around this, you need to specify the maximum Custom Data Index value. The script will then loop through all those numbers and find which ones contain values and remembers them. It then exports only those custom index values so that the script runs efficiency.

By default the script uses 5000 as the maximum index number. But as you can see from the below example, the maximum index number is 10000 so we need to specify that. We look at all 10000 possibilities (it goes fairly quick) and takes note that there’s only 8 indices used and then extracts only those 8 from the ITM’s. In the past, the script would loop through all 10000 for each ITM really slowing things down. Now, even if your largest number is 6 or 7 digits (not recommended) the script will still be fairly quick.

Here’s what that Delimiter Character configuration option looks like…


Summary

In the past, if you didn’t like the export files names, where they went, or wanted to change the scope of which files or folders you extract data from, you could have always changed the COD script code yourself. You now shouldn’t have to. Hopefully this makes running these scripts a little more flexible and user friendly.

Fabrication Job Contains No Parts – Possible Fix?

Have you ever tried importing an MAJ into Revit and received the following error….Fabrication Job Contains No Parts.

There’s a lot of reasons this can occur and it’s NEVER because there are no parts. So much for Autodesk’s QA/QC and Error checking.

You may see this most commonly because parts used in the model contain data that’s no longer in your database. You’ve likely noticed from time to time database entries with curly braces around parts of the name like the following…

This happens when an entry in the database is used by an ITM but the database entry itself later gets deleted. Information is cached within the ITM so when it’s accessed, it creates a Proxy entry in your database if it was missing. Within the {Curley Braces} is the name of the object that created the entry.

While CADmep, ESTmep and CAMduct handle this fairly gracefully, Revit on the other hand does not. When it attempts to load an MAJ, it sees these entries and notices they’re missing from your database and prohibits you from importing the MAJ file. Revit thinks the database doesn’t match the MAJ and stops you cold!

A Possible Fix

If this is cause for the import error, you can use the following COD script to potentially work around the issue….

Take the following script and run in in CADmep, ESTmep or CAMduct. You should be logged in with Administrative Permissions while doing this. This script isn’t fixing Revit or the MAJ. What it’s doing is loading ALL the ITM’s from your Database Library into memory.

The process of loading all these ITM’s into memory creates all these proxy entries in your database. This way, when Revit attempts to import the MAJ, the data associated with those ITM’s are most likely present in your Database configuration. In many cases then results in a successful import of the MAJ.

If the Revit file you are importing the MAJ into already points to a Fabrication Configuration, you should reloaded the configuration FIRST before attempting to import the MAJ.

If for some reason this process still doesn’t work, verify that Revit is reading from the same database location as the version of CADmep, ESTmep or CAMduct where you ran the COD script.

In the event it still doesn’t work, there may be other reasons for the failure but this is often the most common, especially with MAJ’s created recently.

If it does work, you’ll want to use the other scripts I provide on this site to help analyze your database. You likely deleted those database entries in the first place for a reason. You either didn’t realize they were needed, or you didn’t know where they were used to repoint those ITM’s to a proper substitute. Those scripts can help you find which ITM’s use which database entries.

Hope this helps.

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…

Revit Fabrication Parts – Pattern Support Analysis

It no secret that not every Autodesk Fabrication pattern is supported in Revit. I’ve recently finished a more in-depth analysis of which patterns are and are not supported in Revit. Each of the 703 different pattern types were tested in each version and each update of Revit.

On the Fabrication COD Scripts page, you can find a Revit Support Report script. That script will analyse your ITM library and generate a CSV report of the status of every ITM in your Fabrication Configuration.

You can also find the complete results of my testing on the Revit Support page. Here’s a summary of the the testing…


Tested Version

Each of the below versions of Revit were tested with all the the 704 different patterns:

20162016R22061R2SP7
2017.02017.12017.2
2018.02018.12018.22018.3
2019.02019.12019.2

Testing Criteria

“Supported” for purposes of this testing is based on whether Revit allows a particular pattern to be used in the Fabrication Part Browser.


Testing Results

Testing results will have one of the following status descriptions.

  • No – No Revit support
  • Varies ({verison}) – Revit support varies between Revit version
  • Yes (Risk) – Revit does support but use NOT recommended due to issues
  • New ({version}) – New Pattern supported in later Revit versions
  • Yes – Pattern is supported in all Revit versions with no significant issues

Support Status = No

No – Parts not supported by the Parts Browser are obviously listed as having “No” support. There are a total of 84 different patterns listed in this category. They are as follows…

125126127
128129130141158202203
204205206207208209210211212213
215216218220221228230301302308
503505521530764765803804805806
833873910913928960961964966969
974980983985994996999104911021106
1114114211501152115711611162116511681169
1181119411961198218521892190219121922199
2200287331083873

Support Status = Varies

Varies (version) – In some cases, Fabrication Parts were initially allowed or supported in earlier versions and later were restricted. These parts have a status of “Varies” followed by the version where the change occurred. It’s recommended you avoid use of these patterns even in versions where they work as they will not be supported in later versions. There are 17 patterns that once worked in Revit but are no longer supported. They are as follows…

0182222381845853855864876898
903912915971110511701175

Support Status = Yes (Risk)

Yes (Risk) – Patterns that list “Yes (Risk)” are technically supported in Revit but I highly recommend avoiding their use. Patterns with this status have issues like inserting at the Revit’s Project Base Point and not the cursor location. They also have a tendency to crash Revit if you attempt to grip or edit them. As a result, I highly recommend avoiding their use. There are 29 patterns in this category. They are listed here…

119189317346347348349350351352
353368369390392397398415810828
922930962963968973115911601176

Support Status = New

New (version) – Some patterns were not around in earlier versions of Revit but later added and supported in Revit. These patterns are listed as “New” followed by the version of Revit they became available in. These patterns are generally safe to use for Revit. There are 19 patterns in this category which are listed here…

217120612071238123912401241124212431244
124512461247124812491250219721982217

Support Status = Yes

Yes – Parts allowed by the browser that work across all versions of Revit are listed with e “Yes” status. There are 555 patterns in this category. They are listed here…

12345678910
11121314151617181920
21222324252627282930
31323334353637383940
41424344454647484950
51525354555657585960
61626364656667686970
71727374757778798081
82838586878889909192
939596979899100101102103
104105106107108109110111112113
114115116117118120121122123124
132133134135136137139140142147
148149150151152153154155159160
162163165166169170171172173183
184185186231250251252253254255
309311313314315316318319320321
322323324325326327328329330336
338340341342343344345354355356
357358359360365366367376377378
379380382383384385386387388391
393394395399401410411412413417
420421430431440441450451460461
470471472480501502504506507509
514515518519522523524525526533
535555556557580751760761800801
802807808809811812813814815817
818819820821822823824825826827
830831832834835836837838839840
841842843844846847848849850851
852854856857858859860861862863
865866867868869870871872874875
877878879880881882883884885886
887888889890891892893894895896
899900901902904905906907908909
911914916917918919920921923924
925926927929931932933934935936
938939940941942943944945946947
948950951952953954955956957958
959965967970972976977978979981
9849869879889899951000110111041107
1108110911101111111211131115111611171118
1119112011211122112411251126112711281129
1130113111331134113511361137113811391140
1141114311441145114611471148114911511153
1154115511561158116311641166116711711172
1173117411771178117911801183118411851186
1187118811891190119111921193119711991200
1201120212031204120515221972204020412042
2044204720512060207120722082209721082148
2149215521602182218321842186218721882193
2194219521962326238623882522252325242751
2814282128572868286928752881288228832884
2885288628992900290129022903290429052906
2907291629382965296629672979304130513060
30713386352235234522