Тема: Как передать набор примитивов автокадовской команде?

Задача такая - создаю программными средствами набор примитивов в виде ThisDrawing.ActiveSelectionSet и хочу применить к нему команду PROPERTIES. Однако как передать этот набор команде для обработки, не могу придумать. Может кто-нибудь сталкивался с подобной коллизией?

Re: Как передать набор примитивов автокадовской команде?

Организовать цикл и через последовательный перебор объектов
ThisDrawing.ActiveSelectionSet.item(d) что то вроде того....

Re: Как передать набор примитивов автокадовской команде?

> ssn
Да нет, так не катит. Автокад не замечает моего набора, хотя он(набор) имеет статус активного ...

Re: Как передать набор примитивов автокадовской команде?

Вот пути использовавшиеся из лиспа.
https://www.caduser.ru/forum/topic16434.html
надеюсь поможет.

Re: Как передать набор примитивов автокадовской команде?

> Евгений
Действительно работает!
Теперь, значит, проблема - как передать набор из VBA в LISP. Или найти что-то подобное в VBA.

Re: Как передать набор примитивов автокадовской команде?

> Leonid
Попробуй через словари "XRecord"

Re: Как передать набор примитивов автокадовской команде?

> Leonid
Кажется я туплю.
Проще запустить лисп программу с аргументом (набор) далее разбирать его в лиспе...

Re: Как передать набор примитивов автокадовской команде?

> Евгений
Набор этот в ЛИСПе и разбирать особенно нечего - всего одна строчка кода. Как передать, вот проблема! Есть у меня одна задумка, если хватит энтузиазма, попробую и доложу результат.

Re: Как передать набор примитивов автокадовской команде?

А зачем замарачиваться с "активным" выбором? можно ведь просто создать обычный селекшен сет (всмысле назвать его как нить), заполнить его с активного селекшен сета, и потом как обычно....

Re: Как передать набор примитивов автокадовской команде?

> Leonid
Кажется я запутался...
Тебе в какую сторону надо передать набор из лиспа в вба или из вба в лисп?
Если из вба в лисп, то на лиспе пиши програмку с аргументом набор и из вба через командную строку вызывай лисппрорграмму с аргументом набор.
Если надо передать набор из лиспа в вба то надо где-то сохранять метки (handle) объектов из набора, здесь, мой совет, используй словари "XRecord"...

Re: Как передать набор примитивов автокадовской команде?

Вобщем, я пошел путем достаточно тривиальным - вот работающий код. Если кто-то предложит более элегантный подход, буду рад.

------начало кода VBA-----------------
'создание пустого набора средствами LISP:
    ThisDrawing.SendCommand "CreateSet" & vbCr
'заполнение "лисповского" набора примитивами из A_SSet:
    Dim EntHandle As String
    Dim OldName As String
    Dim sysVarName As String
    sysVarName = "USERS1"
    OldName = ThisDrawing.GetVariable("USERS1")
    Dim i As Integer
    For i = 0 To (A_SSet.Count - 1)
        EntHandle = A_SSet.Item(i).Handle
        ThisDrawing.SetVariable sysVarName, EntHandle
        ThisDrawing.SendCommand "FullSet" & vbCr
    Next i
'подсветка примитивов набора:
     ThisDrawing.SendCommand "GripsSet" & vbCr
'обработка примитивов набора командой PROPERTIES:
    ThisDrawing.SendCommand "PROPERTIES" & vbCr
    ThisDrawing.SetVariable sysVarName, OldName
------окончание кода VBA-----------------
------начало кода LISP-----------------
;;создание пустого набора
 (defun C:CreateSet (/)
  (setq SelSet_LN (ssadd))
)
;;CreateSet
;;заполнение набора
 (defun C:FullSet (/ EntHandle)
  (setq EntHandle (getvar "USERS1"))
  (ssadd (handent EntHandle) SelSet_LN)
)
;;CreateSet
;;подсветка примитивов набора
(defun C:GripsSet (/)
  (sssetfirst nil SelSet_LN)
)
;;GripsSet
------окончание кода LISP-----------------

