Запоминает установки печати, распространяя их на то что не нужно

Автор Тема: Запоминает установки печати, распространяя их на то что не нужно  (Прочитано 19552 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн ДамирАвтор темы

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Доброго времени, эксперты!

Пытаюсь в цикле пробежать по всем рамкам в пространстве модели. Рамки представляют собой блоки с особыми именами. Обнаружив рамку скрипт настраивает его установки печати и печатает его в PDF. Проблема в том, что запомнив первоначальные установки печати он распространяет их на все остальные рамки. Например формат рамки, который я извлекаю из olayt.GetCanonicalMediaNames(). Что делать? Прошу помочь

Код

Код - Visual Basic [Выбрать]
  1. For Each block_ramka In ThisDrawing.ModelSpace
  2.         If block_ramka.ObjectName = "AcDbBlockReference" Then
  3.             If block_ramka.name = "A0_книж" Or block_ramka.name = "A1_альб" Then
  4.                 If block_ramka.name = "A0_книж" Then
  5.                     point_ar = Array(841, 1189)
  6.                     AF = "ISO без полей A0 (841.00 x 1189.00 мм)"
  7.                 End If
  8.                 If block_ramka.name = "A1_альб" Then
  9.                     point_ar = Array(841, 594)
  10.                     AF = "ISO A1 (841.00 x 594.00 мм)"
  11.                 End If
  12.                
  13.                 u = u + 1
  14.                 'point_ar = Array(841, 1189) 'RamkaINI(ramka_name)
  15.                point1 = block_ramka.InsertionPoint
  16.                 point2_ar(0) = point1(0) + point_ar(0)
  17.                 point2_ar(1) = point1(1) + point_ar(1)
  18.                 point2 = point2_ar
  19.    
  20.                 'пространство Модель или ЛистN
  21.                space = ThisDrawing.ActiveLayout.name
  22.              
  23.                 w = point2(0) - point1(0) 'ширина
  24.                h = point2(1) - point1(1) 'высота
  25.      
  26.                 'AF = "ISO_A0_(841.00_x_1189.00_MM)"
  27.                'AF = "ISO без полей A0 (841.00 x 1189.00 мм)"
  28.                Plotter = "DWG To PDF.pc3"
  29.                
  30.                 Dim r
  31.                 Dim Retval
  32.                 Dim str As String
  33.                 Dim AF_r
  34.                  
  35.                 Set olayt = ThisDrawing.ActiveLayout
  36.                 olayt.ConfigName = Plotter
  37.                 'olayt.StyleSheet = "acad.ctb" 'стиль печати
  38.                ReDim Preserve point1(0 To 1)
  39.                 ReDim Preserve point2(0 To 1)
  40.    
  41.                 olayt.SetWindowToPlot point1, point2
  42.                 olayt.PlotType = acWindow
  43.                 olayt.CenterPlot = True
  44.                 olayt.PlotRotation = ac0degrees
  45.                 olayt.StandardScale = 0 'вписать
  46.                'ThisDrawing.Regen 1
  47.                olayt.RefreshPlotDeviceInfo
  48.                 Retval = olayt.GetCanonicalMediaNames()
  49.                
  50.                 For Each r In Retval
  51.                     'MsgBox r
  52.                    'MsgBox olayt.GetLocaleMediaName(r)
  53.                    If (olayt.GetLocaleMediaName(r) = AF) Then
  54.                         olayt.CanonicalMediaName = r
  55.                         MsgBox r
  56.                         AF_r = r
  57.                         Exit For
  58.                     End If
  59.                 Next r
  60.                 ThisDrawing.Plot.PlotToFile "C:\Users\damir\Desktop\1-1-1\" + CStr(u) + ".pdf" '(Replace(Draw.FullName, "dwg", "pdf")
  61.            End If
  62.         End If
  63.     Next block_ramka
  64.  
Сколько голов, столько умов. Но голов больше

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Что делать?
Отменять изменения, т.е. запускать команду _UNDO.
Например, в начале цикла запускаем _UNDO _Mark, а в конце _UNDO _Back
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДамирАвтор темы

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Благодарю, разобрался - немного спутал понятия. Вообщем он обновляет настройки. Все работает
Сколько голов, столько умов. Но голов больше

Оффлайн ДамирАвтор темы

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Есть такая проблема с этим же кодом. При запуске из VBS (код выше VBA соответственно). Пока не грешу на особенности работы с типами данных (Array и Double). Этому был посвящен отдельный пост. Возможно что то делаю не так.
Проблема:

На выходе получаю файл PDF С КОРРЕКТНЫМ ФОРМАТОМ РАМКИ, но внутри не рамка, а просто фрагмент чертежа  - три разные рамки в середине. Т.е. в листе PDF формата А0 должна быть рамка А0, а сейчас три файла PDF и в каждой три рамки в середине. Т.е. процесс захвата рамки не отрабатывает... Прошу помочь с данной проблемой. Еще раз: на VBA все работает, на VBS нет...

В коде такой метод ThisApplication.Utility.VariantToArray отвечает за перевод в тип данных понятный Автокаду
Это системный метод реализованный на платформе где я пишу код на VBS

Код:
Код - Text [Выбрать]
  1. u = 0
  2.   For Each Ramka In Draw.ModelSpace
  3.   if Ramka.ObjectName = "AcDbBlockReference" then
  4.     If Ramka.name = "A0_книж" Or Ramka.name = "A2_книж" Then
  5.                 If Ramka.name = "A0_книж" Then
  6.                     point_ar = array(841.0, 1189.0)
  7.                     AF = "ISO без полей A0 (841.00 x 1189.00 мм)"
  8.                 End If
  9.                 If Ramka.name = "A2_книж" Then
  10.                     point_ar = array(420.0, 594.0)
  11.                     AF = "ISO без полей A2 (420.00 x 594.00 мм)"
  12.                 End If
  13.       u = u + 1
  14. '      dim point2_ar(2)
  15.  
  16. '      point_ar = array(Cdbl(841.0), Cdbl(1189.0))
  17.       point1 = ThisApplication.Utility.ArrayToVariant(Ramka.InsertionPoint)
  18. '      msgbox point1(0) + point_ar(0)
  19.      
  20.  
  21. '      point2_ar(0) = point1(0) + point_ar(0)
  22. '      point2_ar(1) = point1(1) + point_ar(1)
  23. '      point2 = point2_ar
  24. '    
  25. '      w = point2(0) - point1(0)
  26. '      h = point2(1) - point1(1)
  27.  
  28. '      AF = "ISO без полей A0 (841.00 x 1189.00 мм)"
  29.       Plotter = "DWG To PDF.pc3"
  30. '      
  31.       ReDim Preserve point1(2)
  32.       ReDim Preserve point2(2)
  33.  
  34. '      point1 = ThisApplication.Utility.VariantToArray(point1)
  35. '      point2 = ThisApplication.Utility.VariantToArray(point2)
  36.  
  37.  
  38. ''      If (Draw.ActiveSpace = acModelSpace) Then
  39. '        Dim vp
  40. ''        Dim vp_tochka(0 To 2)  As Double
  41. ''        Dim vp_tochka(3)
  42. '        Set vp = Draw.ActiveViewport
  43. ''        vp_tochka(0) = 0
  44. ''        vp_tochka(1) = 0
  45. ''        vp_tochka(2) = 0
  46. ''        vp.Target = vp_tochka
  47. '        vp.Target = ThisApplication.Utility.VariantToArray(array(Cdbl(5000), Cdbl(5000), Cdbl(5000)))
  48. ''        vp.Target = ThisApplication.Utility.VariantToArray(vp_tochka)
  49. '        Draw.ActiveViewport = vp
  50. '        Draw.Regen acAllViewports '1
  51. ''End If
  52.  
  53.       Set olayt = Draw.ActiveLayout
  54.       olayt.ConfigName = Plotter
  55.       olayt.SetWindowToPlot ThisApplication.Utility.VariantToArray(array(Cdbl(point1(0)), Cdbl(point1(1)))), ThisApplication.Utility.VariantToArray(array(Cdbl(point1(0)+point_ar(0)), Cdbl(point1(1)+point_ar(1))))
  56.       msgbox point1(0) & " - " & point1(1)
  57.       msgbox point1(0) + point_ar(0)
  58.       msgbox point1(1) + point_ar(1)
  59.      
  60.       olayt.PlotType = acWindow
  61.       olayt.CenterPlot = True
  62.       olayt.PlotRotation = ac0degrees
  63.       olayt.StandardScale = 0
  64.       olayt.RefreshPlotDeviceInfo
  65.  
  66.       Retval = ThisApplication.Utility.ArrayToVariant(olayt.GetCanonicalMediaNames())
  67. '      olayt.CanonicalMediaName = "ISO_full_bleed_A0_(841.00_x_1189.00_MM)"
  68.  
  69.       For Each r In Retval
  70. '        MsgBox olayt.GetLocaleMediaName(r)
  71.         If (olayt.GetLocaleMediaName(r) = AF) Then
  72.           olayt.CanonicalMediaName = r
  73.           MsgBox r
  74. '          AF_r = r
  75.           Exit For
  76.         End If
  77.       Next
  78.      
  79.       Draw.Plot.PlotToFile "C:\Users\damir\Desktop\1-1-1\" + CStr(u) + ".pdf" '(Replace(Draw.FullName, "dwg", "pdf")  
  80.     End If
  81.     end if
  82.   Next
  83.  

 
Сколько голов, столько умов. Но голов больше

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ничего не понял, но понял что тебе просто нужно разобраться с координатами и чертежом. У тебя на чертеже всё в масштабе 1:1 в мм?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДамирАвтор темы

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Да, в чертеже масштаб задаю в строке olayt.StandardScale = 0.Смущает то что этот же код на vba запускаемый внутри AutoCAD работает на ура. Т.е. очередность методов аналогичная... Насчёт масшатаба согласен. В эту сторону смотреть можно, но я цепляюсь за нижнюю левую и верхнюю правую границу рамки и выбираю "вписать". Все кодом естественно
Сколько голов, столько умов. Но голов больше

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
В эту сторону смотреть можно, но я цепляюсь за нижнюю левую и верхнюю правую границу рамки и выбираю "вписать". Все кодом естественно
В том коде, в котором ты показал совсем не так. Ты к точке вставки рамки (кстати, а где она находится по отношению к самой рамке?) прибавляешь размер формата, а должен размер рамки (если она конечно не в масштабе 1:1).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДамирАвтор темы

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Точка в ставки рамок в левом нижнем углу. Я добавляю размер формата заранее мне известного (ширина, высота). Дело в том что у рамки те же самые размеры. Просто тот же код на VBA успешно работает, я просто скопировал код в VBS обработчик и переписал под синтаксис языка. Во вложении результаты обоих скриптов. Смотрю в сторону масштабов и захвата рамок - как вы и указываете, но пока не могу понять в чем ошибка.  Модет нужно делать сброс вида, экрана (VewPort). Скрипт загружает приложение автокада в активном режиме (не в фоне)
Сколько голов, столько умов. Но голов больше

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Модет нужно делать сброс вида, экрана (VewPort). Скрипт загружает приложение автокада в активном режиме (не в фоне)
Сомневаюсь. Если для одного и тоже чертежа ты получаешь разные результаты, то смотри в чем отличаются коды VBA/VBS. Ничего другого я не подскажу.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДамирАвтор темы

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
 в том то и дело что ничем. Порядок используемых методов аналогичный
Сколько голов, столько умов. Но голов больше

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
в том то и дело что ничем.
Значит отличие есть. Выложи в одном сообщении два кода -  один VBA, второй VBS. Убери лишние комментарии, чтобы легче было читать код. Первый код перепроверь 7 раз, чтобы убедиться, что код VBA работает. Приложи чертеж, на котором проверяешь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДамирАвтор темы

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Все сделал как вы сказали. Во вложении рабочий VBA код с результатом, также VBS код не рабочий, с неверным результатом. Сам чертеж с рамками и вот ссылка на механизм создания https://drive.google.com/file/d/0B7WQynP0e6CrMnRUT3g0dzlZOXc/view?usp=sharing

Сразу хочу сказать что в коде vbs вы обнаружите методы позволяющие переводить типы данных при переносе величин из автокада и обратно. Дело в том что автокад понимает координаты как массивы из Double цифр. Для этого я и использую интегрированные в мою платформу методы по переводу данных. Платформа воспринимает vbs. К примеру, лишь сконвертировав координаты из Variant в массив из 3ех Double получается нарисовать линию.
 Кстати какие бы я цифры не писал в методе .SetWindowToPlot ничего не меняется. Как будто зафиксирован некий вид в модели...
Пробовал и так типы данных перевести - результат тот же
Draw.Utility.CreateTypedArray p1, vbDouble, 0, 0   
Draw.Utility.CreateTypedArray p2, vbDouble, 500, 500

p.s. в vbs коде block_ramka заменить на Ramka, не удачно скопировал

Надеюсь на ваши советы
Сколько голов, столько умов. Но голов больше

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Судя по тому, что я вижу метод
Код - Visual Basic [Выбрать]
  1. olayt.SetWindowToPlot p1, p2
вообще не срабатывает. Возможно какая-то ошибка при преобразованиях в формат точки,
который требует AutoCAD.
Попробуй для проверки вместо
Код - Visual Basic [Выбрать]
  1. Draw.Plot.PlotToFile "C:\Users\damir\Desktop\1-1-1\" + CStr(u) + ".pdf"
поставить
Код - Visual Basic [Выбрать]
  1. Draw.Plot.DisplayPlotPreview acFullPreview
Если точки переданы правильно, то в окне предпросмотра будет всё нормально.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДамирАвтор темы

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Ну вы абсолютно правы. Метод .SetWindowToPlot p1, p2 действительно не отрабатывает на него и грешу.
Draw.Plot.DisplayPlotPreview acFullPreview дал такой же результат - некорректные виды.

По поводу типов данных уже говорил. Могу выполнить любой иной метод связанный с координатами - вставка линии например. Т.е. конвертирую координаты точно правильно. Думаю в методе .SetWindowToPlot нет ничего сверхестественного он должен поедать такие же координаты, только x и y, без z (как в справке и написано)

Как я пытаюсь конвертировать
p1 = ThisApplication.Utility.VariantToArray(array(Cdbl(100), Cdbl(100)))
p2 = ThisApplication.Utility.VariantToArray(array(Cdbl(5000), Cdbl(5000)))

Собственные атокадовские методы:   
Draw.Utility.CreateTypedArray p1, vbDouble, 0, 0
Draw.Utility.CreateTypedArray p2, vbDouble, 500, 500
Сколько голов, столько умов. Но голов больше

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Вообще-то правильно преобразовывать еще координаты из WCS в DCS (точки 3х-мерные):
Код - Visual Basic [Выбрать]
  1. point1 = ThisDrawing.Utility.TranslateCoordinates(point1, acWorld, acDisplayDCS, False)
  2. point2 = ThisDrawing.Utility.TranslateCoordinates(point2, acWorld, acDisplayDCS, False)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение