Common causes for AutoCAD® freezing

How many times have you been working in AutoCAD®, and then suddenly it freezes on you? Panic sets in, as you try to remember the last time you saved… You wait… and wait… and… thankfully AutoCAD® un-freezes, this time…

But what actually is the cause of AutoCAD® freezing? It depends – there are many potential reasons for AutoCAD® freezing, but some can be avoided completely with a little understanding of what’s actually happening.

Selections

The first and most obvious reason for AutoCAD® freezing is when we do things to a very large selection. What can sometimes be unexpected is when AutoCAD® freezes when we have merely selected the objects without doing anything to them. This can sometimes leave us gazing at an hourglass thinking “I didn’t ask you to do anything! Why are you freezing on me!?”. Odd as this may seem, there is a reason for it.

When a selection is made, any on screen information that relates to your active selection needs to be updated; otherwise you’ll be working from incorrect information. So, if for example you have the properties window on your screen anywhere, even if it is docked with the auto-hide feature enabled, all the data in the properties window needs to be updated with correct information. The time that this takes is proportional with the amount of things selected, so you can see that simply selecting objects can be the cause of AutoCAD® freezing.

There are ways of working that allow us to drastically reduce the frequency of AutoCAD® freezing when working with a large selection. Make sure you select commands before you make a selection. This sends a clearer instruction to AutoCAD®, and it is dealt with more quickly than if we make the selection first. By selecting first you’re saying to AutoCAD® “Here are some entities that I am interested in – prepare them for me to use in any way”. This is vague, so AutoCAD® has to prepare for anything. However by invoking the command first and making a selection afterwards you’re saying “I only care about performing this action – these are the entities I want to perform it on”. This instruction is much clearer and skips out a lot that we’re not interested in. An extension of this is to get out of the habit of using the Delete key for erasing entities. Yes, it works. But again, picking the erase command first and then the entities sends a clearer message with a very noticeable difference in performance when working with large selections.

Commands

There are a few commands that more commonly cause AutoCAD® to freeze than others. Hatching is one of the main ones, but again, a little know-how can avoid this. A lot of people routinely use the pick-points option for defining a hatch boundary. I personally always try to draw in a way that makes hatching easy. For example, where possible I use closed polylines instead of lines. This allows me to then hatch later by selecting a boundary, eliminating the need to pick points, potentially making AutoCAD® hang. Take a look at my post on the RECTANG command to see what I mean.

When working in 3D, you might be tempted to avoid the 3DORBIT command completely in favour of the SHIFT+MOUSEWHEEL, but there is a reason you should generally use the 3DO command instead. AutoCAD® needs to prepare for 3D orbitting, and if you’re planning on manipulating the drawing a bit, you only want to make AutoCAD® hang for this preparation once. If you use the SHIFT+MOUSEWHEEL method, you’ll make AutoCAD® prepare for 3D orbitting each time you use it, which can be very time consuming on larger drawings. So for very small drawings, its fine to use SHIFT+MOUSEWHEEL, but for everything else use 3DO.

Networked Working

Working on drawings that are saved on some external network has been known to suffer performance issues. Try where possible to work locally, but only where doing so does not undermine whatever document management system you have in place (you do have a structured and coherent document management system.. don’t you??).

Bugs

One particularly prolific bug that I’ve had problems with is the Scale List Bug. Click here to view the solution.

When AutoCAD® Freezes or Hangs…

Wait!!! Do not mash the keys – however tempting that may be! Doing so will only make it take longer. Try to be patient. After a minute or so, you could try a few taps on the Escape key – sometimes you can cancel the command and regain control. After a few mins longer you may want to weigh up whether or not it is worth trying to regain control at all. Is the amount of work you have done since the last save worth rescuing? That will depend on how much work you did. Often, the bulk of the work is the thought processes that went into whatever you did in AutoCAD® – this work has still been done, and you can redo the actual AutoCAD® input quite quickly. If you choose to kill AutoCAD®, you might want to know this useful keyboard shortcut – Ctrl + Shift + Escape, which brings up the task manager.

I will be updating this list in the future so you may want to revisit this post in the future. If you haven’t already, please do subscribe to howtoautocad.com. It is really simple to do – just fill out your email address below, and all you get is an email whenever I post new content. So, it can only be useful to you, and you have nothing to lose 🙂

Will

Excel and AutoCAD® – A match made in heaven (again!)

Many people are oblivious to the wondrous things that can be achieved with programming. If you cringe at the prospect of writing code, I’ll put this to you now – I cringe at the thought of having to do things manually. Often (and yes, I mean often), I’ll write a little 6 line bit of code that saves me hours of work. Yes, HOURS – perhaps even days. Why people avoid learning this stuff is beyond me, because it really isn’t as hard as it looks.

