"NO DATABASE" ERROR when automating my layers insertion in new drawing

"NO DATABASE" ERROR when automating my layers insertion in new drawing

Anonymous
Not applicable
1,300 Views
6 Replies
Message 1 of 7

"NO DATABASE" ERROR when automating my layers insertion in new drawing

Anonymous
Not applicable

Hello everyone,

 

I'm coding a macro that will insert some layers whenever I create a new drawing. Because there's not such event available to the AcadDocument object I have had to create a class (MyClass) that will provide me the NewDrawing event that belongs to the AcadApplication object instead. See the code below (in case you're wondering, that MsgBox was just for testing purposes):

 

 

 

Option Explicit
Public WithEvents ACADApp As AcadApplication
Private Sub ACADApp_NewDrawing()
    MsgBox "Hello"
    Module1.AutomatedLayerInsertion
End Sub

 

 

 

The AutomatedLayerInsertion is a simple macro meant to insert the layers I want and which is located in Module1 of my .dvb file. Nothing fancy, it has always worked except in this case.

 

The thing is I have programmed everything so that each time an AcadDocument gets activated (AcadDocument_Activate event), it will trigger a module that will instantiate my MyClass class and so I will have the NewDrawing event at my disposal.

 

The order of events: AcadDocument_Activate: calls Init >> Init: Instantiates the MyClass class >> NewDrawing event: insertion of layers (source of the "NO DATABASE" error). Next the codes:

 

AcadDocument_Activate:

 

 

 

Private Sub AcadDocument_Activate()
Module2.Init
End Sub

 

 

 

Init procedure:

 

 

'Public test As New MyClass --DECLARE HERE OR TRY AS A STATIC VARIABLE
Sub Init()

Static test As New MyClass
Dim myCad As AcadApplication

Set myCad = GetObject(, "AutoCAD.Application")
Set test.ACADApp = myCad
'Alternatively do without myCad
'Set test.ACADApp = ThisDrawing.Application

End Sub

 

 

 

The MyClass class once again:

 

 

 

Option Explicit
Public WithEvents ACADApp As AcadApplication
Private Sub ACADApp_NewDrawing()
    MsgBox "Hello"
    Module1.AutomatedLayerInsertion
End Sub

 

 

 

The Source of error:

 

 

 

Dim myLayer As AcadLayer
Dim myColor As AcadAcCmColor
On Error GoTo myError

'Debug.Print ThisDrawing.Layers(0).Name

Set myLayer = ThisDrawing.Layers.Add("Machinery")
.
.
.

 

 

 

The dots are to represent that the code continues. The offensive line is the addition of the "Machinery" layer. More precisely, this is the error: 

 

-2145386390 No database

 

Suspecting AutoCad couldn't find the layers Database (very confusing what that "No database" was referring to initially) I added the line that appears commented out in my code: Debug.Print ThisDrawing.Layers(0).Name. Well, if it's not commented out, that line raises an error which seems to confirm that AutoCad can't find the layers database.

 

Now, if I don't use the NewDrawing event and I run the macro for the layer insertion, it works like a charm. But I do want it to work as I expected it to and I can't give up! So I thought that this had something to do with starting everything from the ThisDrawing object section (remember everything starts with and ACadDocument_Activate) and maybe the ThisDrawing in my macro for the layer insertion (please, refer to the code) was conflicting in some way (just a guess, I have no idea if what I considered was a nonsense). So I changed my code to see If I could "trick" VBA and replaced ThisDrawing with a new variable that is referring to the ActiveDocument (in principle, both things are the same but I had to give it a try).

 

 

 

Dim myLayer As AcadLayer
Dim myColor As AcadAcCmColor

On Error GoTo myError

Dim dwg As AcadDocument
Set dwg = ActiveDocument
'Debug.Print dwg.Layers(0).Name
Set myLayer = dwg.Layers.Add("Machinery")
.
.
.

 

 

 

But the error persists. 

 

I've also tried to put the layer insertion procedure inside the MyClass class, just as a desperate attempt. And it didn't work out either.

 

Can anybody shed some light? I've tried my best to solve the problem but I'd also like to understand what's going on. I may have made a mistake in my code or made a wrong assumption. So I hope you can help me.

 

I hope it doesn't bother you if I mention the two of you. You're relatively active and very knowledgeable 🙂

@Ed__Jobe  and @norman.yuan 

 

Thanks for getting 'til here.

 

0 Likes
1,301 Views
6 Replies
Replies (6)
Message 2 of 7

norman.yuan
Mentor
Mentor

Well, the AcadApplication.NewDrawing event is fired when a new document creation just begins, but not completed, according to Acad VBA document:

<QUOTE>

Triggered just before a new drawing is created.

</QUOTE>

 

That is, the document itself as drawing database container is there, but the database creation is yet to be completed, thus you cannot have code to manipulate data in the drawing.

 

Acad VBA does not provide as many events as Acad .NET API, and your option is quite limited, if you want to have your layer manipulating code run on every new drawing automatically. I'd think you would have to handle AcadDocument.Activate event, where you can only do the layer work when:

 

1. If the drawing is not titled (test "DWGTITLED" system variable, it should be 0);

2. You can also set a flag to indicate the layer work has been done with an untitled drawing. Say, you save the flag in one of the USERS[R][0-5] system variable, to prevent running the layer work code repeatedly.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 7

grobnik
Collaborator
Collaborator

Hi to everybody, I'm sorry for silly answer but if the issue it's only related to layers on new dwg why do not create a dwt model document with already settled the new layer inside? On the opposite if dwg are existing the issue it's different.

0 Likes
Message 4 of 7

Anonymous
Not applicable

Hello Norman,

 

Thanks for answering.

 

Before the changes I had been doing it like you suggest in "1." just to prevent inserting the layers in any document that was not new. So the NewDrawing has the drawback you mention then... Well, if there was not a drawing as such yet I was wondering if I could set a new template by code (AcadApplication.Preferences.Files.QNewTemplateFile). It turns out it doesn't in the first run of the macro, but in the second one, so any changes affecting the drawing through NewDrawing will be useless. I wonder what is the purpose of this event if one can't control the drawing or the settings... I wish I hadn't wasted my time playing around with it.

Message 5 of 7

Anonymous
Not applicable

Your question is not silly, it makes all the sense! 

 

On the one hand, I was just playing around with the NewDrawing event to understand its capabilities, but it turns out - unless I've made a mistake - that is useless when it comes to both the drawing and its settings. If the event doesn't allow me to manipulate the layers because the drawing doesn't exist yet, the least it could do is allowing me to select a template, but it doesn't even do that... I can't think why the event can come in handy at all. Why would anyone use it?

 

On the other hand, the addition of layers to existing drawings is dependent upon circumnstances, so I have created a button on my Tool Palette that runs the macro which adds the layers manually. 

Message 6 of 7

grobnik
Collaborator
Collaborator

Hi @Anonymous ,

As @norman.yuan explained the event trap have limited functionality with VBA, perhaps with a more machine level programming language could be used, Norman talked about VB.Net, could you try to make a topic on relevant VB NET forum.

But let me say another silly answer, why do you don't apply the procedure after new drawing opened, instead into the while drawing it's opening?

What's happen if you manage layers after empty drawing creation completed, you can check the list of layers or other drawing properties in order to check the drawing it's completely new and you manage the layers as you prefer, so the empty drawing database it's complete and any kind of similar error occurs. 

Bye

0 Likes
Message 7 of 7

Anonymous
Not applicable

I have decided to keep it even simpler. I've gone back to the AcadDocument_Activate and coded it like this:

 

Private Sub AcadDocument_Activate()

     If ThisDrawing.FullName = "" And ThisDrawing.Layers.Count = 1 Then Module1.AutomatedLayerInsertion

End Sub