Community
Hi,
Is it possible to search for presence of specific text in a closed drawing? I know that I can't use selectionsets in a closed drawing.
when searching block's I use this Code:
Using db As New Database(False, True) Try db.ReadDwgFile(PathAndFile, FileOpenMode.OpenForReadAndWriteNoShare, True, Nothing) Using MyTrans As Transaction = db.TransactionManager.StartTransaction() Dim bt As BlockTable = MyTrans.GetObject(db.BlockTableId, OpenMode.ForRead) For Each objId As ObjectId In bt Dim btr As BlockTableRecord = MyTrans.GetObject(objId, OpenMode.ForRead) If btr.Name.ToLower = BlockName.ToLower Then BlockIsPresent = True Exit For End If Next MyTrans.Commit() End Using Catch End Try End Using
But how to search for other items like text? Do I have to iterate to each single item in the database or is there a quicker way? how to do it?
kind regards
Wouter
Here is code excerpted from working project (A2014)
See if this helps, also remove unused References in 'Imports' region
Change data extraction path to your needs,
Require reference to AcDx.dll:
Imports System Imports System.Text Imports System.IO Imports System.Data Imports System.Reflection Imports System.Collections.Generic Imports System.Runtime.InteropServices Imports System.Text.RegularExpressions Imports System.Windows.Forms Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.Colors Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.DataExtraction Public Class DataExtract ''----------------------------------------------------------'' ' Example how to exract data into the .xml file in Debug folder ''----------------------------------------------------------'' '' based on Kean Walmsley's example from there: '' http://through-the-interface.typepad.com/through_the_interface/2008/04/extracting-data.html <CommandMethod("TDX")> _ Public Sub ExtractLines() Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor Dim starttime As Double Dim endtime As Double ' In the following example data extracted to "Lines.xml" file in Debug folder Dim filePath As String = Path.GetDirectoryName(Assembly.GetExecutingAssembly.Location) & "\MyTexts.xml" Dim dialog As New System.Windows.Forms.OpenFileDialog With dialog .CheckPathExists = True .CheckPathExists = True .DefaultExt = "dwg" .DereferenceLinks = True .Multiselect = False .Filter = "Drawing (*.dwg)|*.dwg|All files (*.*)|*.*" .Title = "Select drawing" .FilterIndex = 1 End With If dialog.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then Return End If Dim fname As String = dialog.FileName starttime = DateAndTime.Timer Try ''------------------------------------------------------------------------------------------------------'' ' following datatable easy to write to the any data file (Excel, Access, SQL etc) Dim dataTable As System.Data.DataTable = ExtractLines(fname) ''------------------------------------------------------------------------------------------------------'' endtime = DateAndTime.Timer '' write data to Lines.xml in the Debug folder '' change the full path name of the file if you want to save it in other folder dataTable.WriteXml(filePath) ed.WriteMessage(vbLf + "Elapsed time: {0:f4} seconds" + vbLf + "Found {1} objects" + vbLf, endtime - starttime, dataTable.Rows.Count) Catch ex As System.Exception MsgBox(vbCr & ex.ToString & vbCr & ex.StackTrace) End Try MsgBox("Wait tile .xml file will open...") '' Display the file Process.Start(filePath, Nothing) End Sub Public Function extractLines(ByVal fname As String) As System.Data.DataTable Dim dataTable As New System.Data.DataTable() Dim blkTable As New System.Data.DataTable() Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor Dim tags As New List(Of String)() If Not System.IO.File.Exists(fname) Then ed.WriteMessage(vbLf & "Drawing file does not exist.") Return Nothing Exit Function End If Dim es As IDxExtractionSettings = New DxExtractionSettings() Dim de As IDxDrawingDataExtractor = es.DrawingDataExtractor de.Settings.ExtractFlags = ExtractFlags.None Or ExtractFlags.ModelSpaceOnly de.Settings.ExtractFlags = ExtractFlags.ExtractBlockOnly ''Or ExtractFlags.ModelSpaceOnly Dim fr As IDxFileReference = New DxFileReference(Path.GetDirectoryName(fname), fname) de.Settings.DrawingList.AddFile(fr) ' Scan the drawing for object types & their properties de.DiscoverTypesAndProperties(Path.GetDirectoryName(fname)) Dim types As List(Of IDxTypeDescriptor) = de.DiscoveredTypesAndProperties ' Select all the types and properties for extraction ' by adding them one-by-one to these two lists Dim selTypes As New List(Of String)() Dim selProps As New List(Of String)() For Each type As IDxTypeDescriptor In types selTypes.Add(type.GlobalName) For Each pr As IDxPropertyDescriptor In type.Properties If Not selProps.Contains(pr.GlobalName) Then selProps.Add(pr.GlobalName) End If Next Next de.Settings.SetSelectedTypesAndProperties(types, selTypes, selProps) ' Now perform the extraction itself de.ExtractData(Path.GetDirectoryName(fname)) ' Get the results of the extraction dataTable = de.ExtractedData If dataTable.Rows.Count > 0 Then dataTable.TableName = "Texts" ' Change query to select text only Dim selrows As DataRow() = dataTable.Select("AcDxObjectTypeGlobalName Like '%Text'") ' To select lines, texts and mtexts next query used : ' Dim selrows As DataRow() = dataTable.Select("AcDxObjectTypeGlobalName Like '%Line' Or AcDxObjectTypeGlobalName Like '%Text' Or AcDxObjectTypeGlobalName Like '%MText'") blkTable = dataTable.Clone() For Each dr As DataRow In selrows blkTable.ImportRow(dr) Next '' commented code block, that is just for populating form listbox control 'Dim columns As String() = New String() {"AcDxObjectTypeName"} 'Dim dvw As DataView = blkTable.DefaultView 'distinctTable = dvw.ToTable(False, columns) 'Dim bnames As New List(Of String)() 'For Each dr As System.Data.DataRow In distinctTable.Rows ' Dim bname As String = dr(0).ToString() ' If Not bnames.Contains(bname) Then ' bnames.Add(bname) ' End If 'Next 'Me.lst.DataSource = bnames'' <-- to fill ListBox only 'lst.SelectedIndex = -1'' <-- set selected items to nothing End If Return blkTable End Function End Class
Take a look ath this page: