Тема: Программная отмена выполнения команд, как сделать?

Всем добрый день!
Простой вопрос, но что-то не получается.
Объявлено для выполнения ряд команд:
Set PLINE1 =....
Set PLINE2 =....
Set CIRCLE1 =....
Set CIRCLE2 =....
Set dimObj1 =....
Set dimObj2 =....
При К>0 должны выполняться только PLINE1, PLINE2, dimObj1, иначе иначе отменяются CIRCLE1, CIRCLE2, dimObj2
При Db>0 должны выполняться только CIRCLE1, CIRCLE2, dimObj2, иначе отменяются PLINE1, PLINE2, dimObj1
При К>0 и Db>0 выполняются все команды
Написала приблизительно вот такой код:
     If K > 0 Then
Set PLINE1 =....
Set PLINE2 =....
Set dimObj1 =....
     ElseIf Db > 0 Then
Set CIRCLE1 =....
Set CIRCLE2 =....
Set dimObj2 =....
      Else
        SendKeys "{Esc}"
      End If
Вроде бы все получалось, но без размеров(Set dimObj1 =.... и Set dimObj2 =....) когда стала вставлять размеры, при К>0 и Db>0, то CIRCLE1 и CIRCLE2 отрисовываться не хотят.
Подскажите, можно ли отменять выполнение команд при задаваемых условиях, не используя клавишу "Esc"

Re: Программная отмена выполнения команд, как сделать?

А вы в Debug-ere смотрели, пытается они их рисовать или нет? Мне кажется, что CIRCLE1 и CIRCLE2 отрисовываться не хотят потому, что проверка Db >0 находится в ветке ElseIf для K>0. Оно смотрит, что K>0, выполнет эту ветвь и на ElseIf не идёт. Наверно, стоит написать условие для каждого случая отдельно, дабы не запутаться...

Re: Программная отмена выполнения команд, как сделать?

Да вот истинный кусок кода:
If K > 0 Then
Set lineObj11 = ThisDrawing.ModelSpace.AddLine(PL11, PL21)
  lineObj11.Linetype = "DASHDOT"
  lineObj11.LinetypeScale = 7
  lineObj11.Update
Set lineObj21 = ThisDrawing.ModelSpace.AddLine(PL31, PL41)
  lineObj21.Linetype = "DASHDOT"
  lineObj21.LinetypeScale = 7
  lineObj21.Update
Set lineObj12 = ThisDrawing.ModelSpace.AddLine(PL12, PL22)
  lineObj12.Linetype = "DASHDOT"
  lineObj12.LinetypeScale = 7
  lineObj12.Update
Set lineObj22 = ThisDrawing.ModelSpace.AddLine(PL32, PL42)
  lineObj22.Linetype = "DASHDOT"
  lineObj22.LinetypeScale = 7
  lineObj22.Update
Set lineObj13 = ThisDrawing.ModelSpace.AddLine(PL13, PL23)
  lineObj13.Linetype = "DASHDOT"
  lineObj13.LinetypeScale = 7
  lineObj13.Update
Set lineObj23 = ThisDrawing.ModelSpace.AddLine(PL33, PL43)
  lineObj23.Linetype = "DASHDOT"
  lineObj23.LinetypeScale = 7
  lineObj23.Update
Set lineObj14 = ThisDrawing.ModelSpace.AddLine(PL14, PL24)
  lineObj14.Linetype = "DASHDOT"
  lineObj14.LinetypeScale = 7
  lineObj14.Update
Set lineObj24 = ThisDrawing.ModelSpace.AddLine(PL34, PL44)
  lineObj24.Linetype = "DASHDOT"
  lineObj24.LinetypeScale = 7
  lineObj24.Update
  Set PLINE1 = ThisDrawing.ModelSpace.AddLightWeightPolyline(PTS1)
  PLINE1.Color = acRed
  ThisDrawing.Regen (True)
  PLINE1.Closed = True 'close polyline
Set PLINE2 = ThisDrawing.ModelSpace.AddLightWeightPolyline(PTS2)
  PLINE2.Color = acRed
  ThisDrawing.Regen (True)
  PLINE2.Closed = True 'close polyline
Set PLINE3 = ThisDrawing.ModelSpace.AddLightWeightPolyline(PTS3)
  PLINE3.Color = acRed
  ThisDrawing.Regen (True)
  PLINE3.Closed = True 'close polyline
