Author Topic: Using AutoCad's ObjectDBX from Excel  (Read 12610 times)

0 Members and 1 Guest are viewing this topic.

Viktor

  • Guest
Using AutoCad's ObjectDBX from Excel
« on: March 31, 2006, 09:23:29 PM »
Ok, i replied a couple of times to a thread in autolisps about getting attributes using objectdbx, that was very useful. Now I have a VBA question, I know there is a way, but haven't spent enough time on it, how to run odbx from within the excel's vba??? I want to avoid using AutoCad coding all together. Here's the outline of what i'm trying to create in excel:

Pull up a browser to select a number of drawings
Start OBDX
Extract a number of attributes from each file, each layout
Place each attribute in the excel file.

Any suggestions?
Any linkies or examples?

I'm a newbie to this, but with some explanations it clears up for me.
Thanks,
Viktor.

Jeff_M

  • King Gator
  • Posts: 3945
  • C3D user & customizer
Re: Using AutoCad's ObjectDBX from Excel
« Reply #1 on: March 31, 2006, 10:19:10 PM »
OK, first off you MUST have either A.)Autcad running, B.) Autocad installed so it can be started, C.)Purchased the stand-alone version of ObjectDBX (now called RealDWG) from Autodesk. The version that shipes with Acad is free to use, but requires an instance of Acad to be running....although it can be invisible so the user never sees it....
I just worked on an example recently, let me see if I can find it.

Edit....uhm, I seem to be on my home computer and I left my laptop at the office. It'll have to wait unless I can access the place I posted it, which may take me a while because I can't recall where I used it.  :oops:

Jeff_M

  • King Gator
  • Posts: 3945
  • C3D user & customizer
Re: Using AutoCad's ObjectDBX from Excel
« Reply #2 on: April 01, 2006, 02:14:03 AM »
OK, I think I figured it out...it was Viktor I was offering to help over on the Adesk newsgroups. He never responded with the details so I never completed my example.....no wonder I couldn't recall where I posted it, I never did.

So, Viktor, I'll reiterate what I said before. Most of what you need for accessing Acad/ODBX within Excel is in the Sample provided with Acad. As for the browsing for folders/dwgs, there are a number of examples around. I'm pretty sure you will find some here at the Swamp, but that is a typical VBA code that could be pulled from many VBA sources.

If it's as wet here tomorrow as today was, I should have some time to throw something together, if you haven't yet done so.

Viktor

  • Guest
Re: Using AutoCad's ObjectDBX from Excel
« Reply #3 on: April 01, 2006, 08:09:53 PM »
Jeff, thanks for your reply.
Well, you got me there, i'm the same viktor, sorry i didn't get enough details on the adesk forum.
My only excuse is that i've been off and on with this little project. See, it's really not my job to do this, I'm a designer, not a programmer. But it seems that our Drafter Sr. is not about to do anything like this.

Like I said before, I set them up with a automatic process already, it is just very messy. And I do understand that Autocad should be running, that's not my concern. I just don't want it to open each drawing load everything, every xref and every image and then extract the attribute. The way that example that you wrote in the LISP thread worked was awesome! It's like 100 times faster!

But my problem is that half the people that will be using it will be very umm computer illiterate, they managed to screw up what i thought was hard to mess up. Soooo, i really want them to just open excel file, click a button, get the files, and have the autocad do the rest.

I do remember that sample, and it is also on my work's laptop, so I will check it out again, but there are a number of ways how to import the attributes back into the excel, isn't there?

I'm dealing with 50-300 drawings at a time and 5 attributes per drawing, so i'm not sure what would be the best way.

Thanks for your patience Jeff!

Viktor.

Jeff_M

  • King Gator
  • Posts: 3945
  • C3D user & customizer
Re: Using AutoCad's ObjectDBX from Excel
« Reply #4 on: April 02, 2006, 08:45:34 PM »
That's OK, Viktor....I'd rather help you here in theSamp anyway  8-)
I didn't post this yesterday as I got some bad news and I had to wake my wife and leave in a hurry. Due to the passing of my mother-in-law yesterday I'm not sure how much I'll be on in the next week as we'll be travelling to New York sometime.......

Anyway, here's what I have to show how to access the drawings using ObjectDBX from Excel. I don't have time to add in the folder search or anything else....i.e. this is setup as a 1 drawing type access....the acad/objectdbx objects creation should be done once, not everytime you access a drawing. Good luck and hopefully someone else can step in to help.

