2013 map get objectdata record and values from table by name or selection

2013 map get objectdata record and values from table by name or selection

jcoon
Enthusiast Enthusiast
1,125 Views
7 Replies
Message 1 of 8

2013 map get objectdata record and values from table by name or selection

jcoon
Enthusiast
Enthusiast

Hi All,

 

I'm looking for help getting the objectdata record values from a selected table. I'm able to loop thru the list of tables and also select a table to be current, however I can't seem to get the records to displayed display, it tried ex: get records, but that didn't work, not sure why.

 

any ideas where I'm going work. I'm ultimate goal would be to select an Ent object in the dwg and connect to it's table to display the properties fields and values attached so I can edit them much list a properties dialog box, end the end I'd like to query the values in the table to display a layer and style.

any help, links or material I can read would be wonderful.

 

Thank you

John

 

                ex: get records

        odTable = acTableList.Item("obstacle")
                Dim odrecords As ObjectData.Records = odTable.GetObjectTableRecords(Convert.ToUInt32(0), id, Constants.OpenMode.OpenForWrite, True)
                Dim odRecord As ObjectData.Record = odrecords(0)
                MsgBox(odRecord.Count())
                MsgBox(odRecord.Item(0).StrValue)

 

<CommandMethod("readodatatables")> _

PublicSub readodatatables()

Dim ed AsEditor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()

Dim db AsDatabase = HostApplicationServices.WorkingDatabase

Dim civilDoc AsCivilDocument = CivilApplication.ActiveDocument

Dim acaddoc AsDocument = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

Dim mapApp AsMapApplication

mapApp = HostMapApplicationServices.Application

Dim activeProj As Project.ProjectModel

activeProj = mapApp.ActiveProject

Dim ODtablename AsString

Dim mytrans AsTransaction = db.TransactionManager.StartTransaction

Try

Dim acBlkTbl AsBlockTable

acBlkTbl = mytrans.GetObject(db.BlockTableId, OpenMode.ForRead)

Dim acBlkTblRec AsBlockTableRecord

acBlkTblRec = mytrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

Dim BTMSpace AsBlockTableRecord = acBlkTbl(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)

Dim acMapApp AsMapApplication = HostMapApplicationServices.Application

Dim acActiveProject As Project.ProjectModel = acMapApp.ActiveProject

Dim acTableList AsTables = acActiveProject.ODTables

Dim odTable As Autodesk.Gis.Map.ObjectData.Table

ForEach ODTables In acTableList.GetTableNames()

acTableList.GetTableNames.ToString()

ODtablename = ODTables

MsgBox("Table Name = " & ODtablename)

Next

MsgBox("number of tables in table list = " + acTableList.TablesCount.ToString)

odTable = acTableList.Item("obstacle")

MsgBox("Selected table =" + odTable.Name)

Catch exc As Autodesk.Gis.Map.MapException

EndTry

mytrans.Commit()

mytrans.Dispose()

EndSub

0 Likes
1,126 Views
7 Replies
Replies (7)
Message 2 of 8

norman.yuan
Mentor
Mentor

Assuming the code for get ODTable record code is to be somewhere inside the CommandMethod code shown below, there are 2 things I noticed:

 

1. After getting the Records by

 

Dim odrecords As ObjectData.Records = odTable.GetObjectTableRecords(Convert.ToUInt32(0), id, Constants.OpenMode.OpenForWrite, True)

 

You'd better first test if the Records.Count==0 or not, before you call:

 

Dim odRecord As ObjectData.Record = odrecords(0)

 

unless you are absolutely should ALL entities in modelspace have ODTable record attached. Also, this line of code

 

MsgBox(odRecord.Count())

 

would raise exception: Record.Count is a property, not a method, thus you do not follow it with "()".

 

2. In the CommandMethod, you used

 

Try

...

Catch

End Try

 

I am strongly against using empty Catch clause, which simply silently eats unexpected exception and trys continue the execution. If you tried the Record retrieving code inside that "Try...Catch End Try" block in your command method, with the possible error as I methioned above, your code just goes through and does not tell you anything wrong. Unless you absolutely know you can ingnore exception in "Try..." clause and not harm will be done to the execution, never use an empty "Catch..." clause.

 

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 8

jcoon
Enthusiast
Enthusiast

Norman.juan,

 

Thanks for taking a look and also for the description of areas to look for while working on this sample. I'll see what I can do during lunch today.

again thank you

John 

0 Likes
Message 4 of 8

jcoon
Enthusiast
Enthusiast

 

I tried adding this from the map pdf sample getting OD, when I paste the sample I had an error as id, which I assume if the objectID so I added id as objectid , that seemed to pass the error, however when I run this section it stops at  "Dim odrecords As ObjectData.Records = odTable.GetObjectTableRecords(Convert.ToUInt32(0), id, Constants.OpenMode.OpenForWrite, True)" and never makes ti to the test for object type data from the FieldDefinition. I'm geting the correct table from the list of table, next should be the records in that table and then the acture values for each field,  is that coorect?

 

 

 