Set PLINE4 = ThisDrawing.ModelSpace.AddLightWeightPolyline(PTS4)
  PLINE4.Color = acRed
  ThisDrawing.Regen (True)
  PLINE4.Closed = True 'close polyline
Set dimObj1 = ThisDrawing.ModelSpace.AddDimRotated(point2, PL21, location5, rotAngle)
    dimObj1.LinearScaleFactor = Mb
Set dimObj2 = ThisDrawing.ModelSpace.AddDimRotated(point2, PL22, location5, rotAngle)
    dimObj2.LinearScaleFactor = Mb
Set dimObj3 = ThisDrawing.ModelSpace.AddDimRotated(PL42, point4, location6, rotAngle1)
    dimObj3.LinearScaleFactor = Mb
Set dimObj4 = ThisDrawing.ModelSpace.AddDimRotated(PL43, point4, location6, rotAngle1)
    dimObj4.LinearScaleFactor = Mb
Set dimObj5 = ThisDrawing.ModelSpace.AddDimRotated(point6, point7, location7, rotAngle1)
    dimObj5.LinearScaleFactor = Mb
Set dimObj6 = ThisDrawing.ModelSpace.AddDimRotated(point8, point7, location8, rotAngle)
    dimObj6.LinearScaleFactor = Mb
   ElseIf Db > 0 Then
Set lineObj11 = ThisDrawing.ModelSpace.AddLine(PL11, PL21)
  lineObj11.Linetype = "DASHDOT"
  lineObj11.LinetypeScale = 7
  lineObj11.Update
Set lineObj21 = ThisDrawing.ModelSpace.AddLine(PL31, PL41)
  lineObj21.Linetype = "DASHDOT"
  lineObj21.LinetypeScale = 7
  lineObj21.Update
Set lineObj12 = ThisDrawing.ModelSpace.AddLine(PL12, PL22)
  lineObj12.Linetype = "DASHDOT"
  lineObj12.LinetypeScale = 7
  lineObj12.Update
Set lineObj22 = ThisDrawing.ModelSpace.AddLine(PL32, PL42)
  lineObj22.Linetype = "DASHDOT"
  lineObj22.LinetypeScale = 7
  lineObj22.Update
Set lineObj13 = ThisDrawing.ModelSpace.AddLine(PL13, PL23)
  lineObj13.Linetype = "DASHDOT"
  lineObj13.LinetypeScale = 7
  lineObj13.Update
Set lineObj23 = ThisDrawing.ModelSpace.AddLine(PL33, PL43)
  lineObj23.Linetype = "DASHDOT"
  lineObj23.LinetypeScale = 7
  lineObj23.Update
Set lineObj14 = ThisDrawing.ModelSpace.AddLine(PL14, PL24)
  lineObj14.Linetype = "DASHDOT"
  lineObj14.LinetypeScale = 7
  lineObj14.Update
Set lineObj24 = ThisDrawing.ModelSpace.AddLine(PL34, PL44)
  lineObj24.Linetype = "DASHDOT"
  lineObj24.LinetypeScale = 7
  lineObj24.Update
  Set circleObj1 = ThisDrawing.ModelSpace.AddCircle(centerPoint1, radius)
    circleObj1.Color = acRed
    ThisDrawing.Regen (True)
Set circleObj2 = ThisDrawing.ModelSpace.AddCircle(centerPoint2, radius)
    circleObj2.Color = acRed
    ThisDrawing.Regen (True)
Set circleObj3 = ThisDrawing.ModelSpace.AddCircle(centerPoint3, radius)
    circleObj3.Color = acRed
    ThisDrawing.Regen (True)
Set circleObj4 = ThisDrawing.ModelSpace.AddCircle(centerPoint4, radius)
    circleObj4.Color = acRed
    ThisDrawing.Regen (True)
Set dimObj1 = ThisDrawing.ModelSpace.AddDimRotated(PL21, point2, location5, rotAngle)
    dimObj1.LinearScaleFactor = Mb
Set dimObj2 = ThisDrawing.ModelSpace.AddDimRotated(point2, PL22, location5, rotAngle)
    dimObj2.LinearScaleFactor = Mb
Set dimObj3 = ThisDrawing.ModelSpace.AddDimRotated(PL42, point4, location6, rotAngle1)
    dimObj3.LinearScaleFactor = Mb
Set dimObj4 = ThisDrawing.ModelSpace.AddDimRotated(point4, PL43, location6, rotAngle1)
    dimObj4.LinearScaleFactor = Mb
      Else
        SendKeys "{Esc}"
      End If
До тех пор, пока размеры (dimObj...) не добавила, все было красиво. Условия отрисовки линий, полилиний и окружностей выполнялись так, как надо.
Это первая моя программа. Подозреваю, что код можно сократить, но не знаю как

Re: Программная отмена выполнения команд, как сделать?

1) А можно исходную постановку задачи изложить?...
2) Кстати, когда вставляете в форум программный код, есть такая штука: [_code] программный код [_/code] (подчёркивания не надо, я их вставила для того, чтобы эта написанная строчка отобразилась нормально). Тогда не будут убираться отступы и "лишние" пробелы. А то оно плохо читается...
3) Что означают числа у ineObj? Есть подозрение, что можно это дело в цикл засунуть, только я пока не могу понять, что надо получить в итоге и что нам дано на входе.

Re: Программная отмена выполнения команд, как сделать?

> ЛАРИСА
Я не спец в VBA, но почему б не объединить повторяющийся код?

Sub MyAddLine(ptStart() As Double, ptEnd() As Double, Optional sLineType As String = "DASHDOT", Optional dLineTypeScale As Integer = 7)
Dim oLine As AcadLine
  Set oLine = ThisDrawing.ModelSpace.AddLine(ptStart, ptEnd)
  oLine.Linetype = sLineType
  oLine.LinetypeScale = dLineTypeScale
  oLine.Update
End Sub
Sub MyAddLWPline(ptlist() As Double, Optional lColor As Integer = acRed, Optional bIsCLosed As Boolean = True)
Dim oLWPline As AcadLWPolyline
  On Error Resume Next
  Set oLWPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(ptlist)
  oLWPline.color = lColor
  oLWPline.Closed = bIsCLosed
End Sub
Sub MyAddDimRot(ptStart() As Double, ptEnd() As Double, ptLoc() As Double, lAngle As Double, lLinearScale As Long)
Dim oDimRot As AcadDimRotated
  oDimRot = ThisDrawing.ModelSpace.AddDimRotated(ptStart, ptEnd, ptLoc, lAngle)
  oDimRot.LinearScaleFactor = lLinearScale
End Sub
Sub MyAddCircle(ptCenter() As Double, lRadius As Long, Optional lColor As Integer = acRed)
Dim oCircle As AcadCircle
  On Error Resume Next
  oCircle = ThisDrawing.ModelSpace.AddCircle(ptCenter, lRadius)
  'oCircle.TrueColor = lColor
End Sub

Тогда в первом приближении основной код станет подобным:

  If K > 0 Then
    MyAddLine pl11, pl21: MyAddLine pl31, pl41: MyAddLine pl12, pl22
    MyAddLine pl32, pl42: MyAddLine PL13, PL23: MyAddLine PL33, PL43
    MyAddLine PL14, PL24: MyAddLine PL34, PL44
    MyAddLWPline pts1: MyAddLWPline pts2: MyAddLWPline pts3: MyAddLWPline pts4
    MyAddDimRot point2, pl21, location5, rotAngle, mb: MyAddDimRot point2, pl22, location5, rotAngle, mb
    MyAddDimRot pl42, point4, location6, rotAngle1, mb: MyAddDimRot PL43, point4, location6, rotAngle1, mb
    MyAddDimRot point6, point7, location7, rotAngle1, mb: MyAddDimRot point8, point7, location8, rotAngle, mb
  ElseIf Db > 0 Then
    MyAddLine pl11, pl21: MyAddLine pl31, pl41: MyAddLine pl12, pl22: MyAddLine pl32, pl42
    MyAddLine PL13, PL23: MyAddLine PL33, PL43: MyAddLine PL14, PL24: MyAddLine PL34, PL44
    MyAddCircle centerPoint1, Radius: MyAddCircle centerPoint2, Radius: MyAddCircle centerPoint3, Radius
    MyAddCircle centerPoint4, Radius
    MyAddDimRot pl21, point2, location5, rotAngle, mb: MyAddDimRot point2, pl22, location5, rotAngle, mb
    MyAddDimRot pl42, point4, location6, rotAngle1, mb: MyAddDimRot point4, PL43, location6, rotAngle1, mb
  Else
    SendKeys "{Esc}"
  End If

Дальше. У примитивов AcadLine, AcadLWPolyline, AcadDimRotated и AcadCircle нет, по-моему, свойства Color. То есть изменение цвета не произойдет.
И в дополнение. По идее можно попробовать сделать массивы точек (правда, как в VBA с этим дело обстоит, я не очень - скорее всего, придется делать двумерные массивы) и передавать их.

Re: Программная отмена выполнения команд, как сделать?

Для полилиний точно можно массивы. А размерность зависит от типа: LWPolyline - 2D масиив, 2D и 3D полилинии - 3D массив. Для остальных обектов не пробовала.

Re: Программная отмена выполнения команд, как сделать?

[rus] Ne mogu ponjat', zachem voobshe zdes'
[/rus]

SendKeys "{Esc}"

Ничего вам отменять ненадо. А надо рисовать только те примитивы которые нужны. Т.е. сначала делать самую строгую проверку, а затем более мягкие:

If K > 0 AND Db > 0 Then
   Set PLINE1 =....
   Set PLINE2 =....
   Set CIRCLE1 =....
   Set CIRCLE2 =....
   Set dimObj1 =....
   Set dimObj2 =....
ElseIf Db > 0 Then
   Set CIRCLE1 =....
   Set CIRCLE2 =....
   Set dimObj2 =....
ElseIf K > 0 Then
   Set PLINE1 =....
   Set PLINE2 =....
   Set dimObj1 =....
End If

Re: Программная отмена выполнения команд, как сделать?

Отрисовывается прямоугольный фундамент (PLINE) и его оси (lineObj). Фундамент имеет прямоугольные отверстия (PLINE1,2,3 и т.д)и оси(lineObj) у этих отверстий (lineObj11,12,13 и т.д). Иногда вместо отверстий(или вместе с отверстиями) бывают болты (circleObj1,2,3 и т.д) с осями(lineObj11,12,13 и т.д).
К-это размер отверстия, Db-диаметр болта. Отсюда и условие: K>0 рисуем отверстия, Db>0 рисуем болты. Когда K>0 и Db>0 одновременно, рисуем и отверстия и болты.
Может быть мне условие как-то иначе поставить?
А с массивами попробую разобраться.

Re: Программная отмена выполнения команд, как сделать?

> kpblc
С цветом все нормально работает. Меня коробит только то, что для каждой линии приходиться задавать цвет. Код длинный из-за этого получается. То же с заданием переменной для размера (dimObj2.LinearScaleFactor = Mb) и т.д.
Спасибо всем, особенно Gogi. Заработало! Но код получается убийственно огромный. А мне еще столько надо написать!

Re: Программная отмена выполнения команд, как сделать?

> ЛАРИСА
Дык ета... Я ж вынес повторяющиеся куски отдельно.  Код сократился? Да и отлаживать его проще, и ошибок меньше :)
И потом, можно же объединить мой код и код Gogi, получится вообще почти конфетка :)
---
ИМХО

Re: Программная отмена выполнения команд, как сделать?

для каждой линии приходиться задавать цвет

А почему не сделать цвет ByLayer (а самому Layer-y установить нужный вам цвет)? Или у вас все объекты разных цветов?... Мне кажется, стоит сделать отдельные слои для отверстий и болтов, и сам фундамент тоже в отдельный слой засунуть. Даже если у вас всё одного цвета, вдруг, дальше понадобится...

код получается убийственно огромный

Если вы ещё не последовали совету kpblc насчёт отдельных функций, то мне кажется, стоит это сделать.

А мне еще столько надо написать!

А кому сейчас легко?! Не отчаивайтесь! Нас много. :)

Re: Программная отмена выполнения команд, как сделать?

> kpblc
У меня там еще всякая всячина, одно за другое цепляется. Я поняла, что Ваш код го-о-ораздо короче получается. Обещаю переписать свой код в ближайшее время. Приятно, когда есть у кого спросить и есть кому ответить!!

Re: Программная отмена выполнения команд, как сделать?

> ЛАРИСА
Так тогда попробуйте использовать функции, передавая им параметры с ключевым словом Optional и задавая значение по умолчанию. Тогда все будет попроще, думаю. Чем сложнее кажется вся задача, тем проще ее как правило разбить на похожие куски и делать уже их.
---
Оффтоп:
Одно из моих правил: Если похожий код выполняется больше 3 раз и имеет в длину более 3 строк, выносить его в отдельную функцию. И вызывать уже ее.

Re: Программная отмена выполнения команд, как сделать?

> kpblc
Разобралась с вашим кодом. Здорово! Есть несколько вопросов:
1. Почему строка "On Error Resume Next" присутствует только в процедурах с Pline и Circle?
2. Что означают пустые скобки? ()
3. Где можно прочитать про ключевые слова, в частности про Optional?
4 . В чем разница между VBA и VB?

