Тема: Программное рисование в Layoute

Здравствуйте, все добрые люди!
Очень надо рисовать объекты в Layout-e. Руками - не вопрос, но как это сделать программно?  Следующая попытка оказалась безуспешной:

ThisDrawing.ActiveSpace = acPaperSpace
ThisDrawing.ActiveLayout.AddLWPolyline(retCoord)

Догадываюсь, что надо перейти в какой-то конкретный Layout, но как это сделать - не знаю... Так не получилось:

ThisDrawing.SendCommand "<Switching to: Layout-N-43-124-(40-и)>" & vbCr

И ещё если поставить точку после ThisDrawing.ActiveLayout, то в выпадающем списке никаких AddLWPolyline нету. Наверно, это неспроста...
Буду рада любым полезным советам.

Re: Программное рисование в Layoute

> masha
Посмотри свойство Layout.Block
Это то что нужно
Измени название листа на свое:

Option Explicit
Sub test()
Dim oLayout As AcadLayout
Dim oSpace As AcadBlock
Set oLayout = ThisDrawing.Layouts("Layout#44 etc.")
Set oSpace = oLayout.Block
Dim oPline As AcadLWPolyline
Set oPline = oSpace.AddLightWeightPolyline(points)
End Sub

~'J'~

Re: Программное рисование в Layoute

Спасибо, Fatty, это оно! Только на экане почему-то ничего не отбражается. Если смотреть Watch-и объектов в Debuger-e, то полилиния нормальная, какая надо. Но её не видно. Не помогает даже строчка

ThisDrawing.Regen acAllViewports

Отчего такое может быть?...

Re: Программное рисование в Layoute

Ещё одну вещь заметила. Если потыкать мышкой в создавшийся Layout, то координаты, высвечивающиеся внизу, имеют значения от 0 до ~11.5 по Х-координате и от 0 до ~8 по Y. Однако, если в этом Layout-e создать ViewPort, углы которого заданы в предположении, что размеры листа 297x210, то это ViewPort рисуется на ожидаемом месте и виден на экране. Не понимаю, чем полилиния хуже вьюпорта и в чем измеряются координаты Layout-a...

Re: Программное рисование в Layoute

> masha
Сейчас как-то нет времени тщательно в этом
покопаться, но попробуй координаты транслировать
с использованием метода TranslateCoordinates
Жаль, что я не работаю с видовыми экранами
больше ничего подсказать не могу
:(

Re: Программное рисование в Layoute

Я что-то совсем запуталась... Теперь и с вьюпортом проблемы появилсь. У меня есть для примера два файла, так в одном из них вьюпорт рисуется, а в другом - нет. Прохожу в Debuger-e - команды делают вид, что выполняются. Однако на экране ничего не появляется. Код создания вьюпорта:

    Set newViewport = ThisDrawing.PaperSpace.AddPViewport(pt_center, width, height)
    newViewport.Target = Tg
    newViewport.StandardScale = acVpCustomScale
    newViewport.CustomScale = custom_scale
    newViewport.Display True

Значения параматров при создании:
в "удачном" файле: pt_center = (145,80,0), width = 253, height = 122.
в "неудачном" файле: pt_center = (95,102,0), width = 154, height = 166.
По идее, в обих слуаях должно что-то нарисоваться... Подскажите, пожалуйста, люди добрые, в какую сторону мне копать...

Re: Программное рисование в Layoute

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

Re: Программное рисование в Layoute

Ключ к разгадке, думаю, лежит в строке

ThisDrawing.[b]PaperSpace[/b].AddPViewport

PaperSpace-ов то два, а рисование выполняется в первое. Второе имеет имя, кажется, нечто типа PaperSpace0.

Re: Программное рисование в Layoute

А можно поподробнее?  Мне не понятно, почему в одном файле рисуется, куда надо, а в другом нет? Код-то одинаковый... Если PaperSpace-ов 2, то как угадать, с каким из них мы имеем дело? И как называется второй? Если просто написать PaperSpace0 вместо PaperSpace, то ругается, что member or data member not found.

Re: Программное рисование в Layoute

поскольку я совсем не спец в VBA, пойдем "от руды", хорошо (кстати, только сейчас обнаружил, что Paperspace - это вообще коллекция, а не объект)
в VBAIDE в Debug Window (на пустом файле) пишем:

? ThisDrawing.PaperSpace.Count

И оно выводит 0! Но листов-то два! Так, попробуем активировать сначала один, потом второй. Повторяем код. Возвращает 2. Забавно...
Так, а если по-другому? Если рисовать в пространство листа? Получим-ка эти имена (я не знаю всех подробностей VBA, возможно, там все встроенное есть):

Function GetLayoutsNames() As String()
Dim objCounter As AcadLayout
Dim arRes() As String, lCounter As Long
  ReDim arRes(ThisDrawing.Layouts.Count - 2)
  For Each objCounter In ThisDrawing.Layouts
    If LCase(objCounter.Name) <> "model" Then
      arRes(lCounter) = objCounter.Name
      lCounter = lCounter + 1
    End If
  Next objCounter
  GetLayoutsNames = arRes
End Function

И потом работать, например, наподобие такого:

ThisDrawing.Layouts(GetLayoutsNames(0)).Block.AddLine

Я не проверял, так что могут быть тонкости

Re: Программное рисование в Layoute

Всё это мне тоже пригодится, потому что Layout-oв у меня будет много в дальнейшем, но сейчас хочется хотя бы один как следует сделать. Пока не догоняю, как это связано с вьюпортом, который не создаётся... Типа, не в том layout-e создаю? попробую пока похимичить с layout-ами, вдруг чего получится...

Re: Программное рисование в Layoute

Нет, проблема в том, что ты работаешь не в пространстве блока листа, а напрямую на коллекцию. А если это делать, то, как правило, возвращается первый элемент этой коллекции (у которого индекс 1), как это я понимаю.

Re: Программное рисование в Layoute

Перед всем описанным я делаю так:

ThisDrawing.ActiveLayout = ActiveDocument.Layouts.Item(layout_name)

Мне наивно казалось, что после этого заклинания я работаю с нужным layout-ом...

Re: Программное рисование в Layoute

Ага. Только тогда дурной вопрос - а почему использовалось все же PaperSpace, а не Layouts.Item для добавления Viewport'a?

Re: Программное рисование в Layoute

Если написать

Set newViewport = ThisDrawing.Layouts.Item(layout_name).AddPViewport(pt_center, width, height)

, то никакой вьюпорт не рисуется и ничего из него не видно. В "удачном" примере рисуется только та несчастная полилиния... В неудачном - ничего не рисуется. :(

Re: Программное рисование в Layoute

> masha
Несколько раз перечитал и каждый раз терял нить проблемы.. (Вечерами трудно соображается после 12-часовых будней:))
Попробуйте создать объект не в layout напрямую (на сколько я понял help, - layout с точки зрения activeX, всего лишь содержит настройки печати, поэтому Вы и не встретили там методов add...), а в PaperSpace (которое, как и layout.block из способа Fatty, представляет коллекцию объектов текущего layout). Примерно так:

ThisDrawing.ActiveLayout = ThisDrawing.Layouts.Item("layout_name")
Set plineObj = ThisDrawing.PaperSpace.AddLightWeightPolyline(points)

т.е. сначала активируете нужный layout, а потом чертите объект в PaperSpace
Если я что-то не так понял, то втяните меня в тему, пожалуйста:)
Написал сумбурно. Но надеюсь смысл будет понятен..