odTable = acTableList.Item("obstacle")
'MsgBox("Selected table =" + odTable.Name)

            Dim odrecords As ObjectData.Records = odTable.GetObjectTableRecords(Convert.ToUInt32(0), id, Constants.OpenMode.OpenForWrite, True)
            Dim odRecord As ObjectData.Record = odrecords(0)
            If (odRecord.Count() > 0) Then
                For Each rec As ObjectData.Record In odrecords
                    For i As Integer = 0 To rec.Count() - 1
                        Dim val As Autodesk.Gis.Map.Utilities.MapValue
                        val = rec(i)
                        Dim fieldDefs As ObjectData.FieldDefinitions = _
                          odTable.FieldDefinitions
                        Dim fieldDef As ObjectData.FieldDefinition
                        fieldDef = fieldDefs(i)
                        ed.WriteMessage(
                        vbNewLine + fieldDef.Name + ": ")
                        Select Case val.Type
                            Case Constants.DataType.Character
                                ed.WriteMessage(val.StrValue)
                            Case Constants.DataType.Integer
                                ed.WriteMessage(val.Int32Value.ToString)
                            Case Constants.DataType.Point
                                ed.WriteMessage("point")
                            Case Constants.DataType.Real
                                ed.WriteMessage(val.DoubleValue.ToString)
                            Case Else
                                ed.WriteMessage("undefined")
                        End Select
                    Next
                Next
            End If
            odrecords.Dispose()

 

0 Likes
Message 5 of 8

norman.yuan
Mentor
Mentor

ODTable.GetObjectDataTableRecords() returns Records (plural), its Count could be 0 (i.e. the eneity does not have any ODTable record attached to it).

 

As I pointed out in previous reply, see this line of code right after calling GetObjectTableRecords():

 

Dim odRecord As ObjectData.Record = odrecords(0) ''<--if odrecords.Count=0, this line of code will raise exception

 

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 6 of 8

jcoon
Enthusiast
Enthusiast

I was finally able to connect to a named table and display the value for item (0) for table obstacle, I'd like to ask another question; I'm looking for links that show how I could read and then set the the number of fields (items) in a table so I can display that data in a datagridview so I can edit item values.

 

second, is it possible to window autocad items and return the tables that are present in the window that I could then select from or place in a tree or combobox

 

Thanks for all your help

John.

 

 

<CommandMethod("ObjectdataReadrecords2")> _
    Public Sub ObjectdataReadrecords2()
        Dim acaddoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()
        Dim db As Database = HostApplicationServices.WorkingDatabase

        Dim acMapApp As MapApplication = HostMapApplicationServices.Application
        Dim acActiveProject As Project.ProjectModel = acMapApp.ActiveProject
        Dim acTableList As Tables = acActiveProject.ODTables
        Dim findtable As String = "obstacle" 'table name
        Dim trans As Transaction = db.TransactionManager.StartTransaction()
        Try

        Dim returnval As Integer = 0
            Dim mapvalstr As String
            Dim mapvalodstr As String
        Dim tables As ObjectData.Tables = HostMapApplicationServices.Application.ActiveProject.ODTables
        Using doclock As DocumentLock = acaddoc.LockDocument
                Using mytrans As Transaction = db.TransactionManager.StartTransaction
                    'Open the Block table for read
                    Dim acBlkTbl As BlockTable
                    Dim acBlkTblRec As BlockTableRecord

                    '' Open Model space for write
                    acBlkTbl = mytrans.GetObject(db.BlockTableId, OpenMode.ForRead)
                    acBlkTblRec = mytrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                    Dim odrecords As ObjectData.Records = tables.GetObjectRecords(0, acBlkTblRec.ObjectId, Constants.OpenMode.OpenForRead, False)
                    If odrecords.Count > 0 Then
                        For Each odrec As ObjectData.Record In odrecords
                            If odrec.TableName.ToUpper = findtable.ToUpper Then
                                mapvalstr = odrec.ToString
                                returnval += 1
                                mapvalodstr = odrec.Item(0).StrValue
                                ed.WriteMessage(vbCrLf + vbLf & "Record from Item(0)" & mapvalodstr.ToString)
                            End If
                        Next
                    End If
                    mytrans.Abort()
                End Using 'transaction
        End Using 'document lock  
        Catch ex As Exception
        End Try
    End Sub

 

0 Likes
Message 7 of 8

norman.yuan
Mentor
Mentor

If I understand you correcctly: you want to dispaly the OD data in a tabular format, such as in a gridview. So, the first thing you need to do is to define the gridview's column (fields of the ODTable), while before your code runs you may not know what fields an ODTable has.

 

You can get ODTable's fields (name, value type..) from ODTable.FieldDefinitions property. Once you know the ODTable's field names, value types, then you can dynamically added columns in GridView. Then you retrieve OD records into a IList collection and bind the collection to the GridView. It sounds quite simple, but the code might be quite long for doing thisSmiley Sad.

 

As for your second question, yes, instead of looping through all entities in modelspace, you first do a window selection, using one of the Editor.SelectXXXX() method to obtain a SelectionSet of entities. You can apply properly defined filter to narrow down the target entities being seleccted. Then you only loop through the smaller set of entities to retrieve ObjectData.

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 8 of 8

jcoon
Enthusiast
Enthusiast

norman.yuan,

 

I was able collect the FieldDefinitions and then the ObjectData.FieldDefinition for the named table and the map record values. It's been very busy at work so I had to put this down for awhile, but with your help I was able to move it along a little more. I'll try to tackle the grid next.

thank you

john

 

0 Likes