Code: [Select]
'Excel Code!
'Modified April 1, 2006 by Jeff Mishler to demonstrate the use of ObjectDBX.
'      ActiveX Sample
'
'      Copyright (C) 1997, 1999, 2002 by Autodesk, Inc.
'
'      Permission to use, copy, modify, and distribute this software
'      for any purpose and without fee is hereby granted, provided
'      that the above copyright notice appears in all copies and
'      that both that copyright notice and the limited warranty and
'      restricted rights notice below appear in all supporting
'      documentation.
'
'      AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
'      AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
'      MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
'      DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
'      UNINTERRUPTED OR ERROR FREE.
'
'      Use, duplication, or disclosure by the U.S. Government is subject to
'      restrictions set forth in FAR 52.227-19 (Commercial Computer
'      Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
'      (Rights in Technical Data and Computer Software), as applicable.

Option Explicit
Sub Extract()
    Dim sheet As Object
    Dim elem As Object
    Dim excel As Object
    Dim excelSheet As Object
    Dim RowNum As Integer
    Dim Array1 As Variant
    Dim Count As Integer
    Dim acad As Object
    Dim doc As Object
    Dim mSpace As Object
    Dim NumberOfAttributes As Integer
    Dim AcadRunning As Boolean
   
    Set excel = GetObject(, "Excel.Application")
    Worksheets("Attributes").Activate
    Set excelSheet = excel.ActiveWorkbook.Sheets("Attributes")
    excelSheet.Range(Cells(1, 1), Cells(1000, 100)).Clear
    excelSheet.Range(Cells(1, 1), Cells(1, 100)).Font.Bold = True
    Set acad = Nothing
    On Error Resume Next
    Set acad = GetObject(, "AutoCAD.Application")
    If Err <> 0 Then
        Set acad = CreateObject("AutoCAD.Application")
        acad.Visible = False
        AcadRunning = False
        'MsgBox "Please open a drawing file and then restart this macro."
        'Exit Sub
    Else
        AcadRunning = True
    End If
    On Error GoTo 0 'Err_Handler
    If acad.Version Like "16*" Then
        Set doc = acad.getinterfaceobject("ObjectDBX.AxDbDocument.16")
    ElseIf acad.Version Like "17*" Then
        Set doc = acad.getinterfaceobject("ObjectDBX.AxDbDocument.17")
    Else
        Set doc = acad.getinterfaceobject("ObjectDBX.AxDbDocument")
    End If
    doc.Open "C:\Temp\Att-Test.dwg"
    RowNum = 1
    Dim Header As Boolean
    Header = False
    Dim oBlock As Object
    Dim oLayout As Object
    For Each oLayout In doc.Layouts
        If oLayout.Name <> "Model" Then
        Set oBlock = oLayout.block
        For Each elem In oBlock
            With elem
                If StrComp(.EntityName, "AcDbBlockReference", 1) = 0 Then
                   If UCase(.Name) = "TDG" Then
                    If .HasAttributes Then
                        Array1 = .GetAttributes
                        For Count = LBound(Array1) To UBound(Array1)
                            If Header = False Then
                                If StrComp(Array1(Count).EntityName, "AcDbAttribute", 1) = 0 Then
                                    excelSheet.Cells(RowNum, Count + 1).Value = Array1(Count).TagString
                                End If
                            End If
                        Next Count
                        RowNum = RowNum + 1
                        For Count = LBound(Array1) To UBound(Array1)
                            excelSheet.Cells(RowNum, Count + 1).Value = Array1(Count).TextString
                        Next Count
                        Header = True
                    End If
                    End If
                End If
            End With
        Next elem
        End If
    Next oLayout
    NumberOfAttributes = RowNum - 1
    If NumberOfAttributes > 0 Then
        Worksheets("Attributes").Range("A1").Sort _
        key1:=Worksheets("Attributes").Columns("A"), _
        Header:=xlGuess
    Else
        MsgBox "No attributes found in the current drawing."
    End If
    Set doc = Nothing
    If AcadRunning = False Then acad.Quit
    Set acad = Nothing
    Exit Sub
Err_Handler:
    Debug.Print Err.Number & " - " & Err.Description
    Err.Clear
    If AcadRunning = False Then acad.Quit
End Sub

Chuck Gabriel

  • Guest
