Просмотрев весь форум по данной теме, к сожалению так ни чего приемлемого
для своих целей и не нашёл. Поэтому пошёл своим путём. А то что получилось
предлагаю на суд професионалов.
Данный метод имеет следующие преимущества:
-позволяет, в момент загрузки VBA приложения, запускать необходимый
макрос, для инициализации всех необходимых параметров.(Тоже что
делает файл acad.dvb с макросом AcadStartup, только к именам вы не
как не привязаны.)
-позволяет запускать необходимый код, в работу, непосредственно по
вашим собственным командам, без всяких загрузок макросов.
-позволяет работать напрямую с набором PickfirstSelectionSet и определяет
былли выбор в ActiveSelectionSet, или был выход без выбора.
Алгоритм следующий:
1. В момент загрузки нашего VBA приложения, запускается макрос
VBAProject_Initialize, в котором выставляются все необходимые для
работы приложения параметры. В данном случае создаём нашу собственную
команду MYCMD.
2. Вводим команду в командной строке MYCMD. Перехватываем её и запускаем
макрос Begin_Select. В данном макросе делаем проверку на метод выбора
объектов. Если объекты были выбраны заранее на экране, то запускаем
макрос обработки объектов SelObjsManipulations.
Если объекты выбраны не были, то запускаем команду SELECT для выбора
объектов.
3. Перехватываем выход из команды SELECT и проверяем был ли выбор объектов,
или был отказ от выбора. Если был отказ, то прекращаем работу. Если объекты
были выбраны, то запускаем макрос обработки объектов SelObjsManipulations.
Если код отработал успешно, то макрос SelObjsManipulations выдаст сообщение
о количестве выбранных объектов.
Модуль AutoCAD Objects
-> ThisDrawing
Private Sub AcadDocument_BeginCommand(ByVal CommandName As String)
On Error GoTo OnErr
If ProgRuning = False Then VBAProject_Initialize
Select Case CommandName
Case "MYCMD": Begin_Select: Exit Sub
Case "SELECT"
If CmdEndOnCancel = True Then _
CmdEndOnCancel = False: CmdMyCmd = False _
Else: CmdEndOnCancel = True
End Select
OnErr:
If Err.Number <> 0 Then Err.Clear
End Sub
Private Sub AcadDocument_EndCommand(ByVal CommandName As String)
Dim SelSet As AcadSelectionSet
Dim I As Long
On Error Resume Next
If ProgRuning = False Then VBAProject_Initialize
Select Case CommandName
Case "SELECT"
If CmdMyCmd = True Then
CmdMyCmd = False: CmdEndOnCancel = False
CommandName = "MYCMD"
With ActiveDocument
If .ActiveSelectionSet.Count <> 0 Then
Set SelSet = .SelectionSets("$OLDACTIVESELOBJS_0A1H2F3B")
If .ActiveSelectionSet.Count = SelSet.Count Then
For I = 0 To .ActiveSelectionSet.Count - 1
If .ActiveSelectionSet(I) Is SelSet(I) = False Then GoTo NewSel
Next I
SelSet.Delete: Set SelSet = Nothing
Exit Sub
NewSel:
End If
SelSet.Delete: Set SelSet = Nothing
SelObjsManipulations
End If
End With
End If
End Select
End Sub
Private Sub AcadDocument_BeginSave(ByVal FileName As String)
Dim SelSet As AcadSelectionSet
For Each SelSet In ActiveDocument.SelectionSets
If SelSet.Name = "$EXPOLDACTSELOBJS_0A1H2F3B" Then SelSet.Delete: Exit For
Next SelSet
Set SelSet = Nothing
End Sub
Модуль
-> SelectObjects
Public ProgRuning As Boolean
Public CmdEndOnCancel As Boolean, CmdMyCmd As Boolean
Sub VBAProject_Initialize()
On Error Resume Next
ActiveDocument.SendCommand _
"(vl-load-com)" & _
"(defun MYCMD()())" & _
"(vlax-add-cmd ""MYCMD"" 'MYCMD)" & _
"(princ)" & vbCr
DoEvents
ProgRuning = True
У данного Lisp кода есть одна особенность. Все Lisp функции загруженные через
командную строку видны, только когда активен файл в котором они были загружены.
Поэтому, если в момент ввода нашей команды будет активен другой файл, то
AutoCAD выдаст, в командной строке, сообщение об ошибке. Для нашего VBA кода
это не имеет ни какого значения, главное что перехват команды отрабатывается чётко.
Если для кого-то это критично, то данный Lisp код необходимо сохранить
в файле *.lsp или в коде *.vlx и вместо приведёного выше кода, ввести
Lisp код загрузки вашего *.lsp или *.vlx файла, через специальную VLisp команду.
End Sub
Sub Begin_Select()
Dim AcadObj As AcadObject
Dim ArrayObj(0) As AcadObject
Dim SelSet As AcadSelectionSet
On Error GoTo OnErr
With ActiveDocument
If .PickfirstSelectionSet.Count <> 0 Then
SelObjsManipulations
Exit Sub
Else
For Each SelSet In .SelectionSets
If SelSet.Name = "$OLDACTIVESELOBJS_0A1H2F3B" Then SelSet.Clear: GoTo Sel_NoAdd
Next SelSet
Set SelSet = .SelectionSets.Add("$OLDACTIVESELOBJS_0A1H2F3B")
Sel_NoAdd:
For Each AcadObj In .ActiveSelectionSet
Set ArrayObj(0) = AcadObj
SelSet.AddItems ArrayObj
Next AcadObj
Set SelSet = Nothing: Set AcadObj = Nothing
CmdMyCmd = True: CmdEndOnCancel = False
.SendCommand "_SELECT" & vbCr
End If
End With
OnErr:
If Err.Number <> 0 Then Err.Clear
End Sub
Sub SelObjsManipulations()
Dim SelectionSet As AcadSelectionSet
With ActiveDocument
If .PickfirstSelectionSet.Count <> 0 Then
Set SelectionSet = .PickfirstSelectionSet
ElseIf .ActiveSelectionSet.Count <> 0 Then
Set SelectionSet = .ActiveSelectionSet
Else: Exit Sub
End If
End With
MsgBox "Выбрано: " & SelectionSet.Count & " объектов." & (Chr(13) & Chr(10)) & _
"Выбранные объекты в наборе - SelectionSet", vbInformation
End Sub