layerlist by selection

layerlist by selection

jan_tappenbeck
Collaborator Collaborator
617 Views
3 Replies
Message 1 of 4

layerlist by selection

jan_tappenbeck
Collaborator
Collaborator

Hi!

i want to create a function to get a layerlist with selection.

 

default the LyFilter will be * and than all layers should be return. even a list of selectiondefintions (ex. Building, Street_*) should be possible.

 

the parameter IgnoreXrefLayer current will not be used!

 

my code current looks like

 

    Public Function GetLayerList(Optional ByVal LyFilter As String = "*", _
                                 Optional ByVal IgnoreXrefLayer As Boolean = False, _
Optional ByVal IgnoreNull As Boolean = True, _
Optional ByVal IgnoreDefPoints As Boolean = True _
) As List(Of String)
        ' ------ http://ma22-wiki-001/eblwiki/index.php?title=Acad_(Klasse_von_EBL.Service)#GetLayerList ------

        AcReInit()
        Dim docs As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
        Dim listOfLayers As List(Of String) = New List(Of String)
        Dim StatusIgnore As Boolean = False
        Dim Filterliste As New List(Of String)

        Dim FilterSplit As String() = LyFilter.Split({","}, StringSplitOptions.RemoveEmptyEntries)
        For i As Integer = 0 To FilterSplit.Count - 1
            Filterliste.Add(FilterSplit(i))
        Next i

        Try
            Using tr As Transaction = _AcDocument.TransactionManager.StartTransaction
                Dim lt As LayerTable = DirectCast(tr.GetObject(_Database.LayerTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead, False), LayerTable)
                For Each lid As ObjectId In lt
                    StatusIgnore = False 'Reinit
                    Dim ltr As LayerTableRecord = tr.GetObject(lid, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)
                    If lid.IsValid Then
                        'Todo - hier noch XREF einbauen
                        Dim EinzelFilter() As String
                        Dim treffer As Boolean = False

                        'StatusIgnore = True
                        '' Filter ergänzen
                        ''For Each Filter As String In Filterliste
                        ''    If treffer = False Then
                        ''        Filter = Filter.Replace("*", ".*")  '* Regexkonform machen - kann das oben eingebaut werden??????
                        ''        EinzelFilter = Filter.Split(",") 'Zusammengefasste Filter trennen
                        ''        For Each FilterElement As String In EinzelFilter
                        ''            If Regex.IsMatch(ltr.Name, FilterElement) = True Then
                        ''                StatusIgnore = False
                        ''                Exit For
                        ''            End If
                        ''        Next
                        ''    End If
                        ''Next

                        ' dann auch entsprechend ergänzen
                        If ltr.Name.ToUpper = "0" And IgnoreNull = True Then StatusIgnore = True
                        If ltr.Name.ToUpper = "DEFPOINTS" And IgnoreDefPoints = True Then StatusIgnore = True
                        ' jetzt die Auswertung
                        If StatusIgnore = False Then listOfLayers.Add(ltr.Name)
                    End If
                Next
                tr.Commit()
            End Using

        Catch ex As Exception
            _TryReport.Show("unerwarteter Fehler in EBL.Service > Acad > GetLayerList", ex.ToString)
        End Try

        Return listOfLayers
    End Function

 

 

this functio will works - but when i try to use filters by wildcards there is a problem.

current in the code the part of a way to filter by the names will be comment. it not works correct - look this exampel:


test - layername: "__Layer2"
text - selection: "Layer.*"

 

 Layername:= __Layer2
 -- FilterElement:= Layer..*
 ----> Status:= True
 Layername:= Layer
 -- FilterElement:= .*Layer.*
 ----> Status:= True
 Layername:= Layer134
 -- FilterElement:= Layer..*
 ----> Status:= True
 Layername:= Haus
 -- FilterElement:= Haus
 ----> Status:= True
 Layername:= Layer208abc
 -- FilterElement:= Layer..*
 ----> Status:= True
 Layername:= Nadel
 ----> Status:= False
 Layername:= Personen
 -- FilterElement:= Personen
 ----> Status:= True

 

could someone help of has a better idea?

regards Jan

0 Likes
618 Views
3 Replies
Replies (3)
Message 2 of 4

ActivistInvestor
Mentor
Mentor

Your problem lies largely in the fact that you don't yet know how to write code in a way that prevents it from becoming unmanageable.

 

You should try to break a problem down into several smaller, and simpler problems.

 

For example, you should write a second function that performs the filtering of each layer name, and does nothing but that, like this:

 

 

Public Shared Function LayerNameMatches(name As String, pattern As String, allowZero As Boolean, allowDefPoints As Boolean) As Boolean
   name = name.ToUpper()
   If Not allowZero AndAlso name = "0" Then
      Return False
   ElseIf Not allowDefPoints AndAlso name = "DEFPOINTS" Then
      Return False
   Else
      Return Autodesk.AutoCAD.Internal.Utils.WcMatchEx(name, pattern, True)
   End If
End Function

 

 

You should also try to learn how to use logical operators and avoid using statements like If something = True or If something = False in your code, because it is redundant and confusing.

 

Instead of

 

If someboolean = True Then ...

you should use:

 

If someboolean Then ...

And instead of:

 

If someboolean = False then

you should use:

 

If Not someBoolean Then ...

@jan_tappenbeck wrote:

Hi!

i want to create a function to get a layerlist with selection.

 

default the LyFilter will be * and than all layers should be return. even a list of selectiondefintions (ex. Building, Street_*) should be possible.

 

the parameter IgnoreXrefLayer current will not be used!

 

 

 

this functio will works - but when i try to use filters by wildcards there is a problem.

current in the code the part of a way to filter by the names will be comment. it not works correct - look this exampel:


test - layername: "__Layer2"
text - selection: "Layer.*"

 

 Layername:= __Layer2
 -- FilterElement:= Layer..*
 ----> Status:= True
 Layername:= Layer
 -- FilterElement:= .*Layer.*
 ----> Status:= True
 Layername:= Layer134
 -- FilterElement:= Layer..*
 ----> Status:= True
 Layername:= Haus
 -- FilterElement:= Haus
 ----> Status:= True
 Layername:= Layer208abc
 -- FilterElement:= Layer..*
 ----> Status:= True
 Layername:= Nadel
 ----> Status:= False
 Layername:= Personen
 -- FilterElement:= Personen
 ----> Status:= True

 

could someone help of has a better idea?

regards Jan


 

0 Likes
Message 3 of 4

tbrammer
Advisor
Advisor

Try the wildcard to regex solution proposed here:

 

  // If you want to implement both "*" and "?"
  private static String WildCardToRegular(String value) {
    return "^" + Regex.Escape(value).Replace("\\?", ".").Replace("\\*", ".*") + "$"; 
  }

  // If you want to implement "*" only
  private static String WildCardToRegular(String value) {
    return "^" + Regex.Escape(value).Replace("\\*", ".*") + "$"; 
  }

Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 4 of 4

tbrammer
Advisor
Advisor

oops - accidently posted twice. Just ignore this.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes