Results 1 to 7 of 7

Thread: Help with inserting blocks

  1. #1
    Member
    Join Date
    2010-08
    Posts
    39

    Default Help with inserting blocks

    New to .NET, here's the the setup, windows form with 4 buttons each inserting a different block. I'm attempting to pass the block name from the button click event to a sub routine that checks if block exists. Then insert if yes, or insert source dwg with block and then insert if no. So far if the block exists all t works but throws self reference exception. if it does not, then code is failing at inserting the source drawing, it throws security exceptions and a self reference issue. any thoughts? maybe move the insertion portion up to the sub routine instead of button click event? anyways heres the code so far:
    Code:
    Imports System
    Imports Autodesk.AutoCAD.Runtime
    Imports Autodesk.AutoCAD.ApplicationServices
    Imports Autodesk.AutoCAD.DatabaseServices
    Imports Autodesk.AutoCAD.Geometry
    Imports Autodesk.AutoCAD.EditorInput
    
    Public Class StallCounterInterface
    
        Public Sub blocktest(ByVal BlockName As String)
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                If bt.Has(BlockName) Then
                    MsgBox("Yon Block Doth Exist-eth!")
                Else
                    Dim id As ObjectId
                    Dim stallblk As New Database(False, True)
                    stallblk.ReadDwgFile("C:\\mkacadd_Hybrid\\Civil3D\\CAD data\\Support\\Blocks\\StallCount.dwg", IO.FileShare.Read, True, "")
                    id = db.Insert(BlockName, stallblk, True)
                    stallblk.Dispose()
                End If
            End Using
        End Sub
    
    
        Private Sub StdBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StdBtn.Click
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim BlockName As String
            BlockName = "Standard"
            Call blocktest(BlockName)
            Dim loopcontrol As Boolean = True
            Do While loopcontrol
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    'get insertion point
                    Dim ppo As New PromptPointOptions(vbLf & "Specify insertion point: ")
                    Dim ppr As PromptPointResult = ed.GetPoint(ppo)
                    Dim pt As Point3d = ppr.Value
                    'create block ref
                    Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                    Dim br As New BlockReference(pt, bt("Standard"))
                    Dim btr As BlockTableRecord = DirectCast(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                    btr.AppendEntity(br)
                    tr.AddNewlyCreatedDBObject(br, True)
                    tr.Commit()
                End Using
            Loop
        End Sub

  2. #2
    AUGI Addict fixo's Avatar
    Join Date
    2005-05
    Location
    Pietari, Venäjä
    Posts
    1,216

    Default Re: Help with inserting blocks

    Think you may want to use this possible way,
    You can add a boolean variable inside your class,
    then use it after in your subs:

    Code:
    Public Class StallCounterInterface
    private blockexist as boolean=true
        Public Sub blocktest(ByVal BlockName As String)
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                If bt.Has(BlockName) Then
    blockexists=true
                    MsgBox("Yon Block Doth Exist-eth!")
                Else
    blockexists=false
                    Dim id As ObjectId
                    Dim stallblk As New Database(False, True)
                    stallblk.ReadDwgFile("C:\\mkacadd_Hybrid\\Civil3D\\CAD data\\Support\\Blocks\\StallCount.dwg", IO.FileShare.Read, True, "")
                    id = db.Insert(BlockName, stallblk, True)
                    stallblk.Dispose()
                End If
            End Using
        End Sub
    Or you can rewrite you Sub blocktest as function to retrieve boolean variable

    ~'J'~
    "The whole problem with the world is that fools and fanatics are always
    so certain of themselves, and wiser people so full of doubts."
    Bertrand Russell

  3. #3
    Member
    Join Date
    2010-08
    Posts
    39

    Default Re: Help with inserting blocks

    fixo, thanks for the response not quite what i was going for, but i had other problems to begin with. So i re-wrote the code and have since solved my original problem, so on to the next problem! so now i want to grab the current layer, set it to something else, insert my blocks and then restore the original layer upon exiting the program (with an exit button) so heres the code i have so far:
    Code:
    Imports System
    Imports Autodesk.AutoCAD.Runtime
    Imports Autodesk.AutoCAD.ApplicationServices
    Imports Autodesk.AutoCAD.DatabaseServices
    Imports Autodesk.AutoCAD.Geometry
    Imports Autodesk.AutoCAD.EditorInput
    
    ' This line is not mandatory, but improves loading performances
    <Assembly: CommandClass(GetType(Stall_Counter_Redux.StallCount))> 
    
    Namespace Stall_Counter_Redux
        Public Class StallCount
            <CommandMethod("Staller")> _
            Public Sub GUI()
                'gets current doc and database
                Dim doc As Document = Application.DocumentManager.MdiActiveDocument
                Dim db As Database = doc.Database
                'start transaction, access layertable, grab current layer, change to c-vprt.
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    Dim LayTable As LayerTable = tr.GetObject(db.LayerTableId, OpenMode.ForRead)
                    Dim ltr As LayerTableRecord = CType(tr.GetObject(db.Clayer, OpenMode.ForRead), LayerTableRecord)
                    Dim curlay As String = "C-VPRT"
                    If LayTable.Has(curlay) = True Then
                        db.Clayer = LayTable(curlay)
                        tr.Commit()
                    End If
                End Using
                'initiate form
                Dim myform As New StallCounterInterface
                Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(myform)
            End Sub
        End Class
    End Namespace
    and then the actual form/user interface:
    Code:
    Imports System
    Imports Autodesk.AutoCAD.Runtime
    Imports Autodesk.AutoCAD.ApplicationServices
    Imports Autodesk.AutoCAD.DatabaseServices
    Imports Autodesk.AutoCAD.Geometry
    Imports Autodesk.AutoCAD.EditorInput
    
    Public Class StallCounterInterface
    
        Public Sub blocktest(ByVal BlockName As String)
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            'test if block exists
            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                If bt.Has(BlockName) Then
                    ed.WriteMessage(vbLf & "block exists, now inserting!")
                Else
                    MsgBox("not found, insert source file")
                    Exit Sub
                End If
            End Using
            Dim LoopControl As Boolean = True
            Do While LoopControl
                doc.LockDocument()
                Me.Hide()
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                    Dim id As ObjectId = bt(BlockName)
                    ' Get insertion point
                    Dim ppo As New PromptPointOptions(vbLf & "Specify insertion point, press [ESC] to return:")
                    Dim ppr As PromptPointResult = ed.GetPoint(ppo)
                    ' Exit if the user presses ESC or cancels the command
                    If ppr.Status = PromptStatus.Cancel Then Exit Do
                    If ppr.Status = PromptStatus.OK Then
                        Dim pt As Point3d = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem)
                        ' Create a block reference
                        Dim br As New BlockReference(pt, id)
                        ' Get Model space
                        Dim btr As BlockTableRecord = DirectCast(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                        ' Add the block reference to Model space
                        btr.AppendEntity(br)
                        tr.AddNewlyCreatedDBObject(br, True)
                        tr.Commit()
                    End If
                End Using
            Loop
            Me.Show()
            BlockName = Nothing
        End Sub
    
        Private Sub StdBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StdBtn.Click
            Dim BlockName As String = "Standard"
            blocktest(BlockName)
        End Sub
    
        Private Sub CompBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CompBtn.Click
            Dim BlockName As String = "Compact"
            blocktest(BlockName)
        End Sub
    
        Private Sub VanBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VanBtn.Click
            Dim BlockName As String = "Van"
            blocktest(BlockName)
        End Sub
    
        Private Sub HandBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HandBtn.Click
            Dim BlockName As String = "Handicap"
            blocktest(BlockName)
        End Sub
    ' This where i want to reset the layer to before the app was started.
        Private Sub ExitBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitBtn.Click
            Me.Close()
        End Sub
    End Class
    so what i need help with is passing "ltr" between classes, finding alot on passing between forms, but not classes.

  4. #4
    AUGI Addict fixo's Avatar
    Join Date
    2005-05
    Location
    Pietari, Venäjä
    Posts
    1,216

    Default Re: Help with inserting blocks

    You may want to use next method
    Add Module in your project:
    Code:
        Module Module1
            Public ltr As String = "C-VPRT"     '<-- change layer name or kept them as empty string
        End Module
    Inside your working process you can set this value as you need.

    Then after you've finish your job, add this sub on form code module:

    Code:
        Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs)
            If e.CloseReason = CloseReason.UserClosing Then
                Dim result = MessageBox.Show("Do you want to reset the current layer?", "Question", MessageBoxButtons.YesNo)
                If result <> System.Windows.Forms.DialogResult.Yes Then
                    Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("clayer", ltr)
                    e.Cancel = True
                End If
            End If
        End Sub
    Not tested, just from the top of my head

    ~'J'~
    "The whole problem with the world is that fools and fanatics are always
    so certain of themselves, and wiser people so full of doubts."
    Bertrand Russell

  5. #5
    Member
    Join Date
    2010-08
    Posts
    39

    Default Re: Help with inserting blocks

    Hrmm we're on the right path, but i need to access that module immediateily after the command method, and before i change the current layer.
    module code:
    Code:
    Imports Autodesk.AutoCAD.ApplicationServices
    Public Module Laycurrent
        Public laycur As String = Application.GetSystemVariable("Clayer")
    End Module
    app intialization:
    Code:
    Namespace Stall_Counter_Redux
        Public Class StallCount
            <CommandMethod("Staller")> _
            Public Sub GUI()
                'gets current doc and database
                Dim doc As Document = Application.DocumentManager.MdiActiveDocument
                Dim db As Database = doc.Database
                'start transaction, access layertable, grab current layer, change to c-vprt.
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    Dim LayTable As LayerTable = tr.GetObject(db.LayerTableId, OpenMode.ForRead)
                    Dim ltr As LayerTableRecord = CType(tr.GetObject(db.Clayer, OpenMode.ForRead), LayerTableRecord)
     access module and set Laycur before SetLay
                    Dim SetLay As String = "C-VPRT"
                    If LayTable.Has(SetLay) = True Then
                        db.Clayer = LayTable(SetLay)
                        tr.Commit()
                    End If
                End Using
                'initiate form
                Dim myform As New StallCounterInterface
                Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(myform)
            End Sub
        End Class
    End Namespace
    and finally the close button:
    Code:
    Private Sub ExitBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitBtn.Click
            Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("clayer", Laycurrent.laycur)
            Me.Close()
        End Sub
    Now i could jsut scrap this bit and set a static layer name and the button, but why not be extra spiffy about it if i can

  6. #6
    Member
    Join Date
    2010-08
    Posts
    39

    Default Re: Help with inserting blocks

    fixo i got it (yay me!)
    Code:
      Public Class StallCount
            <CommandMethod("Staller")> _
            Public Sub GUI()
                'gets current doc and database
                Dim doc As Document = Application.DocumentManager.MdiActiveDocument
                Dim db As Database = doc.Database
    call to module 
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("clayer", Laycurrent.lay2)
                'start transaction, get current layer, set layer to c-vprt.
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    Dim LayTable As LayerTable = tr.GetObject(db.LayerTableId, OpenMode.ForRead)
                    Dim SetLay As String = "C-VPRT"
                    If LayTable.Has(SetLay) = True Then
                        db.Clayer = LayTable(SetLay)
                        tr.Commit()
                    End If
                End Using
                'initiate form
                Dim myform As New StallCounterInterface
                Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(myform)
            End Sub
        End Class
    module sets clayer to static lay2
    Code:
    Imports Autodesk.AutoCAD.ApplicationServices
    Public Module Laycurrent
        Public laycur As String = Application.GetSystemVariable("Clayer")
        Public lay2 = laycur
    End Module
    then exit button calls on lay2
    Code:
    Private Sub ExitBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitBtn.Click
            Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("clayer", Laycurrent.lay2)
            Me.Close()
        End Sub
    End Class

  7. #7
    AUGI Addict fixo's Avatar
    Join Date
    2005-05
    Location
    Pietari, Venäjä
    Posts
    1,216

    Default Re: Help with inserting blocks

    Hey, sounds good, I often use same way
    Happy coding
    Cheers

    ~'J'~
    "The whole problem with the world is that fools and fanatics are always
    so certain of themselves, and wiser people so full of doubts."
    Bertrand Russell

Similar Threads

  1. inserting (annotative) blocks
    By n_withers in forum AutoCAD Tables
    Replies: 1
    Last Post: 2009-08-21, 08:26 PM
  2. Inserting blocks
    By JSelf in forum VBA/COM Interop
    Replies: 1
    Last Post: 2008-08-07, 05:07 PM
  3. Inserting Blocks
    By Luke_W in forum AutoCAD General
    Replies: 2
    Last Post: 2007-11-08, 01:34 PM
  4. Inserting Multiple Blocks
    By Statler in forum AutoCAD General
    Replies: 1
    Last Post: 2007-01-03, 12:09 PM
  5. Inserting Blocks into a drawing containing an X-Ref
    By jm.pearson in forum AutoCAD General
    Replies: 8
    Last Post: 2006-02-20, 05:39 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •