Archive | CAD Development RSS for this section

Match Icon Check Boxes

Many years ago I created a MicroStation basic macro that would check the boxes of the match element command. At the time, MicroStation J did not save these settings, so every time you used the command you would have to check the boxes for the element attributes you wanted to change. In MicroStation V8i these settings are saved, so you only have to check the boxes one time. The basic macro (before VBA) was really simple and you could record it using the record macro dialog. VBA of course is just as easy – as we will see in a moment.

match01

Do we still need a macro like this one? If you want all options on, or all off then there may still be room in your toolbox for this macro.  It’s easy enough to record the action of checking these boxes (and unchecking the boxes). You can then add these new commands to your MicroStation menus. I like the idea of adding a couple of extra commands in my tasks menu, but adding new icons to the toolbox or pull down menu can work too.

To record the macro, open the VBA Project Manager dialog – Utilities | Macro | Project Manager.

match02

The project manager dialog will open.

match03

Before we record the check boxes we need to start the Match command. You can select the command from the Task menu, or type the keyin “match icon”.

The settings dialog changes to show the Match Element Attribute controls.

match04

To record, highlight the Default VBA and then click the red button in the Project Manager dialog. Check the boxes.

match05

Now, click the stop button (white square) in the Project Manager dialog.

match06

Open the Visual Basic Editor (icon that looks like a dialog box – to the right of the triangle).

match07

The visual basic editor will contain the macro you just recorded. It will look similar to the following.

match08

You can remove all of the Dim statements because these are not used. Remove the second last line too, CommandStatement.StartDefaultCommand. This command will stop the match command and select your default command (usually smart selector). Finally, remove all of the extra lines. The finished macro will look like this.

match09

Repeat these steps but uncheck the boxes. Or, copy and paste Macro1 (change the new sub name to Macro2). Replace the value -1 with 0. This new macro will uncheck all of the boxes.

match10

If you want a different name for a macro, just change the sub name. Instead of Macro1() you could replace that with MatchChkAll() and for Macro2() maybe this could be MatchChkNone().

To run the vba you can use the keyin, vba run Macro1. But, we also want to make sure tha the Match Element Attributes command has been started. So, use the following keyin,

match icon;vba run Macro1

Run this keyin from the keyin browser, add an icon to the Change Attributes toolbox and maybe create a new task. With just a little bit of effort you can optimize your workflows and create a more productive CAD environment.

About Mark Stefanchuk: Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached directly at mstefanchuk@cadmanage.com.

photoDGN Beta

Transparent Dialogs

by Mark Stefanchuk, cadmanage.com

I was playing around with MicroStation preferences the other day and something was bugging me. Turning on/off dialog transparency was clumsy. I know it’s a user preference and that it’s normally on or normally off, but opening the preferences dialog, finding the transparency preference seemed to be more cumbersome than it should be. It was definitely not quick. In this case I just want to switch on/off the dialog transparency without having to go through the steps of opening checking and clicking ok – just to turn transparency on. Call me lazy.

So, to shorten the steps, I used the VBA macro recorder to capture the actions needed to turn on transparency.

To record the macro, open the VBA Project Manager dialog – Utilities | Macro | Project Manager. The project manager dialog will open. Select the Default project in the VBA Project Manager. Click the red circle to start recording.

td01

Go to Workspace | Preferences | Look and Feel. Check the box, “All modeless dialogs use the same transparency”.

td02

Click OK. Click Stop in the VBA Project Manager (the square white button).

td03

I then cleaned up (deleted) all of the extra lines of code that the recorder adds. That is, the lines we don’t need.

This records the steps in your VBA. It creates a new Macro and a Macro Handler (to control the dialog box). The recording process adds a lot of extra code that we don’t need. You can remove the extra code. Your code will look similar to the following when you are done.

Sub Macro1() 'turn on dialog transparency
  Dim modalHandler As New Macro1ModalHandler
  AddModalDialogEventsHandler modalHandler
  CadInputQueue.SendCommand "MDL SILENTLOAD USERPREF"
  RemoveModalDialogEventsHandler modalHandler
End Sub

And the handler will look similar to the following.

Implements IModalDialogEvents
Private Sub IModalDialogEvents_OnDialogClosed _
  (ByVal DialogBoxName As String, _
  ByVal DialogResult As MsdDialogBoxResult)
End Sub
Private Sub IModalDialogEvents_OnDialogOpened _
(ByVal DialogBoxName As String, _
DialogResult As MsdDialogBoxResult)
  If DialogBoxName = "Preferences [untitled]" Then
    '   Set a variable associated with a dialog box
    SetCExpressionValue "savePrefs.addFlags.dialogsUseSameTranparency", 1, "USERPREF"
    '   Remove the following line to let the user close the dialog box.
    DialogResult = msdDialogBoxResultOK
  End If  ' Preferences [untitled]
End Sub

The Macro is saved in Module1 and the handler is saved in the Class Module folder of the VBA. The macro opens the preferences dialog. It also starts and stops the event handler. The handler does the work. It turns on the transparency. All of this is built for you when you record the macro. All you have to do is remove the code that you don’t need.

Next, we want a command to turn off the transparency. Just copy Macro1 and rename it as Macro2. Change Macro1ModalHandler to Macro2ModalHandler.

Sub Macro2() 'turn on dialog transparency
  Dim modalHandler As New Macro2ModalHandler
  AddModalDialogEventsHandler modalHandler
  CadInputQueue.SendCommand "MDL SILENTLOAD USERPREF"
  RemoveModalDialogEventsHandler modalHandler
End Sub

Now, create a new class module called Macro2ModalHandler. Copy the contents of Macro1ModalHandler to this new class module. Finally, in the line that starts with SetCExpressionValue, change the 1 to a 0 (i.e. on to off). Like this.

Private Sub IModalDialogEvents_OnDialogOpened _
(ByVal DialogBoxName As String, _
DialogResult As MsdDialogBoxResult)
  If DialogBoxName = "Preferences [untitled]" Then
    '   Set a variable associated with a dialog box
    SetCExpressionValue "savePrefs.addFlags.dialogsUseSameTranparency", 0, "USERPREF"
    '   Remove the following line to let the user close the dialog box.
    DialogResult = msdDialogBoxResultOK
  End If  ' Preferences [untitled]
End Sub

The last thing we want to do is add these commands to the UI so that we have and easy way to run the commands.To do this I added a new dgnlib to my workspace. I’m using the default untitled workspace, so I added the dgnlib to $(MS)\Workspace\projects\untitled\DGNLIB\. While in the dgnlib, open the Customize dialog box – Workspace | Customize. Add a new toolbox and two new tools. Change the names as shown in the image below.

td04

On the first tool change the Key-in to vba run macro1. This will run the macro that turns off dialog transparency. On the second tool change the Key-in to “vba run macro2”. I’ve also changed the icon. The default tool icon is the wrench. You can select any icon you want. I just took a couple of icons from ustation.rsc (tools I don’t use very often).

Now, right click on the new toolbox name and select “Open Tool Box”.This is what mine looks like.

td05

You can dock this on your MicroStation window. I dock mine at the top so that I can quickly access these buttons. So, now I can control dialog transparency without multiple clicks.

td06

td07

About Mark Stefanchuk: Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached directly at mstefanchuk@cadmanage.com.

photogeoDWG

VBA Custom Configs

by Mark Stefanchuk, cadmanage.com

I’m not really a big fan of increasing the number of MicroStation config variables. Where possible, try to use built in variables. For example, you can use CreateCellElement3

with just the name of the cell as long as the cell library is defined in MS_CELLLIST. You might have something that looks like this in your VB code.

oCell = MainForm.oMSApp.CreateCellElement3(MainForm.uc_o.txtCameraName.Text, Point, True)

This is from a VB.Net example, that’s why the MicroStation Application object is included.

Here’s how I might define MS_CELLLIST for use with photogeoDGN.

CADMANAGE = C:/ProgramData/Cadmanage/PhotogeoDGN/Contents/
MS_ADDINPATH < $(CADMANAGE)Windows/8.11/
MS_CELLLIST < $(CADMANAGE)Resources/*.cel

Sometimes however, it is necessary to identify a special folder or some other resource in your custom program. For example, your program might include a catalog file that provides some engineering data that your program will associate with a cell. You could decide to put this in a resources folder that is always in the install directory. But, a better solution might be to let the end user decide where she wants to save the resource. In this case the resource or file is one that MicroStation doesn’t know anything about, but your program has to be able to find. To fix that we could define the following,

CMRI_CATALOG = $(CADMANAGE)Resources/testcatalog.xml

Put the variable in one of MicroStation’s configuration files, like your UCF. Now, to access the variable from your custom VBA program you need to use ConfigurationVariableValue. Here’s how to do that in VBA.

Sub testConfig()
Debug.Print ActiveWorkspace.ConfigurationVariableValue("CMRI_CATALOG")
End Sub

The example will print the value of the configuration variable in the VBA IDE’s immediate window.

C:\ProgramData\Cadmanage\PhotogeoDGN\Contents\Resources\testcatalog.xml

Use this expansion to open the file, or in this case define your XML document object.

As long as the variable name is different than any other MicroStation config variable, you can use it, but I would recommend  including a prefix. In the previous example, I used CMRI (for CAD Management Resources, Inc). This just helps to avoid variable conflicts.

About Mark Stefanchuk: Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached directly at mstefanchuk@cadmanage.com.

photogeoDWG

photoDGN Beta

Upgrade or Re-write and Tech Manager Overload

by Mark Stefanchuk, CADmanage.com

I have been working with an old MDL application that needs to be upgraded from MicroStation version 8.5 to the latest release. Ideally, I might want to re-write this app using the latest development tools so I can take advantage of the latest IDE, more easily integrate with supporting systems, and better support future maintenance efforts. As a technology manager however, there are other things to consider like training, testing, and deployment. If I keep the application within the MDL framework I eliminate end user re-training. This means the users are up and running as soon as you deliver the updated application. Testing and deployment issues on the other hand will still exist. But, if I just update the MDL I can keep the deployment the same and focus the testing on only the features that have been changed or fixed. I might also add some regression testing to check for the unexpected.  The result though, is less time spent and users are up and running sooner than later.

So, when would I re-write? If I have a choice and the technology doesn’t force the re-write then it would happen after I have satisfied the basic end user workflow with an upgrade. This assumes of course that I have the bandwidth on my team to support the re-write effort. Which leads me to another issue – tech manager overload.

Many of us work on our own, we don’t have a team. We develop, train, support, and configure. And, often we’re expected to design too! There’s no time during the work week to do the things that will make you a better technology manager, or make your CAD system perform better. To that I say, then you need help. And typically I get back, yes, but I’m not going to get it.

Really? Some of you will never be convinced, but for those who might I have a recommendation. Document all of the things you do on a day-to-day basis, and even those things you do weekly, monthly, or only a few times per year. Put time estimates to each of these tasks and account for where your time is spent during the week. You will see immediately if you have too much work to do. You will likely identify things you do that should be done by someone else, and things that simply aren’t important. Share this with your boss.

I can’t tell you how many times I’ve had the boss of a tech manager say they had no idea that he/she was doing that much work. But, I work hard, everyone says so. Sure, but they think they work hard too, and frankly they don’t really care until they don’t get what they want. That sounds harsh, but it’s human nature. The reality is that they don’t know how much you have to do for them. This includes your boss.

There are a number of reasons workload increases. One of the main causes is that we agree to take on tasks and responsibilities that add to that daily workload without any oversight or governance. We never ask if the new feature, process, or technology being requested adding value to our business or is it just a nice to have? And, we don’t look at how the new technology will impact our workload. We never, or rarely say no. We just do it, because for some reason we just assume we’re suppose to, it makes us feel good to help, be the hero, or worse, we assume someone else is keeping track of how much work we’re doing. I can assure you, if you aren’t telling anyone, no one knows.

It’s up to you to keep track and apply some system oversight. You’re the technology manager – ask why implementing the users request is important and have a good understanding of how it will impact your workload. Don’t just do it. Have a plan to support and maintain the request even if it seems small. And, share with your boss. Some bosses are just bad bosses – get a new job. But, most are reasonable and will get you the resources you need to effectively support your end users. They can only do that if they have visibility into your workload. Show them how much you are expected to do and you will get help.


About Mark Stefanchuk:
 Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached by contacting us at info@cadmanage.com.

Managing Usability

by Mark Stefanchuk, CADmanage.com

[Update: Be sure to check out Kim’s comment – a great alternative using the F1 key and choose none. Thanks Kim!]

I’ve been debating whether or not to share this with my MicroStation peeps. I hesitate because I don’t like to admit that sometimes I don’t adjust to change as quickly as I should, but also because this example has some conflict with features in MicroStation V8i that we wouldn’t introduce normally, especially if we don’t have to. What am I talking about?

Earlier this year I was working with a client helping them upgrade from MicroStation 2004 to V8i SS2. Not as big of a jump from V7 to V8, but big enough. Things were missing and commands didn’t work the same way. Years ago we could rely on commands that were in the previous version to work the same way in the new version. Today, it’s not that way. And seriously, there are good reasons for change, like productivity gains. I’m all for that. In this case however, it was clear that the user base missed some of the key operations that made MicroStation, well MicroStation and not AutoCAD.

For example, in older versions of MicroStation when you were done with a selection created using power selector you would use the right mouse button to deselect (reset). In V8i you just use the right mouse button (a datapoint in the view). That’s seems pretty easy. But if you have been drafting for years using the same workflow not being able to use something so simple as the reset button to deselect a selection set can be really frustrating.

Now, I was the consultant and I really wanted my client to be happy so I fixed it. I built an MDL application that would watch for reset. When the user clicks reset any active selection set would be removed. The command is very primitive, but I thought I would share in case you might have a similar issue. There’s not much to it – comments below.

#include    <mdl.h> 
#include    <tcb.h> 
#include    <dlogitem.h> 
#include    <dlogids.h> 
#include    <rscdefs.h> 
#include    <mdlerrs.h> 
#include    <userfnc.h> 
#include    <global.h> 
#include    <mselems.h> 
#include    <accudraw.h> 
#include    <cexpr.h> 
#include    <math.h> 
#include    <string.h>

#include    "ps_resetcmd.h" 
#include    "ps_reset.h" 
#include    "fdf.fdf"

int goFlag; // a flag to watch for active commands that might conflict
// the event watcher
Private int monitorQueue ( Inputq_element *queueElementP ) 
{     
    char sCmd[256];         
    sprintf(sCmd, "%S", mdlState_getCurrentCommandName());     

    // Element Selection Active     
    if (strcmp(sCmd, "Element Selection") == 0)
    {
        goFlag = 0;  
    }

    // a quick a dirty way to watch for active command - be careful with upgrades because this might not be
    // supported in the future. - not very elegant but it works - I'm a little bull headed that way.
    if ((strcmp(sCmd, "Dimension Element") == 0) || (strcmp(sCmd, "Dimension Linear Size") == 0) 
        ||   (strcmp(sCmd, "Dimension Angle Size") == 0) || (strcmp(sCmd, "Dimension Ordinates") == 0) 
        ||   (strcmp(sCmd, "Change Dimension") == 0) ||   (strcmp(sCmd, "Drop Dimension Element") == 0)
        ||   (strcmp(sCmd, "Dimension Size Perpendicular to Points") == 0) ||   (strcmp(sCmd, "Dimension Diameter") == 0) 
        ||   (strcmp(sCmd, "Label Point Coordinate") == 0) || (strcmp(sCmd, "Dimension Symmetric") == 0) 
        ||   (strcmp(sCmd, "Dimension Half") == 0) || (strcmp(sCmd, "Dimension Chamfer Angle") == 0) 
        ||   (strcmp(sCmd, "Dimension Diameter Perpendicular") == 0) || (strcmp(sCmd, "Dimension Radius (Extended Leader)") == 0) 
        ||   (strcmp(sCmd, "Place Center Mark") == 0) || (strcmp(sCmd, "Dimension Radius") == 0) 
        ||   (strcmp(sCmd, "Dimension Arc Distance") == 0))  
    {   
        goFlag = 1; // the active command is a dim command so dont deselect on reset
    }  
    else  
    {   
       goFlag = 0; // ok to reset - conflict mitigated  
    }    

    // user clicked reset and conflict minimized so go for it
    if (queueElementP->hdr.cmdtype == RESET)  
    {   
        if (goFlag == 0)    
            mdlInput_sendKeyin ("powerselector deselect", 0, 0, NULL);
    }
    return INPUT_ACCEPT;
}

// command entry
int main () 
{     
    RscFileHandle   rfHandle;  
    goFlag = 0;

    mdlResource_openFile (&rfHandle, NULL, FALSE);

    if (mdlParse_loadCommandTable (NULL) == NULL)  
        mdlOutput_rscPrintf (MSG_ERROR, NULL, 0, 4);

    mdlInput_setMonitorFunction (MONITOR_ALL, monitorQueue);
    return  SUCCESS; 
}

The conflict was created by sending a command, i.e. powerselector deselect, when commands that you didn’t want to terminate using reset were active – like dimension commands. The easiest way to work around this was to set a flag. If one of the dimension commands is active then don’t deselect on reset. The code and compiled ps_reset.ma is on cadmanage.com/cadgurus. Put the ma in your mdlapps folder so it will load when MicroStation is loaded. You can also use the keyin mdl load ps_reset to load this app.

About Mark Stefanchuk: Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached by contacting us at info@cadmanage.com.

CAD Management – Resource Style

by Mark Stefanchuk, CADmanage.com

Seth and I have been a somewhat focused on resources lately, but for good reason. Things like layers, blocks, and styles (lines, dimensions, tables) are assets that are created and recreated from project to project and it seems like this is a bit of extra work.

Of course we can use templates and standards, but there always seems to be a page setup or table style missing – one that we created for a project we were working on just last week. And boy wouldn’t it be great if I could get all of those things with a quick click.

The import of many of these assets is pretty straight forward code wise, so I’m going to “give away the store” (or just a small portion of the store) and show you how you can do this yourself. I’ll then introduce you to our next Exchange App that we expect will be ready by the end of November.

In this example I’m going to show you how to get text styles from an external DWT, DWS, or DWG file (the sourceDb) and bring these into the current DWG (the destDb). We will use VB.Net. Here’s the code listing. Comments embedded.

'use the following: 
Imports Autodesk.AutoCAD.Runtime 
Imports Autodesk.AutoCAD.ApplicationServices 
Imports CADAPP = Autodesk.AutoCAD.ApplicationServices.Application 
Imports Autodesk.AutoCAD.DatabaseServices 
Imports Autodesk.AutoCAD.EditorInput 

'string library_path => the file spec of the source dwt, dws, or dwg file 
'DuplicateRecordCloning clg => Replace or Ignore - how to handle text styles with the same name 
Private Sub cmr_getTextStyles(ByVal library_path As String, ByVal clg As DuplicateRecordCloning)
'connect to current database
Dim dm As DocumentCollection = CADAPP.DocumentManager
Dim doc As Document = dm.MdiActiveDocument
Dim ed As Editor = dm.MdiActiveDocument.Editor
Dim destDb As Database = dm.MdiActiveDocument.Database
Dim sourceDb As Database = New Database(False, True)

Try
    Using dl As DocumentLock = doc.LockDocument()
    'connect to the external dwt, dws, or dwg
    sourceDb.ReadDwgFile(library_path, System.IO.FileShare.Read, True, "")

    'create a container for our text styles
    Dim textsToClone As ObjectIdCollection = New ObjectIdCollection()
    Dim tm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = sourceDb.TransactionManager

    'start a transaction with the external drawing
    Using tr As Transaction = tm.StartTransaction()

        'get the text style ids
        Dim ldt As TextStyleTable = TryCast(tm.GetObject(sourceDb.TextStyleTableId, _
            OpenMode.ForRead, False), TextStyleTable)

        'save the ids in an object collection
        For Each txtID As ObjectId In ldt
            textsToClone.Add(txtID)
        Next

        ' Add text styles to the current drawing
        Dim mapping As IdMapping = New IdMapping()
        sourceDb.WblockCloneObjects(textsToClone, destDb.TextStyleTableId, mapping, clg, False)
        'commit the sourceDb transaction (even for read)
        tr.Commit()
    End Using
End Using
Catch ex As Autodesk.AutoCAD.Runtime.Exception
'
End Try
End Sub

You can use this same pattern for dimension styles, multi-leader styles, table styles, line types, and page sets. Layers, and blocks are similar but require some extra effort.

So, what about that next app? Seth and I have been working on a new app for Autodesk Exchange and expect to have it published shortly. So, if you don’t want to tackle importing resources yourself then you can download our version. DWG Resource Importer consolidates these operations into a convenient palette allowing you to quickly import resources from templates, standard files, and drawing files. Here’s what you can expect to see.

Select the resources to import – layers, blocks, line styles, dimension, and more…

Import the resources and if you want to refer back to the report later you can save it.

There’s no reason anyone on your team should have to recreate resources from project to project. Whether you develop your own import palette or use one like DWG Resource Importer your team will save production hours.

About Mark Stefanchuk: Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached by contacting us at info@cadmanage.com.

Multiple Resources (AutoCAD)

by Mark Stefanchuk, CADmanage.com

Seth’s last blog, Resources Resources…, was great! In particular this bit of information really caught my attention.

The Files tab lists the folders that AutoCAD will use to search for resource files (a.k.a. Support Paths), drivers, CUI files, tool palettes, and so on.  There are also user-defined settings such as the  dictionary file used for checking spelling.  Paths are searched in the order that they are listed in the Options dialog box, and if the same file exists in different folders, the first instance found is used.

Ok, so that got me thinking. How do I know if there is more than one file with the same name in my paths folders and is the file I want loaded in the right place? My first thought was to just look in each folder and see if there are duplicates. But, turns out there are a lot of files in these folders. I’m going to need a better way. I could write a vb script to look in each support folder and compare all of the files dumping the results to some output file, but I kind of want to be able to debug my profile folders when I’m in AutoCAD. To do that we will need a different approach.

I decided to build a plug-in. If you’re not familiar with .Net plugins for AutoCAD check out Autodesks “My First Plug-in” tutorials. Really well done. You don’t need the wizard, and you can find the AutoCAD references in the AutoCAD program files folder. There are a lot of on-line tutorials for VB.Net or C# – either programming language can be used to create an AutoCAD plugin. I’ll let you do your own googling to find what you need.

Here are some pointers for getting the support file information from AutoCAD. We will start by just figuring out what our support files are.

Your class will need to reference and Import the following:

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Interop

In your class you will need a new command to show the support paths.

<CommandMethod("SHOWSP")> _
Public Shared Sub ShowSupPaths()
    Dim acadApp As AcadApplication = Application.AcadApplication
    MsgBox(acadApp.Preferences.Files.SupportPath)
End Sub

Compile this to create a dll that you can netload (just like in the plug-in tutorials). After you netload you can use the command SHOWSP which will display a message box similar to this one.

It’s not very pretty and you can find the same information using the built in OP (options) command. So, what we really want is to get a list of file names from each folder and then compare them to one another to see if they show up more than once. What can we do? The first thing to notice is that the support paths are separated by a semi-colon. That gives us a way to “split” the string into an array of folders. We can then use System.IO to get directory info which we can use to list the file names. Something like this…

Dim sPaths() As String
sPaths = acadApp.Preferences.Files.SupportPath.Split(";")
For Each s As String In sPaths
    Dim di As DirectoryInfo = New DirectoryInfo(s + "\")
    For Each f As FileInfo In di.GetFiles()
        lstFiles.Items.Add(f.Name)
    Next
Next

In this example I have added the file names to a list box. You can loop through the list items to check for duplicates and output to another list box. I took it a step further and built a Palette. In the top panel I added a tree view so that I have a way to step though the folders and files. In the bottom panel I list the files that show up more than once.

I also added a double click feature to open a window and select the file in the folder it resides in so that I have a quick way to compare files. Finally, I decided to add an extension filter so that I can debug just cuix, or lsp files.

We’re looking into posting this on the Autodesk Exchange. So, if you don’t want to dig deeper and try to write it yourself I hope to have this submitted and available in the next few weeks.

About Mark Stefanchuk: Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached by contacting us at info@cadmanage.com.

Reference Files and XRef Paths

by Mark Stefanchuk, CADmanage.com

I was looking through some old emails recently and found this questions from Adrian. “How do I get the reference file path of a reference file?”

Why would you need the path? Good question. You might want to audit projects to make sure users are using standard naming conventions. You may need to include reference file names and paths in the border for cross referencing. Or, maybe, as is the case with MicroStation you want to know if the file is located in the project path or if it’s coming from another folder – another project or a common files folder like you might have for standard borders.

So, how do we do it? Well, you could open the reference dialog and hover your mouse over the file name until the pop-up window shows you the file specification, or you can write a small app.

In MicroStation we get the reference file path and file name using the designfile object with fullname. In this example, I’m just sending the name to the immediate window.

Sub reftest()
    Dim att As Attachment
    For Each att In ActiveModelReference.Attachments
        Debug.Print att.DesignFile.FullName
    Next
End Sub

AutoCAD looks a little different, because we have to search the list of blocks in the file and filter out the ones that are XREFS.

Sub xreftest()
    Dim oBlk As AcadBlock
    For Each oBlk In ThisDrawing.Blocks
        If oBlk.IsXRef Then
            Debug.Print oBlk.Path
        End If
    Next
End Sub

Printing to the immediate window is a quick and easy solution for you, but if you want your users to be able to cut and paste give them a list box or dump the results to at text file.

A listbox approach might look like this.

And the code for this is essentially the same, except you put the for each into the userform_initialize event and add items to the listbox instead of printing it to the immediate window.

 Load frmRefList
 frmRefList.Show
 frmRefList.lstXRefs.Clear
 Dim att As Attachment
 For Each att In ActiveModelReference.Attachments
    frmRefList.lstXRefs.AddItem att.DesignFile.FullName
 Next

Finally, if you want your users to be able to copy the list to the clipboard then you will have to provide a copy button because CTRL-C does not work on the list contents. This example shows you how to use a DataObject to copy the list. Put the code into a button click event and you’ll be good to go.

 Dim s As String, i As Integer, oData As DataObject
 For i = 0 To Me.lstXRefs.ListCount - 1
    If Len(Trim(Me.lstXRefs.List(i))) > 0 Then
        s = s + Trim(Me.lstXRefs.List(i)) + vbCrLf
    End If
 Next i
 Set oData = New DataObject
 oData.Clear
 oData.SetText Trim(s)
 oData.PutInClipboard

Code download is available on our CADgurus page.

About Mark Stefanchuk: Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached by contacting us at info@cadmanage.com.

Experiences in CAD Management – System Performance

by Mark Stefanchuk, CADmanage.com

I was thinking about all of the things a CAD Manager does and decided to start a list. It was very long. At the highest level the list is typically support, training, and development – a very basic IT management framework. That is, get feedback from support and address systemic issues first with training and if necessary with development. Of course, the details of the day to day activities of a CAD Manager paint a much more complex picture. The CAD Manager doesn’t just have to know how to reset passwords. The CAD Manager also has to be able to peel back the layers of the CAD system one by one to  separate the relevant from the irrelevant. CAD support might appear to be as simple as demonstrating feature function, but more often it requires traversing multiple integrated systems.

A few years back I had a situation where several users were seeing really poor performance, but only when working in a CAD drawing. Basic drawing commands – lines, circles, boxes and text were really slow. Everyone had the same software, the same computer, the same OS, but only a handful of users were seeing performance degradation. What gives?

In large corporations there are large IT teams and on occasion they can be a challenge to work with. Their requests can seem ridiculous at times, but usually these requests or “push-backs” are opportunities to eliminate a suspected root cause. In this case, our IT partners were skeptical and told us that we were imagining the performance issue. Ok. A simple timing script resolved that. I created a macro to place objects into a drawing. Pretty simple really – time stamp before and after and take the difference between the two. In VBA use the timer function. The output will be in seconds.

Dim t1 as Single, t2 as Single
t1 = Timer()
‘ do lots of stuff
‘ ...
t2 = Timer()
Debug.Print Str(t2-t1)

Test some stuff, but be sure that your macro tests remote resources not just local desktop operations. Open a file, or place a block (or cell) that resides on a server. If you want to run a file open test, run it from a VBS.

' VBS - open and close a MicroStation Files
dim t1, t2, msApp
t1 = Timer()
Set msApp = CreateObject("MicroStation.Application")
msApp.visible = 1
msApp.mbeSendCommand ("rd=C:\tmp\test.dgn")
msApp.quit
t2=Timer()
'--- CREATE AN OUTPUT FILE SO THAT WE KNOW IT IS EMPTY
Set tfo = CreateObject("Scripting.FileSystemObject")
Set tf = tfo.CreateTextFile("c:\tmp\tout.txt", True)
tf.WriteLine(" TIME FOR FILE OPEN AND CLOSE: ")
tf.WriteLine(t2-t1)
tf.close

The test did the job. We were able to prove that performance was bad on these select machines. Still no root cause, but we proved the problem existed. The next “push-back” – well it must be the CAD software. Hmm. I thought I had done enough, but I went ahead and stepped through my checklist (working inside out) – drawings same problem with a new/different drawings so it can’t be drawing file specific, data connections not applicable, CAD application versions and settings are the same, CAD engine configurations the same. There weren’t any differences related to the CAD environment.

Volley back to IT. At this point I had the evidence to demonstrate that the problem wasn’t due to the CAD environment. This meant that our IT partners now had to take a closer look at the differences in the desktop programs and utilities that they managed. This included many things including network, terminal windows, OS system and patches. Network diagnostics checked out, OS system and patches ok, anti-virus software was the same, but… there was a difference. Turns out the AVS settings were not the same. On the computers with the problem the check box to scan remote computers was checked. Every time the CAD program grabbed a file or resource from the server it was being scanned.

A systematic analysis of each component of our design automation platform eventually found the root cause. And, in this case the resolution was relatively simple. That is, turn off remote detection. No need for redundant scans of internally managed servers.

About Mark Stefanchuk: Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached by contacting us at info@cadmanage.com.

Information to Help You Better Manage Your CAD Environment

by Mark Stefanchuk, CADmanage.com

Information is the key. Without it we can’t analyze and resolve issues, or win funding for new initiatives. As a CAD Manager, one of the toughest things I had to do was present and support the business case for moving projects forward. It required formulating data in a way that each stake holder could understand. Often that was a monetary presentation other times it was technical. We need information that can help us to understand overall operations, as well as detailed data about each workstation. With information readily available we will have much better control of the CAD ecosystem and a better argument when we have to reach out to our boss for funding. Here are five things, pieces of information, that can help you manage your CAD environment.

Computer Names

Capture computer names to support automated deployments. If you have a small footprint this is easy enough to manage and you probably aren’t doing automated deployments – but can offer you insights when combined with other data. In larger environments, especially those with self service request centers knowing who has what software isn’t always that easy. Even if you have a small pool of licenses your installed base could be much larger. Automating license capture is necessary and can help you with the next deployment.

User Names

In addition to providing very granular usage stats, user names can also provide data on asset usage – shared and individual. Tracking user names per computer name can tell you how effectively you are using your hardware assets. And you may find there are opportunities to consolidate resources or in some cases pro-actively address maintenance issues for shared resources. You can extend usage monitoring to just about any asset including software. In large environments software deployment, including CAD software is often managed by a centralized IT department. In this scenario CAD Managers will quickly lose track of who has and is using critical software assets.

How can we capture username and computer name? In a small environment (say fewer than 10) you can just survey the team and catalog the data manually. In larger environments you will want to use automation to capture this data. A quick and easy way to do this is to add some code to your start up script or program. In VBA you can use the following…

   Dim sComp as String, sUser as String
   sComp = $Environ(“computername”)
   sUser = $Environ(“username”)

And a quick way to save this data is to just append it to a log file using the open and print statements. Check http:\\en.wikibooks.org\wiki\Visual_Basic\Files for details on writing text files. Of course a more sophisticated approach would be to use a SQL database or some other data system that you can query and report.

Version Audit

Going a step further in your intelligence gathering you might also consider capturing version dates on first tier software. These include your business critical applications – that is MicroStation, AutoCAD, Civil3D, and so on.  Version audits can help to avert support issues. For example, incompatible plug-ins.

In both MicroStation and AutoCAD VBA this is easy – it’s just a simple call to the application object.

Application.Version

 

In addition to analyzing support issues, version audits can also help with funding – as is the case with Adobe applications where each version counts as a license instance. In larger environments with self service software requests I’ve seen incorrect versions deployed and version audits can help identify workstations that need to be upgraded. For those of you working for a consulting shop, it’s not unusual to be running multiple versions because in these situations we tend to upgrade as users finish one project and are just starting a new project. So in this case we can use version audits to avoid potential production losses.

In smaller environments versions and software deployments are more easily managed, but if you’re managing a reasonably sized CAD ecosystem computer names, user names, and versions can provide better feedback from your CAD environment. And there are many other things you might want to consider tracking – hardware form factors, plotter usage, and user profiles – each provides valuable information and combined they can inform upgrade schedules, refresh strategy, and software management policies. I’ll investigate these more in future posts, but for now experiment with user, computer, and versions, and let me know what else you might want to track.

About Mark Stefanchuk: Mark is a VP and senior consultant with CAD Management Resources, Inc. He divides his time between developing innovative custom software solutions and helping clients navigate complex design automation environments. If you would like to find out how he can assist you with your design technology he can be reached by contacting us at info@cadmanage.com.