Тема: Выделить SelectionSet

Здравствуйте, господа!
Прошу прощения, что еще раз поднимаю извечную тему, но это правда очень необходимо!
Ясно, что SelectionSet не «выбрать» из VBA, это уже обсуждалось здесь: https://www.caduser.ru/forum/topic22906.html
и в других темах. Есть определенные проблемы с SendCommand “pSelect p  ”, например если до него в программе был .Select к другому набору выбора, то выбирается именно предыдущий, и другие ошибки…
Насколько я понимаю, AutoCAD может читать LISP-выражения напрямую через SendCommand. Нет ли универсального решения «выделить» MySset путем посыла LISP-выражений через SendCommand? (MySset as AcadSelectionSet)
Если бы нашлось такое решение, это навсегда сняло бы все вопросы по поводу несчастного ”выделения SelectionSet”…
Прошу, помогите!!

Re: Выделить SelectionSet

Нечто типа:

Sub SelectionSetHighlight(objSelSet As AcadSelectionSet)
Dim objEnt As AcadEntity
Dim sCommand As String
  sCommand = "(setq *selset* nil *selset* (ssadd))(mapcar '(lambda(x) (ssadd (handent x) *selset*)) '("
  For Each objEnt In objSelSet
    sCommand = sCommand & Chr(34) & objEnt.Handle & Chr(34)
  Next objEnt
  ThisDrawing.SendCommand sCommand & "))(sssetfirst *selset* *selset*)" & vbCr
End Sub

Написано на коленках. Возможно, есть другой, более простой способ.

Re: Выделить SelectionSet

> Кулик Алексей aka kpblc
Спасибо большое. Все работает. Вы спасли мой проект )).
Эй, ребята! Все сюда! Тут SelectionSet выделяют!! ))))
Вот только sCommand as String не резиновый к сожалению, для больших объемов не сработает. Надо, наверное, сюда же добавить некий предохранитель от переполнения, с последующим "довыделением"...

Re: Выделить SelectionSet

Отправил функциональные строчки:

sCommand = "(setq *selset* nil *selset* (ssadd))(mapcar '(lambda(x) (ssadd (handent x) *selset*)) '("
  For Each objEnt In objSelSet
    sCommand = sCommand & Chr(34) & objEnt.Handle & Chr(34)
  Next objEnt
  ThisDrawing.SendCommand sCommand & "))(sssetfirst *selset* *selset*)" & vbCr

в цикл, обрабатывающий входящий SelectionSet "по малым частям", чтобы не было переполнения в SendCommand. Но получилось, что программа выделяет эти куски по циклу, выделение "прыгает" по кускам, а не добавляет к сущестующему.
Как же изменить код, чтобы объекты добавлялись к текущему набору/выделению?

Re: Выделить SelectionSet

Все исправил. Вынес за цикл определение блока и конечное выделение. Переработав идеи Кулика Алексея aka kpblc, я родил код, нормально выделяющий любой SelectionSet путем посыла LISP-команд через SendCommand. Вот он:

Public Sub st_MakeSsetActive(eSset As AcadSelectionSet)
On Error GoTo MyError
If eSset.Count = 0 Then
    Exit Sub
End If
[i]'чтобы не портить входящий набор - переобозначим[/i]
Dim usedSset As AcadSelectionSet
Set usedSset = eSset
Dim objEnt As AcadEntity
Dim myEntArr() As AcadEntity
Dim sCommand As String
Dim i As Integer
Dim k As Integer: k = 9
[i]'первая LISP-строчка. определяет LISP-набор[/i]
ThisDrawing.SendCommand "(setq *selset* (ssadd))" & vbCr
[i]'исходный набор будем брать кусками по 10, чтобы не переполнялся SendCommand[/i]
Do
    [i]'определим массив Entity для манипуляций с наборами[/i]
    If usedSset.Count < 10 Then
        k = usedSset.Count - 1
    End If
    ReDim myEntArr(k)
    sCommand = "(mapcar '(lambda(x) (ssadd (handent x) *selset*)) '("   '(1)
    For i = 0 To k
        Set myEntArr(i) = usedSset(i)
        sCommand = sCommand & Chr(34) & myEntArr(i).Handle & Chr(34)    '(2)
    Next
    sCommand = sCommand & "))"                                          '(3)
    '[i]через эту строчку объекты добавляются в LISP-набор[/i]
    ThisDrawing.SendCommand sCommand & vbCr
    [i]'удалим уже записанные элементы из обрабатываемого набора[/i]
    usedSset.RemoveItems myEntArr
Loop While usedSset.Count <> 0
[i]'последняя часть[/i]
[i]'выделение набора, полученного с помощью LISP[/i]
ThisDrawing.SendCommand "(sssetfirst *selset* *selset*)" & vbCr
Exit Sub
MyError:
myMsg "Ошибка в st_MakeSsetActive"
End Sub

Тестим и говорим еще раз спасибо огромное Алексею!

Re: Выделить SelectionSet

> StudentCM
Я бы не торопился, посмотри внимательно, что
он посылает в цикл For Next
Ты в соостоянии оценить какая строка там
реально создается?
Проверь через Debug.Print sCommand
:)
~'J'~

Re: Выделить SelectionSet

> StudentCM
Я бы сделал так
Для примера выделяем на экране облегченные
полилинии:

Option Explicit
Sub GripTest()
   Dim oSset As AcadSelectionSet
   Dim vType(0) As Integer
   Dim vData(0) As Variant
   vType(0) = 0
   vData(0) = "LWPOLYLINE"
          With ThisDrawing.SelectionSets
               While .Count > 0
                    .Item(0).Delete
               Wend
          Set oSset = .Add("$GripTest$")
          End With
   oSset.SelectOnScreen vType, vData
   ThisDrawing.SendCommand "(sssetfirst (setq *selset* (ssget " & Chr(34) & "_P" & Chr(34) & "))" & _
                           "(ssget " & Chr(34) & "_P" & Chr(34) & "))" & vbCr
   MsgBox "Gripped and highlighted"
   oSset.Highlight False
   MsgBox "Will gripped only"
   MsgBox "Will ungripped"
   ThisDrawing.SendCommand Chr(27) & Chr(27) & Chr(27)
   MsgBox "Ungripped"
End Sub

А для проверки набери в командной строке после
завершения:

(sslength *selset*)

- увидишь количество полилиний входящих в набор,
т.е. переменная *selset* сохраняется
~'J'~

Re: Выделить SelectionSet

я просто не спец в лиспе вообще... а строки я смотрел нажатием F2.
Оценить корректность этих строк я немогу, только по смыслу понимаю что к чему в первой и последней строке, разбирался по инету.. лямбда же мне никак не далась, да и времени не было :(
но все вроде работает )).

Re: Выделить SelectionSet

> StudentCM
Совершенно здравая мысль, я тоже не стороник
переделывать что-то, что 100% рабочее
Здесь скорее речь об рациональности кода
и ничего более
~'J'~