TheSwamp

Code Red => .NET => Topic started by: Matt__W on December 08, 2011, 02:12:04 PM

Title: [VB.NET] - Struggling with some code
Post by: Matt__W on December 08, 2011, 02:12:04 PM
The following code works fine in VBA, but in VB.NET I'm struggling with trying to get these declared properly.  I get the message "Type 'AcadBlockReference' is not defined".  I'm


Code: [Select]
        Dim objBlock As AcadBlockReference
        Dim objEnt As AcadEntity
        Dim objLayout As AcadLayout
        Dim dbxDoc as AxDbDocument

I've noticed that if I copy this code from a separate class and paste it in the code for my form then it works but then I get an error about it being ambiguous in the namespace.

Code: [Select]
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Colors
Imports Microsoft.Office.Interop.Excel

So what's the correct way to go about doing this?

Right now I have a form, 2 classes and 1 module that has some global declarations.
Title: Re: [VB.NET] - Struggling with some code
Post by: Keith™ on December 08, 2011, 02:19:28 PM
You do need import the Autodesk stuff, otherwise you won't have access to those objects. Without looking at your code, I can't tell why you have an ambiguous definition error. Are you importing the stuff more than once or in multiple locations?
Title: Re: [VB.NET] - Struggling with some code
Post by: Matt__W on December 08, 2011, 02:25:29 PM
I had it in one location, but it wasn't recognizing AcadBlockReference, AcadEntity, AcadLayout or AxDbDocument.  When I copied it to another location, it started recognizing them (except for the AxDbDocument).  That's when I started getting the ambiguous errors.

So I guess for starters, WHERE should the Imports go and is there a "special" way of making them global?
Title: Re: [VB.NET] - Struggling with some code
Post by: Jeff H on December 08, 2011, 03:00:19 PM
Just skimming through real quick.
Make sure you know the difference between a class and a module(Shared Class)
 
You need a imports statement for each .vb file at the top.
 
Also for VB.NET in properties on reference tab you can check them so it you do not have to import it.
 

 
 
Title: Re: [VB.NET] - Struggling with some code
Post by: Matt__W on December 08, 2011, 03:09:58 PM
Just skimming through real quick.
Make sure you know the difference between a class and a module(Shared Class)
 
You need a imports statement for each .vb file at the top.
 
Also for VB.NET in properties on reference tab you can check them so it you do not have to import it.
So if I toggle the items I want to import, I don't have to write the "Imports Autodesk....." code?  Is that what you're saying?
Title: Re: [VB.NET] - Struggling with some code
Post by: Jeff H on December 08, 2011, 03:29:41 PM
Yes
Title: Re: [VB.NET] - Struggling with some code
Post by: Matt__W on December 08, 2011, 03:53:34 PM
Where's the one for ObjectDBX?  Do you know?   I have it referenced in already.

Basically what I'm rewriting is code that opens drawings using DBX and reads & counts block attributes and dumps them into Excel.
Title: Re: [VB.NET] - Struggling with some code
Post by: Jeff_M on December 08, 2011, 04:21:23 PM
Forget ObjectDBX.....in .NET this is no longer needed. Create a Database Object, then 'open' the drawing using the Database object's ReadDwgFile method. You can still use the COM objects you are used to (although if you switch to the managed objects you wouldn't need a separate version for each version of Acad). I don't have any VB code handy, but I'll see if I can find some (unless Jeff_H posts first).
Title: Re: [VB.NET] - Struggling with some code
Post by: Matt__W on December 08, 2011, 04:31:32 PM
Forget ObjectDBX.....in .NET this is no longer needed. Create a Database Object, then 'open' the drawing using the Database object's ReadDwgFile method. You can still use the COM objects you are used to (although if you switch to the managed objects you wouldn't need a separate version for each version of Acad). I don't have any VB code handy, but I'll see if I can find some (unless Jeff_H posts first).
*sigh*  Okay... now I'm TOTALLY lost.  :)

*off to abuse Google.... again*
Title: Re: [VB.NET] - Struggling with some code
Post by: n.yuan on December 08, 2011, 05:07:50 PM
The reason of being lost is because you are probably trying to directly move your VBA code into .NET API project. While it is technically doable, it is not desired in most cases.

You'd better forget the VBA/COM code/knowledge (excepting the knowledge you know how AutoCAD works), and focus on using Acad's .NET API. After 8 versions of releases, Acad's NET API gets a lot more mature, you can hardly find something you can do with COM API that you cannot with .NET API. You also eliminate unnecessary dependency (to AutoCAD.Interop/Common) from your project.
Title: Re: [VB.NET] - Struggling with some code
Post by: Jeff_M on December 08, 2011, 05:24:24 PM
Matt, this is a very simplified example that leaves a lot to do, but it shows how simple it is to get the remote database object (what we used to need ObjectDBX for).
Code: [Select]
    Public Sub DoIt(ByVal filename As String)
        Dim sourceDb As Database = New Database(False, True)
        sourceDb.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, False, "")
        countblocks(sourceDb)
    End Sub

    Private Sub countblocks(ByVal db As Database)
        ''code to count the blocks in a database
    End Sub
