Тема: Как узнать Object_ID для объекта, созданного через SendCommand ?

Зравствуйте!
Ситуация такая. Я рисую несколько объектов с помощью SendCommand, а потом хочу их объединить в блок. Для этого надо их добавить в SelectionSet, которому, в свою очередь, нужны ссылки на объекты. Зная Object_ID, можно получить эти ссылки. Вопрос: как узнать Object_ID?
Если есть способы проще достигнуть цели, буду рада советам.
Спасибо всем, кто что-нибудь подсажет.

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Проще - есть. Если все же оставаться на VBA, то создавай указатель на свой блок и выполняй "рисование" прямо в нем.

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Указатель на блок - это как? Раньше с блоками не работала... Можно поподробнее, как это осуществить?

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Прошу учесть, что я в VBA не очень, больше на лиспе:
Определяем "базовую точку" блока:

Dim apInsPoint(2) As Double
  apInsPoint(0) = 0#: apInsPoint(1) = 0#: apInsPoint(2) = 0#

И создаем новый блок:

Dim aoBlock As AcadBlock
  Set aoBlock = ThisDrawing.Blocks.Add(apInsPoint, "New Block")

И добавим в него (в блок то бишь), например, отрезок:

Dim apStartPoint(2) As Double, apEndPoint(2) As Double
  apStartPoint(0) = 0#: apStartPoint(1) = 0#: apStartPoint(2) = 0#
  apEndPoint(0) = 10#: apEndPoint(1) = 20.5: apEndPoint(2) = 0#
Dim aoLineInBlock As AcadLine
  Set aoLineInBlock = aoBlock.AddLine(apStartPoint, apEndPoint)

И установим для отрезка тип и вес линии "ПоБлоку":

  aoLineInBlock.Lineweight = acLnWtByBlock
  aoLineInBlock.Linetype = "ByBlock"

Примерно так...

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Нет, не могу я так. Если бы AddArc был по трём точкам, то всё было бы нормально. Но когда я начинаю высчитывать необходимые параметры, то результат получается чуть-чуть не такой, как надо.
Поэтому пришлось извратиться с SendCommand. Действую сейчас по принципу "лишь бы работало, хоть как-нибудь".
Подробно описала ситуацию в теме https://www.caduser.ru/forum/topic27852.html .
Наверно, сейчас я попробую ещё раз проверить все свои формулы, высчитать заново параметры для дуг, чтобы можно было рисовать их через AddArc, а не SendCommand...

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Ну или попробовать смотреть в сторону

object.Select Mode[, Point1][, Point2][, FilterType][, FilterData]
Object - SelectionSet - The object or objects this method applies to.
Mode - AcSelect enum; input-only
Point1 - Variant (array of doubles); input-only; optional The 3D WCS coordinates, or array of coordinates, specifying Point1. See the mode definitions for the proper use of Point1.
Point2 - Variant (three-element array of doubles); input-only; optional
The 3D WCS coordinates specifying Point2. See the mode definitions for the proper use of Point2.
FilterType - Integer; input-only; optional
A DXF group code specifying the type of filter to use.
FilterData - Variant; input-only; optional
The value to filter on.

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Это типа выделения прямоугольником просто в окне AutoCAD-a? Интересная мысль... Кстати, у меня Help безмолвствует на эту тему. Только меня терзают смутные сомнения, что это чудо будет довольно медленно работать, если так выделять каждый из объектов будущего блока. Мне и блок-то нужен сейчас больше всего для ускорения вывода на экран. Но, вообще-то, не только для этого. Хотелось бы просто взять ID уже нарисованных объектов и слепить из них блок, но я не знаю, как это сделать.

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

acSelect можно использовать и Last (я точно не помню - вызови справку из када, посмотри там).

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Во, нашла в Helpe.
Last
Selects the most recently created visible objects
Только меня смущает слово objectS - сколько их, этих objects-ов, он сочтёт последними?... Параметра, задающего количество последних нарисованных объектов, я не вижу. Сейчас попробую, вдруг чего получится...

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Чего-то совсем плохо:
Dim ssetObj As AcadSelectionSet
Set ssetObj = ThisDrawing.SelectionSets.Add("curr_cell_ss")
После второй из этих строчек выходит из функции, ничего не сделав (во всяком случае, видимый изменений не наблюдаю). Чего-то не то я, наверно, делаю...

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

https://www.caduser.ru/forum/topic26902.html

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Спасибо! Моё шаманство завершилось тем, что прога падать перестала. Насчёт Sencommand-a -- полностью согласна, что это криво. Применяю его только потому что иначе работает не совсем верно:  https://www.caduser.ru/forum/topic27852.html . Однако, мне всё ещё не понятна такая вещь: судя по содержимому файла блока, блок создаётся нормально. Но при попытке выделить его выделяется только та дуга, на которую кликнули. То есть как будто и не блок это... Так должно быть или нет?
Код такой:

ThisDrawing.Wblock "F:\BlockFileName.dwg", ssetObj
base_point(0) = 0#: base_point(1) = 0#: base_point(2) = 0#
Set blk = ThisDrawing.Blocks.Add(base_point, "block_name")
base_point(0) = cell_points_arr(0): base_point(1) = cell_points_arr(1): base_point(2) = 0
Set blockRefObj = ThisDrawing.ModelSpace.InsertBlock(base_point, "block_name", 1#, 1#, 1#, 0)

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

masha пишет:

Dim ssetObj As AcadSelectionSet
Set ssetObj = ThisDrawing.SelectionSets.Add("curr_cell_ss")
После второй из этих строчек выходит из функции, ничего не сделав (во всяком случае, видимый изменений не наблюдаю).

А какого видимого эффекта Вы ожидаете от этих двух строк?) Ведь Вы всего лишь этим добавляете в документ именованый SelectionSet.

Однако, мне всё ещё не понятна такая вещь: судя по содержимому файла блока, блок создаётся нормально. Но при попытке выделить его выделяется только та дуга, на которую кликнули. То есть как будто и не блок это... Так должно быть или нет?

Если вы выделяете дугу в файле блока, то да, - блоком является в этом случае сам файл.

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

А по вопросу :

Вопрос: как узнать Object_ID?

Так и узнать: object.ObjectID

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Извиняюсь, не совсем разобрался в вопросе вот здесь > Сидор Лютый (2006-06-22 10:46:07) :)
Думаю, создать через SendCommand несколько объектов и потом враз их выделить невозможно.. Только по одному, через вышеупомянутый select last.

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

А какого видимого эффекта Вы ожидаете от этих двух строк?) Ведь Вы всего лишь этим добавляете в документ именованый SelectionSet.
Видимый эффект -- чтоб в Debug-ере можно было двинуться на следующую строчку кода. :) Вместо этого оно выходило из функции. Сейчас какими-то дикими методами (уже не помню, что именно я для этого сделала) мне удалось победить эту бяку, но осталась проблема со вставкой блока: он не всегда вставляется. Файл блока создаётся, а блок не вставляется. Поэтому и получалось выделение не всего блока в целом, а отдельных дуг. Это те дуги, из которых мы лепим блок. По идее, после вывода блока их стоит удалять, но тогда на экране ничего не останется.

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

> masha
Я тоже только на днях занялся этим вопросом (вставку блока, имею в виду)
В вашем коде происходит следующее:
1. Вы посылаете свой SelectionSet в файл:

ThisDrawing.Wblock "F:\BlockFileName.dwg", ssetObj

2. Создаете в текущем чертеже пустой блок:

Set blk = ThisDrawing.Blocks.Add(base_point, "block_name")

, с именем "block_name", который никак не связан с созданным в п.1 "BlockFileName.dwg" и с вашими объектами.
3. Вставляете reference этого же пустого блока в текущий чертеж:

