Kean Walmsley

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Twitter Updates

    follow me on Twitter



    « Creating an AutoCAD table using .NET | Main | Embedding fields in an AutoCAD table using .NET »

    June 08, 2007

    TrackBack

    TrackBack URL for this entry:
    http://www.typepad.com/services/trackback/6a00d83452464869e200df35222dae8834

    Listed below are links to weblogs that reference Creating an AutoCAD table containing block images using .NET:

    Comments

    Muito bom este exemplo.
    Aguardo um com a manipulação de campos, como criar e alterar campos no documento. Valeu.

    " Very good this sample.
    I wait one with the manipulation of Fields, as to create and to modify fields in the document.
    It was valid."

    Kean, can you provide an example for putting another block into the same cell and changing cell layout (to horizontal layout or to vertical layout) in 2008?
    Fields and formulas are of great interest too.

    A minha ideia é a seguinte:
    1 - Criar um dialógo para selecionar um arquivo txt delimitado.
    2 - E fazer a inserção dos valores na tabela.
    Sei que isso eh possível no Autocad 2008, inserindo uma planilha do excel. Mais o interesse aqui é manipular via NET.
    Com isso, teriamos abordado 3 conceitos.
    - a utilização de diálogos no cad;
    - a manipulação de dados externos vindo do arquivo txt; e
    - a manipulação da tabela.
    Valeu.

    " My ideia is the following one:
    1 - To create one dialógo to select an archive txt delimited.
    2 - E to make the insertion of the values in the table.
    I know that this eh possible in Autocad 2008, inserting a spread sheet of excel. More the interest is here to manipulate way NET.
    With this, we teriamos boarded 3 concepts.
    - the use of dialogue in cad;
    - the manipulation of external data come of the archive txt;
    - e manipulation of the table.
    It was valid."

    Kélcyo,

    Yes, I could certainly show this, but the pieces related to AutoCAD's APIs have already been shown in this code. The additional work (file selection and reading) are standard tasks that are relatively easy to accomplish with the .NET Framework (and I'm sure are covered by blog posts/articles elsewhere). Once you've populated your array of strings, the above code can be hooked in easily enough.

    Thanks for the suggestion, though.

    Regards,

    Kean

    OPPPS that's again gr8....

    I did it in 2001 by using VB 6.. Thanks for this tut for Dot Net....

    Sunilkumar S. (SUKU)
    www.suncindia.com

    hello i found your tutorial very informing but i have a problem applying it...

    when i use the code for typical blocks it works perfectly but when the code works on a block that contains an attribute autocad crashes with an error - handle reentered...
    i tried using the setblockattribute method in hope it will fix it but to no avail.

    i would really apreciate if you could help because i have a complete addon program which is pending on this bug only

    Yes... I see the same behaviour: the code wasn't designed to work with blocks with attributes.

    I added some code, after the call to tb.SetBlockTableRecordId():

    BlockTableRecord blockDef =
    (BlockTableRecord)tr.GetObject(
    objId,
    OpenMode.ForRead
    );
    foreach (ObjectId id in blockDef)
    {
    DBObject obj =
    tr.GetObject(id, OpenMode.ForRead);
    AttributeDefinition att =
    obj as AttributeDefinition;
    if (att != null)
    tb.SetBlockAttributeValue(i, 3, id, att.Tag);
    }

    This - as you've noticed - also fails, unless we change the transaction type by calling StartOpenCloseTransaction() instead of StartTransaction(). This creates a transaction type that (under the covers) uses Open & Close to access database-resident objects.

    This type of transaction was added in 2009, so if you're using a previous version your only real option would be to translate all your calls to the transaction into individual ObjectId.Open() and ObjectId.Close() calls.

    Assuming there's no way to get the standard transaction to work (the Open/Close Transaction was added to help deal with situations where finer grained access control is required by AutoCAD, and I suspect this is one of those situations).

    Otherwise you might also try separating the table creation from the code to set the attribute values (by collecting the info in some kind of structure and adding it after the fact). This might also help.

    Good luck,

    Kean

    Greeting Kean

    thank you very much for replying

    unfortunately am using autocad 2008 so i had to try replacing transaction calls with open\close methods and it worked great for the task but a side problem happened, it seems that something is not closed in the database so i cannot select the table and cannot save the file, after checking for a bit i found that i didn't close the table object, after i closed it i can select the table but any modification such as moving the table or trying to save the file i get an error eisalready in database.
    here is the code for you so you can get a clear picture

    this is a function i made that creates a table based on a filled array of blocks to generate a legend...

    Public Sub Create_Table(ByVal RowCount As Integer, ByVal RowHeight As Double, ByVal ColumnWidth As Double, ByVal Position As Point3d, ByVal Symbols() As String)
    Dim tb As Table = New Table
    Dim doc As Document = Application.DocumentManager.MdiActiveDocument
    Using db As Database = doc.Database
    Using tr As Transaction = db.TransactionManager.StartTransaction
    Dim Dlock As DocumentLock = Application.DocumentManager.MdiActiveDocument.LockDocument()
    Dim bt As BlockTable = db.BlockTableId.Open(OpenMode.ForRead)
    tb.TableStyle = db.Tablestyle
    tb.NumRows = RowCount + 2
    tb.NumColumns = 2
    tb.SetRowHeight(RowHeight)
    tb.SetColumnWidth(ColumnWidth)
    tb.Position = Position


    tb.SetTextHeight(RowType.DataRow, 2.5)
    tb.SetTextHeight(RowType.HeaderRow, 2.5)
    tb.SetTextHeight(RowType.TitleRow, 1)
    tb.SetAlignment(CellAlignment.MiddleCenter, RowType.DataRow)
    tb.SetAlignment(CellAlignment.MiddleCenter, RowType.HeaderRow)
    tb.SetAlignment(CellAlignment.MiddleCenter, RowType.TitleRow)

    tb.SetTextString(0, 0, "Legend")
    tb.SetTextString(1, 0, "Symbol Name")
    tb.SetTextString(1, 1, "Symbol Image")


    Dim Row As Integer = 1
    Dim i As Integer = 0
    Dim Scaling_Factor As Double = 1

    For i = 0 To RowCount
    If bt.Has(Symbols(i)) Then

    tb.SetBlockTableRecordId(Row, 0, bt(Symbols(i)), True)
    Dim objid As ObjectId = tb.GetBlockTableRecordId(Row, 0, 0)
    Dim blockdef As BlockTableRecord = objid.Open(OpenMode.ForRead)

    For Each id As ObjectId In blockdef
    Dim obj As DBObject = id.Open(OpenMode.ForRead)
    If TypeOf (obj) Is AttributeDefinition Then
    Dim att As AttributeDefinition = obj
    tb.SetBlockAttributeValue(Row, 0, id, att.TextString)
    End If
    obj.Close()
    Next
    Row = Row + 1
    blockdef.Close()
    End If
    Next i
    tb.GenerateLayout()

    Dim btr As BlockTableRecord = bt(BlockTableRecord.PaperSpace).Open(OpenMode.ForWrite)
    'Dim btr As BlockTableRecord = tr.GetObject(bt(BlockTableRecord.PaperSpace), OpenMode.ForWrite)
    btr.AppendEntity(tb)

    tr.Commit()

    btr.Close()
    bt.Close()

    db.Dispose()
    btr.Dispose()
    bt.Dispose()
    Dlock.Dispose()
    tb.Close()
    tb.Dispose()
    tr.Dispose()
    GC.Collect()

    End Using
    End Using

    End Sub

    One thing I can see straightaway is that you're still creating and committing the transaction - which is both unnecessary and potentially dangerous (you should avoid mixing transactions with open/close).

    Other than that I can't see what the problem is, though you might try reducing the time the various objects are open (the block table could be closed sooner, if you collect the info you need and then close it, for instance).

    Regards,

    Kean

    Greetings Kean

    thanks again for your prompt reply

    to tell you the truth i first tried it without using the transaction and i got an access violation error so when i used the transaction it worked...

    for the tr.commit it was the only way for the table to render without the code ran and nothing happened...

    for the block table i'll try to close it sooner and see what happens and as for the tb.close i cannot put it sooner than the document lock or i will get the already in database error at the moment the code is run..

    btw i remember that the code ran correctly when the table doesn't have a blocks with attributes.

    I am veteran in working Autocad. I like a lot what you have programmed. It is brilliant. I want to use it but i don t know how to.Can i convert it to autolisp? You can help me if you want.

    It should be possible. Unfortunately I don't have time to spend on converting posts to other languages... someone on the AutoLISP Discussion Group may be able to help.

    Kean

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search