Re: Using AutoCad's ObjectDBX from Excel
« Reply #5 on: April 02, 2006, 09:10:35 PM »
I'm sorry to hear about your mother-in-law Jeff.  Hug your wife for me.

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Using AutoCad's ObjectDBX from Excel
« Reply #6 on: April 02, 2006, 10:45:17 PM »
I am sorry to hear that as well Jeff.

Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: Using AutoCad's ObjectDBX from Excel
« Reply #7 on: April 03, 2006, 02:25:44 AM »
If you don't ABSOLUTELY require a code solution, from AutoCAD 2004 on I believe, you can use 'Advanced Attribute Extraction' (just type EATTEXT on the command line).

It will allow you to select multiple drawing files and pick the block and attributes form the block to be exported. If you have EXCEL on the machine you will get an option to save to an EXCEL file directly.

Cheers,
Glenn.
Me

Viktor

  • Guest
Re: Using AutoCad's ObjectDBX from Excel
« Reply #8 on: April 03, 2006, 12:06:37 PM »
Jeff, thank you greatly for your reply, I am sorry to hear about your loss, and don't worry about me here, if i don't get the answer I have patience to help me out there.

Glenn, actually eattext is horrible, i don't believe it is a finished routine that adesk came up with. it does not work for multiple drawings, it works partially, but not as it should be. There are threads on adesk forums talking about it, but no solution has been posted. and this will allow me to acutally use my own spreadsheet and fill the cells i want, not just a new spreadsheet.

Thanks again, I will give the code a try.
Viktor.

Viktor

  • Guest
Re: Using AutoCad's ObjectDBX from Excel
« Reply #9 on: April 03, 2006, 10:43:36 PM »
ok, so i've been looking around a bit, and need a little help from someone...
What is the difference between getting stuff from a drawing via vba
OR
Getting stuff from the drawing VIA OBDX & VBA???
i'm mainly talking about the sample that is provided by autodesk and is posted above. So it's the same thing as just working with VBA in AutoCad, you just can't have selection sets, and you also don't have to have the drawing open, correct? (autocad running, but drawing does not have to be opened) so why is the sample still wanting that drawing to be opened?

yea, i'm a bit confused. someone give me a link to some tutorials or something.
Thanks,
Viktor.

Bryco

  • Water Moccasin
  • Posts: 1849
Re: Using AutoCad's ObjectDBX from Excel
« Reply #10 on: April 04, 2006, 10:48:03 AM »
The open in the sample is a different find of open. Think of it being more like opening a dxf file in notepad. You can find all the info in the drawing in the text (I'm not quite sure how odbx works). You can open 10 dwgs in cad with vba and you see each dwg flash on the screen, you can also open 10 dwgs in odbx and you will see nothing. It's faster and runs in the background.

Viktor

  • Guest
Re: Using AutoCad's ObjectDBX from Excel
« Reply #11 on: April 04, 2006, 12:31:06 PM »
Thanks :) that's how i thought of it too.

Noooooooooow, i need some more help. Here's what I got:

Code: [Select]
Public acad As Object
Public odbx As Object
Public mspace As Object
Public excel As Object
Public AcadRunning As Integer
Public excelSheet As Object
Sub Extract()
    Dim sheet As Object
    Dim shapes As Object
    Dim excel As Object
    Dim excelSheet As Object
    Dim RowNum As Integer
    Dim Array1 As Variant
    Dim i As Integer
    Dim ent As AcadEntity
    Dim Layouts As AcadLayouts
    Dim Layout As AcadLayout
    Dim blkref As AcadBlockReference
    Dim filetoopen As Variant
       
    'Prepare Excel
   
    Set excelSheet = ActiveWorkbook.Sheets("test")
   

'getfilenames
filetoopen = Application.GetOpenFilename("Drawing Files (*.dwg), *.dwg", , "Select Drawings", "Get Attributes", True)


On Error Resume Next
Set acad = GetObject(, "AutoCAD.Application")
If Err <> 0 Then
Set acad = CreateObject("AutoCAD.Application")
End If
On Error GoTo 0
Set odbx = acad.GetInterfaceObject("ObjectDBX.AxDbDocument.16")
odbx.Open

   
       
    RowNum = 0
   
    'Work in AutoCad
   
    Set doc = acad.ActiveDocument
    Set Layouts = doc.Layouts
   