Set blockRefObj = ThisDrawing.ModelSpace.InsertBlock(base_point, "block_name", 1#, 1#, 1#, 0)

То есть п.2 нужно убрать, а п.3 надо записать так:

Set blockRefObj = ThisDrawing.ModelSpace.InsertBlock(base_point, "F:\BlockFileName.dwg", 1#, 1#, 1#, 0)

(Если "F:\" есть в путях поддержки AutoCad, то можно указывать только название файла.)
По крайней мере, я так делаю..:)

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Я так и сделала.  Теперь появилась другая печаль: вместо одного блока рисуется сразу два, один поверх другого, причём нижний совершенно неубиваемый, его даже выделить не получается. И так до тех пор, пока не нарисую новый блок. Когда рисую новый блок, старый исчезает. С экрана исчезает или вообще - не знаю. Мне кажется, что причина этого явления в том, что имя файла блока каждый раз одно и то же. В связи с этим вопрос: если удалить файл блока, разве это вляиет на блок, который уже вставлен в чертёж?
Если давать разные имена файлам блоков, то почему-то у меня в одних случаях блок вставляется, а в других - нет. Хотя все блоки рисуются одиноково, только с разными значениями координат. Я пока не знаю, в чём причина. Буду искать, либо вообще забью на эти блоки и постараюсь сделать через полилинии. Код выглядит так:

ThisDrawing.Wblock "block_file.dwg", sstemp
base_point(0) = 0: base_point(1) = 0: base_point(2) = 0
Set blockRefObj = ThisDrawing.ModelSpace.InsertBlock(base_point, "block_file.dwg", 1#, 1#, 1#, 0)
blockRefObj.Update

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Только что писал вставку блака с атрибутами проблем не замечал. ПРивожу листинг из контекста

Public Sub InsertDenom(ac As Object)
On Error GoTo ENDSUB
 Dim blockname As String
 SetVar ac, "OSMODE", 547
 PrintMessage ac, 25                         'Specify layer name:
DelByLayer ac, GoToLayer(ac, Replace(ac.Utility.getstring(False), "/", ""))
blockname = PathToSimboli & "Denominazione.dwg"
strTemp = ""
strTemp2 = ""
Do While Percent > 0
PrintMessage ac, 22                          'Specify point:
basePnt = ac.Utility.GetPoint
    If strTemp = "" Then
     PrintMessage ac, 53                      'Street type:
     strTemp = ac.Utility.getstring(False)
     If strTemp = "" Then strTemp = "x"
    End If
    If strTemp2 = "" Then
     PrintMessage ac, 54                      'Street name:
     strTemp2 = ac.Utility.getstring(False)
     If strTemp2 = "" Then strTemp2 = "y"
    End If
    Set blockObj = ac.ModelSpace.InsertBlock(basePnt, blockname, 1, 1, 1, 0)
      Attr = blockObj.GetAttributes
      Attr(0).TextString = strTemp
      Attr(1).TextString = strTemp2
Loop
ENDSUB:
    PrintMessage ac, 46                      'Operations finished!
End Sub

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Вот, для примера, эта подпроцедура вставки блока у меня тоже всегда выполняется без глюков:

Sub InsertBlock()
    Dim ArAtr As Variant
    Dim Bltmp As Object
        Pnt(0) = TPosition1(0)
        Pnt(1) = TPosition2(0)
        Pnt(2) = 0#
        Set Bltmp = Cad.ModelSpace.InsertBlock(Pnt, "002b.dwg", ScB, ScB, 1#, 0)
        If Bltmp.Name = "" Then
            Cad.Utility.prompt "Невозможно выполнить операцию. Обратитесь к разработчикам."
        Else
            ArAtr = Bltmp.GetAttributes
            ArAtr(0).textstring = n
            ArAtr(1).textstring = FormatNumber(Ar, 1#, -1, 0, 0)
        End If
End Sub

Теперь появилась другая печаль: вместо одного блока рисуется сразу два, один поверх другого, причём нижний совершенно неубиваемый, его даже выделить не получается. И так до тех пор, пока не нарисую новый блок. Когда рисую новый блок, старый исчезает. С экрана исчезает или вообще — не знаю. Мне кажется, что причина этого явления в том, что имя файла блока каждый раз одно и то же. В связи с этим вопрос: если удалить файл блока, разве это вляиет на блок, который уже вставлен в чертёж?

Есть такое понятие, как "Block Definition" (не знаю, как описать это по-русски)) Это что-то типа определения (описание) блока. В вашем примере, вы меняете его, посылая измененные примитивы в "block_file.dwg", а потом вставляете в чертеж, в котором уже есть предыдущий (то бишь другой) Block Definition и с тем же самым именем.
То есть вы правы. Проблема тут в том, что содержание блока меняется, а имя блока - нет. Поэтому, вставляя блок с новым содержанием вы переопределяете все referense с тем же самым именем. Отсюда и накладки один на другой.. Один экземпляр - это новый вставленный блок, а под ним - предыдущий, но переопределенный и получивший новое содержание.

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

masha пишет:

Если давать разные имена файлам блоков, то почему-то у меня в одних случаях блок вставляется, а в других — нет. Хотя все блоки рисуются одиноково, только с разными значениями координат. Я пока не знаю, в чём причина

Возможно, проблема в базовой точке. Если Вы нарисовали примитивы далеко от 0,0,0 а затем через "ThisDrawing.Wblock" послали их в файл-блок, то базовая точка у такого блока будет всегда в 0,0,0. Следовательно, содержимое блока (его примитивы) вставятся в вашем примере в те же координаты, которые они имели перед занесением их в файл-блок.
В общем, при вставке такого блока, он должен появиться там, где были его "родительские" примитивы:)

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Спасибо всем огромное!

Re: Как узнать Object_ID для объекта, созданного через SendCommand ?

Да, кстати. Открою секрет своего глюка. Только сегдня обнаружила, перепробовав все предложенные версии и потерпев неудачу. В имени файла блока не может быть запятых!!! - из-за этого он и не вставлял блоки.
Ещё раз всем спасибо за проявленное терпение и полезную информацию!