Re: Программное рисование в Layoute

Вот наспех собранная по кусочкам из хелпа программка:

Sub pline()
    Dim plineObj As AcadLWPolyline
    Dim points(0 To 9) As Double
    Dim center(0 To 2) As Double
    center(0) = 3: center(1) = 3: center(2) = 0
    points(0) = 1: points(1) = 1
    points(2) = 1: points(3) = 2
    points(4) = 2: points(5) = 2
    points(6) = 3: points(7) = 2
    points(8) = 4: points(9) = 4
    ThisDrawing.ActiveLayout = ThisDrawing.Layouts.Item("layout2")
    Set newViewport = ThisDrawing.PaperSpace.AddPViewport(center, 300, 400)
    Set plineObj = ThisDrawing.PaperSpace.AddLightWeightPolyline(points)
End Sub

Вроде работает..

Re: Программное рисование в Layoute

А вот чертить скрытно (не активируя layout) можно, наверное, только через layout.block
Точно не скажу, надо разбираться..

Re: Программное рисование в Layoute

Спасибо, с рисованием линий разобралась. Сейчас проблема следующая: если вьюпорт рисуется, то и линия рисуется, либо ни того, ни другого.   Единицы измерения - миллиметры. Создаю вьюпорт так:

Set newViewport = ThisDrawing.PaperSpace.AddPViewport(pt_center, width, height)

При этом он создаётся (и с правильными параметрами), если верить Debuger-у, но на экране ничего не появляется - ни самого VP, ни того, что должно быть из него видно. Может, кто знает, почему такие неприятности случаются?... По идее, это уже оффтоп, но понять очень хочется.

Re: Программное рисование в Layoute

masha пишет:

если вьюпорт рисуется, то и линия рисуется, либо ни того, ни другого

Мистика какая-то!:) А поподробнее можно?
После создания объектов "_zoom _all" или "_zoom _e" делали? С видимостью слоев все нормально?

Re: Программное рисование в Layoute

Да, вам смешно... А мне каково?! Ну, ладно... A вот за ZoomAll спасибо, он действительно рулит - теперь всё видно! Но с таким косяком: беленький прямоугольничек Layout-a очень маленький, а вьюпорт и всё, что в него видно - огромный, по сравнению с ним, и находится за его пределами (поэтому и не видно ничего на листе). Лист Layout-а имеет размеры 11,5 x 8, а вовсе не 297х210. Получается, что надо задать размеры листа Layout-a. Ну, теперь самый дурацкий мой вопрос: как это сделать? В списке подсказок ничего адекватного не вывалилось...
И ещё. Для меня так и остаётся загадкой, почему в "удачном" файле лист сразу имеет нужные размеры - 297х210 (А4), а тут - нет.

Re: Программное рисование в Layoute

masha пишет:

Лист Layout-а имеет размеры 11,5 x 8,

По-моему это размеры А4 в дюймах..
Сдается что-то с единицами напутано..

Re: Программное рисование в Layoute

Точно, подогнать под А4 можно так:

ActiveDocument.Layouts.Item(layout_name).PaperUnits = acMillimeters

А так оно, видимо, в дюймах было... Однако, всё равно не понятно, что делать с другими форматами: А3, А2 и т.д. Вьюпорт и его содержимое у меня нормально масштабируются (в программе), а размер листа такой и остаётся, как для А4...

Re: Программное рисование в Layoute

Смотрите в сторону свойства Layout.CanonicalMediaName и объекта PlotConfiguration
На пальцах объяснять долго.

Re: Программное рисование в Layoute

Спасибо, поищу. Насчёт PlotConfiguration справка говорит, что Keyword Not Found... Сейчас буду Гугл мучить...