For Each Layout In Layouts
If Layout.Name <> "Model" Then
    For Each ent In Layout.Block
        If ent.ObjectName = "AcDbBlockReference" Then
            Set blkref = ent
                If blkref.Name = "CORP-D" Then
                    Array1 = blkref.GetAttributes
                   
                    RowNum = RowNum + 1
                    For i = LBound(Array1) To UBound(Array1)
                        If Array1(i).TagString = "4" Then

                        excelSheet.Cells(RowNum, 1).Value = Array1(i).TextString
                        End If
                       
                        If Array1(i).TagString = "5" Then

                        excelSheet.Cells(RowNum, 2).Value = Array1(i).TextString
                        End If
                       
                        If Array1(i).TagString = "6" Then

                        excelSheet.Cells(RowNum, 3).Value = Array1(i).TextString
                        End If
                       
                        If Array1(i).TagString = "7" Then

                        excelSheet.Cells(RowNum, 4).Value = Array1(i).TextString
                        End If
                       
                        If Array1(i).TagString = "8" Then

                        excelSheet.Cells(RowNum, 5).Value = Array1(i).TextString
                        End If
                       
                    Next i
                End If
              End If
            Next ent
            End If
        Next Layout
    Set acad = Nothing
    Set odbx = Nothing
End Sub

my question is in the FILETOOPEN area and GetOpenFilename, at the beginning.
So GetOpenFilename allows me to get a list of files that I want to process, in a clean way. FileToOpen is a variant and it then contains a list of these files.
Now, how do I get ODBX to go through each one of those files?
I understand, For Each doc in docs do this and that, but it seems that odbx is not opening those files, can someone help me out here?
What do i have wrong?
Thanks,
Viktor.

Jeff_M

  • King Gator
  • Posts: 3945
  • C3D user & customizer
Re: Using AutoCad's ObjectDBX from Excel
« Reply #12 on: April 04, 2006, 01:28:42 PM »
First off, thanks to all for the kind words.

Next, Bryco explained ObjectDBX pretty well.
Thanks :) that's how i thought of it too.

Noooooooooow, i need some more help. Here's what I got:

Code: [Select]
snipped the code
my question is in the FILETOOPEN area and GetOpenFilename, at the beginning.
So GetOpenFilename allows me to get a list of files that I want to process, in a clean way. FileToOpen is a variant and it then contains a list of these files.
Now, how do I get ODBX to go through each one of those files?
I understand, For Each doc in docs do this and that, but it seems that odbx is not opening those files, can someone help me out here?
What do i have wrong?
Thanks,
Viktor.
I've never used the GetOpenFileName function so I don't know what it returns, but I'd venture a guess that it is probably either a collection or an array. In either case you can use
For Each filename  In filetoopen
  odbx.open filename
  do whatever with the odbx, such as cycle the layouts collection
Next doc

Also, you set doc to the active acad document........forget that you have acad open! ALL work is to be done with the ODBX object, which is a document.

So you will do this after opening the odbx file:
Set Layouts = odbx.Layouts
then cycle through those layouts.

Does that make more sense?


Viktor

  • Guest
Re: Using AutoCad's ObjectDBX from Excel
« Reply #13 on: April 04, 2006, 03:19:49 PM »
Thanks Jeff, you are as always filled with wisdo advice!

It works! do you think this could also be somehow improved? it is a bit slow... am i running some loop too much or complicating it a bit? It's not slow slow, but its not flash and done kind of thing.

Now I have to combine 2 attributes before inserting it into cad, that should be fun...
Thanks again Jeff!
Viktor.

Jeff_M

  • King Gator
  • Posts: 3945
  • C3D user & customizer
Re: Using AutoCad's ObjectDBX from Excel
« Reply #14 on: April 04, 2006, 03:30:05 PM »
I'd like to try a bit more to further clarify what ObjectDBX is.

Think of ObjectDBX as nothing more than Autocad without a graphics engine that works ONLY in SDI (single document) mode. So everytime you you use the Open method you will be eliminating any reference to the previously opened document. Unlike Autocad, there are no prompts or warnings to ask if you want to save or discard changes. It is up to you, the programmer, to make that determination prior to executing the Open method. If you intend to save any changes, do so with the SaveAs method before calling the Open method. Additionally, anytime you save a drawing in ODBX you lose the thumbnail preview image. There is a workaround for this, but I will save that for another time.

As I was posting this I ssaw that Viktor had made another post.....
No one said it will be done in a flash, Viktor. :-) What we have said is that it will be MUCH faster than using Autocad and cycling through the drawings in it. That being said, I have a routine (sorry, I cannot share it) that accesses, records, and revises 14 attributes in every Layout of approx. 2000 drawings and it takes some time. But I know, without even trying, that this it far faster than opening each in Acad.