BlackBox Posted April 16, 2013 Posted April 16, 2013 For kicks... What happens when you try the same declaration in a class with only Autodesk Imports statements (i.e., using AutoCAD 2010-2012 .NET Wizards, etc.)...??? Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 For kicks... What happens when you try the same declaration in a class with only Autodesk Imports statements (i.e., using AutoCAD 2010-2012 .NET Wizards, etc.)...??? I followed that wizard as it showed. So I created a new project (a plugin, not a windows form) and I was able to delcare my AcadApplication variable correctly (not amiguous this time). Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 For kicks... What happens when you try the same declaration in a class with only Autodesk Imports statements (i.e., using AutoCAD 2010-2012 .NET Wizards, etc.)...??? Now for the very weird part ... I copy pasted my project folder to another location in an attempt to delete stuff without screwing the whole thing up. All my references are working! Quote
Alex_AMF Posted April 16, 2013 Author Posted April 16, 2013 Thanks heh ... It's just not working in the place I want it to lol I wanted it to work in the C:\ directory not my Project Backups haha I'll see what I can do with that tomorrow. Thanks for all the help! Quote
Alex_AMF Posted April 17, 2013 Author Posted April 17, 2013 The reference problem was caused by having these two references at the same time: Quote
BlackBox Posted April 17, 2013 Posted April 17, 2013 The only real COM coding I do is with Visual LISP (ActiveX COM API), for .NET development even when I interact with COM it's to access non-.NET API exposed Objects in my plug-ins, so that is something I completely overlooked in your prior screen shot(s)... Thanks for coming back to post the solution. Quote
Alex_AMF Posted April 17, 2013 Author Posted April 17, 2013 Thanks a lot to you BlackBox, you helped a lot! Here's the answer on how to retrieve blocks: Public dic_Contents As New SortedDictionary(Of Integer, List(Of String)) Public Function GetBlockContents(ByVal vActiveDoc As AcadDocument) Try CleanSelectionSets(vActiveDoc) For y As Integer = 0 To sSet1.Count - 1 Dim myObj = sSet1.Item(y).GetAttributes FillStock2(sSet1.Count, myObj, y) Next Catch ex As Exception MsgBox(ex.Message) End Try Return dic_Contents End Function Private Sub CleanSelectionSets(ByVal vActiveDoc As AcadDocument) 'Remove all selection sets from the drawing (if any) System.Threading.Thread.Sleep(500) For Each selSet As AcadSelectionSet In vActiveDoc.SelectionSets System.Threading.Thread.Sleep(500) selSet.Delete() System.Threading.Thread.Sleep(500) Next sSet1 = vActiveDoc.SelectionSets.Add("selstock2") sSet2 = vActiveDoc.SelectionSets.Add("selrevis1") sSet3 = vActiveDoc.SelectionSets.Add("selblocknt") System.Threading.Thread.Sleep(500) sSet1 = GetBlockSet(vActiveDoc, "STOCK2") sSet2 = GetBlockSet(vActiveDoc, "REVIS1") sSet3 = GetBlockSet(vActiveDoc, "BLOCKNT") End Sub Private Function GetBlockSet(ByVal vActiveDoc As AcadDocument, ByVal BlockName As String) System.Threading.Thread.Sleep(500) Dim BlockSet As AcadSelectionSet Dim dxfCode(1) As Short Dim dxfValue(1) As Object System.Threading.Thread.Sleep(500) For Each selSet As AcadSelectionSet In vActiveDoc.SelectionSets System.Threading.Thread.Sleep(500) If selSet.Count > 0 Then If selSet.Name = BlockName Then selSet.Delete() Else Exit For End If Next BlockSet = vActiveDoc.SelectionSets.Add(BlockName) dxfCode(0) = 0 dxfCode(1) = 2 dxfValue(0) = "INSERT" dxfValue(1) = BlockName BlockSet.Select(Common.AcSelect.acSelectionSetAll, , , dxfCode, dxfValue) Return BlockSet End Function Private Sub FillStock2(ByVal NumBlocks As Integer, ByVal BlockSet As Object, ByVal k As Integer) Dim PartNo As String = "" Dim Qty As String = "" Dim ItemNo As String = "" Dim myList As New List(Of String) For y As Integer = 0 To UBound(BlockSet) Select Case BlockSet(y).TagString Case "PART" PartNo = BlockSet(y).TextString.ToUpper Case "QTY" Qty = BlockSet(y).TextString.ToUpper Case "ITEM" ItemNo = BlockSet(y).TextString.ToUpper End Select Next myList.Add(PartNo) myList.Add(Qty) dic_Contents.Add(CInt(ItemNo), myList) End Sub My dictionary contents will be populated with the part numbers and their quantities. All of them being identified by the dictionary key of their item number (all sorted correctly using the sorted dictionary). If anyone would enlighten me on how to create a better alternative for the "Thread.Sleep(500)" that would be awesome! I seem to always get the following error when I'm cleaning the selection sets (but not if i step through the program slowly...): Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED) Quote
Alex_AMF Posted April 17, 2013 Author Posted April 17, 2013 I found a great alternative to the "Thread.Sleep(X)" ... Since that can over-wait or under-wait certain processes depending on the computer / server speed, I used Microsoft's fix for the Call Rejected by Callee errors: http://msdn.microsoft.com/en-us/library/vstudio/ms228772(v=vs.100).aspx Transformed that into VB.NET code, and simply added "MessageFilter.Register()" before any COM automations, followed by MessageFilter.Revoke() after the COM automation had finished. Hope it can help someone else Quote
BlackBox Posted April 17, 2013 Posted April 17, 2013 Thanks a lot to you BlackBox, you helped a lot! You're welcome; that is kind of you to say. If anyone would enlighten me on how to create a better alternative for the "Thread.Sleep(500)" that would be awesome! Methinks you will see a significant gain in efficiency if you instead iterate the BlockTable conditionally filtering each BlockTableRecord for those identified as needed... This would also make your code more portable for batch processing. Quote
BlackBox Posted April 17, 2013 Posted April 17, 2013 (edited) Methinks you will see a significant gain in efficiency if you instead iterate the BlockTable conditionally filtering each BlockTableRecord for those identified as needed... This would also make your code more portable for batch processing. Here's a quick .NET API Method in C# (sorry on both counts, ), for you to pull from, as an example: void Foo() { Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr = (BlockTable)tr.GetObject(db.[blockTableRecord.ModelSpace], OpenMode.ForRead); foreach (ObjectId id in btr) { BlockReference br = tr.GetObject(id, OpenMode.ForRead) as BlockReference; if (br != null) { switch (br.Name.ToUpper()) { case "STOCK2" : //<-- do STOCK2 work case "REVIS1" : //<-- do REVIS1 work case "BLOCKNT" : //<-- do BLOCKNT work default : break; } } } tr.Commit(); } } Edited April 17, 2013 by BlackBox Code correction; you want to iterate BlockTableRecord.ModelSpace and not the BlockTable itself. Quote
Alex_AMF Posted April 17, 2013 Author Posted April 17, 2013 Cool Thanks! I'll need to do .NET API work eventually so I'll definately look into that. Also I'll probably optimise this whole thing once it's completed. Or when I have less work to do. Till then, take care Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.