Today I’m going to explain how you can write code in Microsoft Excel VBA that controls AutoCAD®. Firstly, let’s get VBA open in Microsoft Excel. With Excel open, press Alt+F11, which should open the VBA IDE (integrated development environment). If this doesn’t work, you can open this by going Tools>Macro>Visual Basic Editor. If you’re using Excel 2007+, you might struggle to find the option. You have to firstly go into Excel Options and check the box to show the Developer Tab on the ribbon interface.

So we’re now in a position to write a bit of code. On the left (or perhaps on your right depending on your PC), there should be a section called the Project Explorer. In here you should have a few things called Sheet1, Sheet2, Sheet3 and one called ThisWorkbook. Right click in this area and select Add Module. This will create an area for us to write our code, and if you’re feeling adventurous you can rename the module to whatever you like. Double click the module to edit it.

Now let’s see if we can get AutoCAD® to do something.

If you’ve done any programming before, you will know that you can have variables, and variables can have different types. These types can be simple, or can be more complex things known as objects. AutoCAD® has its own type library containing all the object types that we are likely to need. This is very useful to load into our application. To do this, go to Tools>References in the VBA window, and look for an option called AutoCAD® 2010 Type Library, or whatever version of AutoCAD® you are using. This has now made available some extra types that weren’t available before.

Now for some basic code! Put this code into the module, and press the run button at the top of the VBA editor. The subroutine name “Main” is unimportant – we could call this anything we like.

Sub Main()
    Dim ACAD As AcadApplication 'Create ACAD variable of type AcadApplication
    Set ACAD = New AcadApplication 'Set the ACAD variable to equal a new instance of AutoCAD
    ACAD.Visible = True 'Once loaded, set AutoCAD® to be visible
    ACAD.ActiveDocument.Utility.Prompt "Hello from Excel!" 'Print a message to the AutoCAD® command line
End Sub


Here we’ve created a new instance of AutoCAD®, and stored a handle to the AutoCAD® object (application) in the ACAD variable, then just printed a line to the AutoCAD® command line. Easy right? Ok, but we’re not going to want to open a new instance of AutoCAD® every time we want to run some code… So instead, we could use this, which links to an already open instance of AutoCAD:

Sub Main()
    Dim ACAD As AcadApplication 'Create ACAD variable of type AcadApplication
    Set ACAD = GetObject(, "AutoCAD.Application") 'Get a running instance of the class AutoCAD.Application
    ACAD.ActiveDocument.Utility.Prompt "Hello from Excel!" 'Print a message to the AutoCAD® command line
End Sub


Great – now we can link to a running instance of AutoCAD®. There is one last thing we need to do with this. If we run this code and AutoCAD® is not running, we will get an error message. Really, we ought to trap this exception – here’s one way this could be dealt with:

Sub Main()
    Dim ACAD As AcadApplication 'Create ACAD variable of type AcadApplication
    On Error Resume Next 'This tells VBA to ignore errors
    Set ACAD = GetObject(, "AutoCAD.Application") 'Get a running instance of the class AutoCAD.Application
    On Error GoTo 0 'This tells VBA to go back to NOT ignoring errors
    If ACAD Is Nothing Then 'Check to see if the above worked
        Set ACAD = New AcadApplication 'Set the ACAD variable to equal a new instance of AutoCAD
        ACAD.Visible = True 'Once loaded, set AutoCAD® to be visible
    End If
    ACAD.ActiveDocument.Utility.Prompt "Hello from Excel!" 'Print a message to the AutoCAD® command line
End Sub


This code firstly tries to link to an existing instance of AutoCAD®. We use the On Error Resume Next statement to skim over any errors that might occur when we try to link to an existing instance of AutoCAD®. It is very important that we also add the statement On Error Goto 0 after we’re done ignoring errors. At first glance you might think that it’s a good idea to skim over all errors by adding On Error Resume Next to the beginning of all our code, but this makes it much more difficult for us as developers to debug our application. Use of On Error Resume Next in excess is generally considered bad programming practice, but under controlled circumstances its use is no problem, and it helps trap our error in the example above.

After our call to the GetObject function, the ACAD variable either contains a link to our AutoCAD® object, or it contains “Nothing” as it was unable to locate one. In the latter case, we are going to create a new instance using the method explained in the first example.

Now we’re getting there.

Let’s actually do something useful now. Go to Excel – Sheet1, and fill columns A and B with some coordinates, X being in column A, and Y being in column B. Here is some data you can copy/paste if you like, though you may need to copy and paste the columns seperately:

3
7
5
2
3
4
5
6
7
8
8
8
5
3
1.6
1
1
1
1.6
3

 

In Excel we can access the data in a worksheet by using Sheet1.Cells(Row, Column). We can loop through Sheet1.Cells and take action in AutoCAD® based on the content of the cells. Below is a quick example of how this can be achieved. The loop that is used is known as a For-Next loop, which increments the value of n in this example from 1 to 10. Then we’re just taking the data from the cells at row n, and using the data to insert a point into AutoCAD®. If you used the data above you’ll end up with a nice smiley face drawn in points!

Sub Main()
    Dim ACAD As AcadApplication 'Create ACAD variable of type AcadApplication
    On Error Resume Next 'This tells VBA to ignore errors
    Set ACAD = GetObject(, "AutoCAD.Application") 'Get a running instance of the class AutoCAD.Application
    On Error GoTo 0 'This tells VBA to go back to NOT ignoring errors
    If ACAD Is Nothing Then 'Check to see if the above worked
        Set ACAD = New AcadApplication 'Set the ACAD variable to equal a new instance of AutoCAD
        ACAD.Visible = True 'Once loaded, set AutoCAD® to be visible
    End If
    ACAD.ActiveDocument.Utility.Prompt "Hello from Excel!" 'Print a message to the AutoCAD® command line
    Dim Coords(2) As Double 'This is an array of double precision floating point numbers
    ' The array goes from 0 - 2, which will contain our coordinates X, Y and Z
    Dim n As Integer 'Create the variable n as the type Integer
    For n = 1 To 10 'Loop this code, incrementing the value of n from 1 to 10
        Coords(0) = Sheet1.Cells(n, 1) 'Put the Column 1 value into the Coords array
        Coords(1) = Sheet1.Cells(n, 2) 'Put the Column 2 value into the Coords array
        ACAD.ActiveDocument.ModelSpace.AddPoint Coords 'Add a point in AutoCAD® at this location
    Next
End Sub


So there we have it – an introduction to using VBA in Excel to control AutoCAD®. Obviously what we have done here only scratches the surface of the capabilities, but I’ll leave you to get creative with the that… for now at least.

As with all my posts I’d finally like to encourage you to subscribe to my blog. I’m always going to be adding new content on here, and I’ll always try to explain everything the best I can. Also, I’ll always be willing to help you with any specific problems that you have, so please do sign up and get involved on my site.

Will

About To Regen

If you ever get the “About to Regen, Ok or Cancel” message, it can be infuriating if you do not know how to turn it off.

So, here’s how – set the REGENAUTO system variable to ON.

Will

Break a line into smaller pieces using VBA or VB.NET in AutoCAD

Here’s a simple example of some VBA code that might come in handy either as a learning exercise, or if you happen to be trying to break a line programatically.

The code fistly asks the user to select a line, and the object is stored in the Line variable. Then, I’ve hard-coded the NumberOfSegments variable to equal 5. Next, we calculate what the “offset” would be for each line if we were to divide the original line up into 5 segments. Using this value, we then set the position of the existing line to be the length of the first line in the new set of lines. Then, using the offset calculated earlier, we can copy the line, and move by the amount defined in the Offset variable.

Option Explicit

Sub ExplodeLine()
    Dim NumberOfSegments As Long
    Dim Line As AcadLine
    Dim NewEndPoint(2) As Double
    Dim BasePoint(2) As Double
    Dim Offset(2) As Double
    Dim n As Long
    Dim p As Variant
    
    ThisDrawing.Utility.GetEntity Line, p, "Pick a Line..."
    NumberOfSegments = 5
    Offset(0) = (Line.EndPoint(0) - Line.StartPoint(0)) / NumberOfSegments
    Offset(1) = (Line.EndPoint(1) - Line.StartPoint(1)) / NumberOfSegments
    NewEndPoint(0) = Line.StartPoint(0) + Offset(0)
    NewEndPoint(1) = Line.StartPoint(1) + Offset(1)
    Line.EndPoint = NewEndPoint
    
    For n = 2 To NumberOfSegments
        ' Loop (NumberOfSegments - 1) times as the first already exists
        Set Line = Line.Copy
        Line.Move BasePoint, Offset
    Next
    
End Sub

Regards,
Will

MText.WidthFactor

If you’ve ever tried to edit the widthfactor of mtext through VBA or VB.NET, you’ll have realised that there isn’t a method for doing so. However, there is a built in trick which bypasses the requirement for doing this. Try the code below:

Sub main()
    Dim p As Variant
    Dim mt As AcadMText
    ThisDrawing.Utility.GetEntity mt, p, "Pick an MTEXT object..."
    mt.TextString = "\W0.5;" & a.TextString
End Sub

Preceeding the TextString property with the prefix \W0.5; tells AutoCAD® to make all the text have a width factor of 0.5. You can also edit the width factor of individual parts of the TextString, by surrounding the text you want to change in curly brackets, as shown below.