Re: Как передать набор примитивов автокадовской команде?

И еще. Я благодарен всем откликнувшимся, ваши подсказки и замечания помогли мне. Спасибо!

Re: Как передать набор примитивов автокадовской команде?

Я как-то обратил внимание, что циклы типа

For i = 0 To (A_SSet.Count - 1)
   ...
   ...
Next i

выполнялись существенно медленнее, чем циклы типа

For Each obj in A_SSet
   ...
   ...
Next

Проявилось на крупных наборах.

Re: Как передать набор примитивов автокадовской команде?

> ALink
Спасибо, что напомнили о хорошем цикле. Я пытался вспомнить, почему применил For i... , но так и не вспомнил, видимо нашло затмение. В итоге, подправил программку и она радостно отозвалась. Цикл For Each...
хорош тем, что гарантированно проходит весь набор - ни больше и ни меньше. А в For i... всегда есть место ошибке из за неправильного задания (использования) индексации. По быстродействию циклы не сравнивал, но верю на слово, будем иметь в виду.

Re: Как передать набор примитивов автокадовской команде?

у Вас для каждого елемента масива вызывается
1. ThisDrawing.SetVariable sysVarName, EntHandle
2. ThisDrawing.SendCommand "FullSet" & vbCr
3. переход в лисп
4. (getvar "USERS1")
5. переход в VBA
кроме того, все проходит чере строку(string) "USERS1"
мне кажется, что мне удалось найти "более элегантный подход", правда для етого необхадима целая лисп ф-я
из VBA достаточно послать kоманду
ThisDrawing.SendCommand "(ssVBA->ssLisp " & Cstr(0) & ")" & vbCr
параметр  ф-и, ето номер SelSet в наборе SelSetов в VBA
напримр
"(ssVBA->ssLisp " & Cstr(0) & ")"    будет работать с CURRENT выбором
"(ssVBA->ssLisp " & Cstr(ThisDrawing.SelectionSets.Count -1) & ")" с PICKFIRST