Title: Re: [VB.NET] - Struggling with some code
Post by: Matt__W on December 09, 2011, 08:29:27 AM
The reason of being lost is because you are probably trying to directly move your VBA code into .NET API project.
No.  I fully understand that it's not possible to just simply copy/paste the code and I'm cool with that.  I'm just struggling to get a grip on the changes.  I was pretty good with VBA/VB 6.  Not so much with .NET (yet).

Matt, this is a very simplified example that leaves a lot to do, but it shows how simple it is to get the remote database object (what we used to need ObjectDBX for).
Thanks, Jeff!  I'm sure I'll be back with more questions as I get further along with this.  :)
Title: Re: [VB.NET] - Struggling with some code
Post by: Matt__W on December 09, 2011, 11:05:33 AM
I'm making progress.  Down to only 8 errors from 25 earlier.  :)  My next issue is with the database (instead of ObjectDBX).
In my VBA app, I had code that would open a DWG using ObjectDBX then cycle through each of the layout tabs.  How is this done with the Database?


Code: [Select]
        Public dbxDoc As Database = New Database(False, True)
Code: [Select]
        dbxDoc.ReadDwgFile("e:\temp\" & RetrieveFileName(strFile), FileOpenMode.OpenForReadAndAllShare, False, "")

        For Each objLayout In dbxDoc.Layouts
            For Each objEnt In objLayout.Block
                If TypeOf objEnt Is BlockReference Then
                    objBlock = objEnt
                    If objBlock.IsDynamicBlock Then....
Title: Re: [VB.NET] - Struggling with some code
Post by: Jeff H on December 09, 2011, 11:16:46 AM
I will post some code later today when I will have some spare time.
 
But since you are getting attributes you can go through the block definitions with attributes then get all the blockReferences.
 
Title: Re: [VB.NET] - Struggling with some code
Post by: Jeff H on December 09, 2011, 02:01:19 PM
Of course not good coding practice hard-coding values, should be broken, etc...........
but here is some code to maybe get you started that just prints all the attribute reference's to the command line, and of course you need to change the drawing path.
 
Code: [Select]

         <CommandMethod("OpenDrawingInSideDatabase")> _
        Public Sub OpenDrawingInSideDatabase()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor

            Using sideDb As New Database(False, True)

                sideDb.ReadDwgFile("C:\Testing\AutoCAD\AttTest.dwg", FileOpenMode.OpenForReadAndAllShare, False, "")

                Using trx As Transaction = sideDb.TransactionManager.StartTransaction

                    Dim bt As BlockTable = trx.GetObject(sideDb.BlockTableId, OpenMode.ForRead)

                    For Each btrId As ObjectId In bt
                        Dim btr As BlockTableRecord = trx.GetObject(btrId, OpenMode.ForRead)

                        If btr.IsLayout Or btr.IsFromExternalReference Or btr.IsDependent Then
                            Continue For
                        End If

                        If btr.HasAttributeDefinitions Then

                            Dim brefIds As ObjectIdCollection = btr.GetBlockReferenceIds(True, False)

                            For Each brefId As ObjectId In brefIds

                                Dim bref As BlockReference = trx.GetObject(brefId, OpenMode.ForRead)

                                For Each attRefId As ObjectId In bref.AttributeCollection
                                    Dim attref As AttributeReference = trx.GetObject(attRefId, OpenMode.ForRead)
                                    ed.WriteMessage("{0}{1} = {2}{0}", Environment.NewLine, attRef.Tag, attRef.TextString)
                                Next

                            Next

                        End If

                    Next

                End Using
            End Using

        End Sub
Title: Re: [VB.NET] - Struggling with some code
Post by: Matt__W on December 09, 2011, 02:23:27 PM
Of course not good coding practice hard-coding values, should be broken, etc...........
but here is some code to maybe get you started that just prints all the attribute reference's to the command line, and of course you need to change the drawing path.
 
Code: [Select]

         <CommandMethod("OpenDrawingInSideDatabase")> _
        Public Sub OpenDrawingInSideDatabase()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor

            Using sideDb As New Database(False, True)

                sideDb.ReadDwgFile("C:\Testing\AutoCAD\AttTest.dwg", FileOpenMode.OpenForReadAndAllShare, False, "")

                Using trx As Transaction = sideDb.TransactionManager.StartTransaction

                    Dim bt As BlockTable = trx.GetObject(sideDb.BlockTableId, OpenMode.ForRead)

                    For Each btrId As ObjectId In bt
                        Dim btr As BlockTableRecord = trx.GetObject(btrId, OpenMode.ForRead)

                        If btr.IsLayout Or btr.IsFromExternalReference Or btr.IsDependent Then
                            Continue For
                        End If

                        If btr.HasAttributeDefinitions Then

                            Dim brefIds As ObjectIdCollection = btr.GetBlockReferenceIds(True, False)

                            For Each brefId As ObjectId In brefIds

                                Dim bref As BlockReference = trx.GetObject(brefId, OpenMode.ForRead)

                                For Each attRefId As ObjectId In bref.AttributeCollection
                                    Dim attref As AttributeReference = trx.GetObject(attRefId, OpenMode.ForRead)
                                    ed.WriteMessage("{0}{1} = {2}{0}", Environment.NewLine, attRef.Tag, attRef.TextString)
                                Next

                            Next

                        End If

                    Next

                End Using
            End Using

        End Sub
I'll have to disect this next week.  Seems everybody wants everything NOW!!

Thanks!  :)