Sub main()
    Dim p As Variant
    Dim mt As AcadMText
    ThisDrawing.Utility.GetEntity mt, p, "Pick an MTEXT object..."
    mt.TextString = "{\W0.5;narrow} {\W2;wide} {\W0.5;narrow} {\W2;wide} {\W0.5;narrow} {\W2;wide}"
End Sub

Hope this helps – if it did, please do subscribe to my blog. I’ll be uploading many more tips and tricks regularly.

ThisDrawing.PaperSpace

ThisDrawing.PaperSpace is a very useful way to access the PaperSpace of your drawing through VBA or VB.NET.

When developing tools that draw entites in a drawing, we can sometimes use ThisDrawing.PaperSpace, forgetting that the tool might actually end up being used in ModelSpace. This would result in bahaviour that is not expected by the user. The ideal solution would be if there were an ActiveSpace method of the ThisDrawing object, but unfortunately this does not exist. There is a workaround however:

Function ThisSpace() As AcadBlock
    If ThisDrawing.ActiveSpace = acModelSpace Then
        Set ThisSpace = ThisDrawing.ModelSpace
    Else
        Set ThisSpace = ThisDrawing.PaperSpace
    End If
End Function

Use this function to return the block object of either ModelSpace or PaperSpace – whichever is actively open by the user. This solves the problem mentioned above, ensuring that you are always writing code that edits the space that is currently being worked on by the user. Use a call to this function in the place of ThisDrawing.PaperSpace.

I have many tutorials on my site for how to use your VBA code in VB.NET projects. I also explain what you need to get started with coding in VB.NET, and where to download the required software for free.

ThisDrawing.ModelSpace

ThisDrawing.ModelSpace is a very useful way to access the ModelSpace of your drawing through VBA or VB.NET.

When developing tools that draw entites in a drawing, we can sometimes use ThisDrawing.ModelSpace, forgetting that the tool might actually end up being used in PaperSpace. This would result in bahaviour that is not expected by the user. The ideal solution would be if there were an ActiveSpace method of the ThisDrawing object, but unfortunately this does not exist. There is a workaround however:

Function ThisSpace() As AcadBlock
    If ThisDrawing.ActiveSpace = acModelSpace Then
        Set ThisSpace = ThisDrawing.ModelSpace
    Else
        Set ThisSpace = ThisDrawing.PaperSpace
    End If
End Function

 

Use this function to return the block object of either ModelSpace or PaperSpace – whichever is actively open by the user. This solves the problem mentioned above, ensuring that you are always writing code that edits the space that is currently being worked on by the user. Use a call to this function in the place of ThisDrawing.ModelSpace.

I have many tutorials on my site for how to use your VBA code in VB.NET projects. I also explain what you need to get started with coding in VB.NET, and where to download the required software for free.

Clipping with multiple boundaries

Here’s a neat little trick that can be very useful. Have you ever wanted to clip an object, say a viewport or xref, with more than one boundary? Well there is a way to achieve the result you want, but using a single boundary.

Consider this – you want to clip an object using the outer rectangle below, but you want the inner rectangle to be a hole through the middle. Hmm this is a problem if you can only select one clipping boundary isn’t it…

rectangle within another rectangle

The solution is to make it a single boundary. Draw the outer rectangle, then just draw a line into the new location, draw that boundary, then draw on top of the line you drew to connect to the inner boundary back to the outer boundary and close the polyline:

rectangle within another rectangle boundary with gap

Here’s the same thing, but with a slight gap between the overlapping lines so that you can see what I mean:

rectangle within another rectangle boundary with gap

This works with clipping xrefs, blocks, viewports, anything that requires a clipping boundary.

I hope this little tip helps you as much as it has helped me. Also, I’d like to recommend that you subscribe below if you found this useful – I have many more tips to share!

Will

AutoCAD® 2008 scale list bug

If you’re using AutoCAD® 2008, then you may have experienced slow copy/pasting in some drawings. This is one of the symptoms of a problem known as the scale list bug. This is where the annotation scale list has for some reason accumulated a huge number of scales. There is a quick fix however – you can simply purge the scale list by using the SCALELISTEDIT command, but there’s another problem. The dialog box will not display if you have excessive scales. Preceeding the command with the minus sign (-SCALELISTEDIT) forces command line entry however, so we can bypass this problem. Select the option to reset, and hopefully this should fix the problem. This issue has a habit of spreading from drawing to drawing, so make sure you fix this is the whole set of drawings you’re experiencing problems with.

For a more permenent fix, you could try adding the following line of lisp code to either acaddoc.lsp, or acad2008doc.lsp:

(COMMAND “-scalelistedit” “R” “Y” “E”)

This will simply reset the scale list every time a drawing is opened.

Hope this helps,
Will