Re: Программная отмена выполнения команд, как сделать?

> ЛАРИСА
Ох придет сейчас админ, порежет ветку :)
0. Прошу ко мне на "ты" - я среди своих клонов потеряться могу :)

1. Почему строка "On Error Resume Next" присутствует только в процедурах с Pline и Circle?

Потому что свойства Color в перечислении свойств LightWeightPolyline и Сircle нет. Есть TrueColor.

2. Что означают пустые скобки? ()

Что передается массив с заранее не известной размерностью

3. Где можно прочитать про ключевые слова, в частности про Optional?

В справке. По крайней мере я там нашел, читая примеры.

4 . В чем разница между VBA и VB?

Программы, выполненные на VB, могут выполняться в отдельном процессе. Код VBA - только внутри приложения, в котором он написан. Т.е. VB-шный код можно скомпилировать в исполняемый файл (обычный exe) и запустить. VBA - только в контексте того приложения, в котором он написан. Запустить Excel'ный макрос внутри AutoCAD'a не получится.

Re: Программная отмена выполнения команд, как сделать?

> kpblc
А синтаксис написания кода в VB и VBA что, практически не отличается? Литературкой одной можно пользоваться для VB и VBA?

Re: Программная отмена выполнения команд, как сделать?

Вроде как да.

Re: Программная отмена выполнения команд, как сделать?

Спасибо тебе, добрый крЫс!

Re: Программная отмена выполнения команд, как сделать?

> kpblc
У примитивов AcadLine, AcadLWPolyline, AcadDimRotated и AcadCircle нет, по-моему, свойства Color
вот пример работающего кода
sAcadVER=16 для 2004-2006
sAcadVER=17 для 2007

Private oColor As AutoCAD.AcadAcCmColor
Set oColor = oApp.GetInterfaceObject("AutoCAD.AcCmColor." & sAcadVER)
   '
   ...
   oColor.SetRGB 80, 100, 244
   oCircle.TrueColor = oColor

Re: Программная отмена выполнения команд, как сделать?

> brigval
Мое почтение! Так, насколько я понимаю, ты обращаешься все равно к свойству TrueColor. Свойство .Color доступно только внутри AutoCAD'a (похоже на рудимент, как (vla-get-color) или (vlax-invoke), который в дальнейшем может быть ликвидирован).

Re: Программная отмена выполнения команд, как сделать?

Боже, не успела порадоваться, что код укоротила, следующая беда:
У меня первая строка кода
Private Sub OKbutton_Click(),
Если я добавляю далее несколько процедур (Sub...), то возникает ошибка
"Expected End Sub"
Где ему этот End Sub ставить?  А может быть что-то еще.
Как вообще должно выглядеть тело кода. У меня получается примерно так (и ничего не работает):

 Private Sub OKbutton_Click()
End Sub
____________________________________
Sub AddLine...
End Sub
____________________________________
Sub AddPline...
End Sub
____________________________________
Sub AddDimRot
End Sub
____________________________________
  AddLine p1, p2
  AddPline pts1
  AddDimRot pt1, pt2, loc1, mb
If K>0 and Db>0 Then
  AddLine p3, p4
  AddPline pts2
  AddDimRot pt3, pt4, loc2, mb
  AddLine p5, p6
  AddPline pts3
  AddDimRot pt4, pt5, loc3, mb
ElseIf K>0  Then
  AddLine p3, p4
  AddPline pts2
  AddDimRot pt3, pt4, loc2, mb
ElseIf Db>0  Then
  AddLine p5, p6
  AddPline pts3
  AddDimRot pt4, pt5, loc3, mb
Else
End If

Re: Программная отмена выполнения команд, как сделать?

Меня смущает последний фрагмент - почему он не внутри некой функции? Думаю, на это ругается... Кроме End sub  нужно ещё начало :) этой sub, например, Sub MyMainFunc(). После этого можно вставить тот бесхозный фрагмент, а в конце приписать End sub. Мне кажется, это будет запускаться.

Re: Программная отмена выполнения команд, как сделать?

А может

> ЛАРИСА
просто стебется над нами ?

Re: Программная отмена выполнения команд, как сделать?

kpblc пишет:

Свойство .Color доступно только внутри AutoCAD'a

Свойство Color работает, но для него надо задавать числа от 0 до 255 из цветовой схемы Index Color

Re: Программная отмена выполнения команд, как сделать?

> brigval
Спасибо, учту :)