;; sets indexed VBA SelSet into current SelSet
;; use (ssget "P") to retrive the Previous SelSet
;; returns count of SelSet or 0(Zero)
(defun ssVBA->ssLisp ( vba-ssInt / ob ss ssVBA)
(setq allSS    (vlax-get-property (vlax-get-property (vlax-get-acad-object)
                            'ActiveDocument)'SelectionSets))
(setq ss(ssadd))
(if(and vba-ssInt
        (< vba-ssInt (vlax-get-property allSS 'Count))
         (>= vba-ssInt 0)
    )
    (progn
        (setq ssVBA (vlax-invoke-method allSS 'Item vba-ssInt))
        (vlax-for ob ssVBA (setq ss(ssadd(vlax-vla-object->ename ob)ss)))
        (vlax-release-object allSS)
        (command "select" ss "")
    )
)
(sslength ss)
)

Re: Как передать набор примитивов автокадовской команде?

> cadhelp
Давно не возвращался к этой теме всерьез , но вот наконец пришло ее время, попробовал функцию в деле.
То что вы предложили, не просто "более элегантный подход", а блестящее решение. Я не специалист в LISP'е, поэтому сужу только по результату - быстродействие увеличивается в сотни раз.
Спасибо за решение, и если автор не возражает, я им воспользуюсь в своей работе.

Re: Как передать набор примитивов автокадовской команде?

Подумал, что для полноты картины не мешает выложить код со стороны VBA, код вызова функции ssVBA->ssLisp:

Dim A_SSet As AcadSelectionSet
    Dim dss As AcadSelectionSets
    'коллекция наборов примитивов в ThisDrawing
    Set dss = ThisDrawing.SelectionSets
    'создаем набор примитивов предназначенных для подсвечивания "ручками".
    ' Это либо новый именованный набор, либо заполненный нашими примитивами
    'один из дежурных -
    'ActiveSelectionSet или PickfirstSelectionSet:
    Set A_SSet = .................
    'определяем порядковый номер набора A_SSet
    'в коллекции  наборов dss
    Dim SetNum As Integer
    Dim i As Integer
    On Error Resume Next
    For i = 1 To dss.Count
        'этот подход универсальный, т.к. основан на
        идентификации объектов
        If [b](dss.Item(i) Is A_SSet)[/b] Then
            SetNum = i
            Exit For
        End If
    Next i
'вызываем функцию ssVBA->ssLisp с параметром SetNum, передаваемым через
'командную строку:
ThisDrawing.SendCommand "(ssVBA->ssLisp " & CStr(SetNum) & ")" & vbCr
Ну и еще я добавил в функцию ssVBA->ssLisp строчку:

- - - - - - - - - - - - - ---

(command "select" ss "")
[b](sssetfirst nil ss)[/b]
  )
)
(sslength ss)
);;ssVBA->ssLisp

Re: Как передать набор примитивов автокадовской команде?

Использовал вышеуказанные советы, чтобы передать набор из VBA в Lisp.
Получается странная вещь: когда ставлю точку останова на

ThisDrawing.SendCommand "(ssVBA->ssLisp " & CStr(SetNum) & ")" & vbCr

и затем по F8 захожу в Lisp и дальше F5, то созданные объекты подсвечиваются, а если просто выполнять программу без остановов, то набора нет.
Вот код:

Sub Example_AddItems()
 If ThisDrawing.SelectionSets.Count > 0 Then
    For I = 1 To ThisDrawing.SelectionSets.Count
    ThisDrawing.SelectionSets.Item(0).Delete
    Next I
End If
    Dim dss As AcadSelectionSets
    Set dss = ThisDrawing.SelectionSets
    Dim ssetObj As AcadSelectionSet    ' Create the new selection set
    Set ssetObj = ThisDrawing.SelectionSets.Add("selset2")
    Dim plineObj As AcadLWPolyline
    Dim points(0 To 5) As Double
    points(0) = 3: points(1) = 7: points(2) = 9: points(3) = 2
    points(4) = 3: points(5) = 5
    Set plineObj = ThisDrawing.ModelSpace.AddLightWeightPolyline(points)
    Dim lineObj As AcadLine
    Dim startPoint(0 To 2) As Double, endPoint(0 To 2) As Double
    startPoint(0) = 0: startPoint(1) = 0: startPoint(2) = 0
    endPoint(0) = 2: endPoint(1) = 2: endPoint(2) = 0
    Set lineObj = ThisDrawing.ModelSpace.AddLine(startPoint, endPoint)
    Dim circObj As AcadCircle
    Dim centerPt(0 To 2) As Double, radius As Double
    centerPt(0) = 20: centerPt(1) = 30: centerPt(2) = 0:  radius = 3
    Set circObj = ThisDrawing.ModelSpace.AddCircle(centerPt, radius)
    ReDim objs(0 To 2) As AcadEntity
    Set objs(0) = plineObj: Set objs(1) = lineObj: Set objs(2) = circObj
    ssetObj.AddItems objs
    On Error Resume Next
    For I = 1 To dss.Count
        If (dss.Item(I) Is ssetObj) Then SetNum = I:  Exit For
    Next I
ThisDrawing.SendCommand "(ssVBA->ssLisp " & CStr(SetNum) & ")" & vbCr
End Sub
(defun ssVBA->ssLisp ( vba-ssInt / ob ss ssVBA)
(setq allSS  (vlax-get-property (vlax-get-property (vlax-get-acad-object)
              'ActiveDocument)'SelectionSets))
(setq ss(ssadd))
(if(and vba-ssInt
    (< vba-ssInt (vlax-get-property allSS 'Count))
       (>= vba-ssInt 0)
  )
  (progn
    (setq ssVBA (vlax-invoke-method allSS 'Item vba-ssInt))
    (vlax-for ob ssVBA (setq ss(ssadd(vlax-vla-object->ename ob)ss)))
    (vlax-release-object allSS)
    (command "select" ss "")
    (sssetfirst nil ss)
  )
)
(sslength ss)
  ;(princ (sslength ss))
);;ssVBA->ssLisp