Академический Документы
Профессиональный Документы
Культура Документы
СОДЕРЖАНИЕ
01.Об AVEVA ................................................................................................................................................................. 3
02.Об AVEVA PDMS и AVEVA MARINE ......................................................................................................................... 3
03.Об этом блоге (справочнике) ................................................................................................................................. 3
04.Терминология ......................................................................................................................................................... 4
05.Что такое PML .......................................................................................................................................................... 4
06.Базовые конструкции языка. Условия................................................................................................................... 5
07.Запросы к Dabacon. Часть 1.................................................................................................................................... 5
08.Базовые конструкции языка. Работа с циклами. Часть 1 .................................................................................... 6
09.Пример работы с базой .......................................................................................................................................... 6
10.Базовые конструкции языка. Работа с циклами. Часть 2 .................................................................................... 7
11.Запросы к Dabacon. Часть 2.................................................................................................................................... 7
12.Работа с файлами. Часть 1 ..................................................................................................................................... 8
13.Работа с графикой. Часть 1 ..................................................................................................................................... 8
14.Работа со строками. Часть 1 ................................................................................................................................... 9
15.Работа с графикой. Часть 2 ................................................................................................................................... 10
16.Пример работы с коллекцией ............................................................................................................................. 11
17.Сообщения пользователю. Часть 1 ..................................................................................................................... 11
18.Пример использования коллекций. Обработка модели................................................................................... 12
19.Пример редактирования атрибутов .................................................................................................................... 13
20.Работа с датой и временем ................................................................................................................................. 14
21.Пример обработки ссылок ................................................................................................................................... 14
22.Пример обработки ссылок. Продолжение ......................................................................................................... 15
23.Автоматизация работы администратора. Часть 1 .............................................................................................. 15
24.Автоматизация работы администратора. Часть 2 .............................................................................................. 16
25.Механизмы работы с объектами. Часть 1 .......................................................................................................... 17
26.Автоматизация работы администратора. Часть 3 .............................................................................................. 18
27.Автоматизация работы администратора. Часть 4,5 ........................................................................................... 18
28.Автоматизация работы администратора. Часть 6,7 ........................................................................................... 19
29.Работа с графикой. Часть 3 ................................................................................................................................... 20
30.Пользовательские проверки данных построения ............................................................................................. 20
31.Файловый проводник ........................................................................................................................................... 22
32.Автоотключение MTOC при создании трубопроводного компонента ............................................................ 22
33.Массовая печать из Draft в DXF/PDF ................................................................................................................... 23
34.Визуальное отображение "головы"/"хвоста" трубопровода ............................................................................ 24
35.Макрос для подсчета элементов......................................................................................................................... 24
36.Подсчет количества сварных швов ..................................................................................................................... 25
37.Разбивка трубопровода фланцами ..................................................................................................................... 26
38.Масштабирование и центрирование содержимого экрана ............................................................................. 27
39.Нахождение коллизий указанного элемента ..................................................................................................... 28
40.Описание опор в зависимости от координаты .................................................................................................. 29
41.Автоизменение параметров каталога................................................................................................................. 29
42.Удаление элементов с помощью графического выделения ............................................................................. 29
43.Раскрашивание элементов бранча в 3D-модели ............................................................................................... 30
44.Когда длина детального текста превышает 120 символов... ............................................................................ 30
45.Вычисляем реальную длину текста на чертеже ................................................................................................. 31
46.Маркировка в Design выбранным атрибутом .................................................................................................... 31
47.Пример команды FLIP для SCTN .......................................................................................................................... 32
48.Пишем свой класс на PML 2. Часть 1 ................................................................................................................... 32
49.Пишем свой класс на PML 2. Часть 2 ................................................................................................................... 32
01.Об AVEVA
Компания AVEVA является ведущим разработчиком решений для проектирования, инжиниринга и
управления проектами в нефтегазовой, энергетической, судостроительной и шельфовой промышленности.
Система интегрированных решений AVEVA сопровождает объект на всем протяжении его жизненного цикла
- от создания проекта и его разработки, до управления проектными данными, технического обслуживания,
модернизации и вывода объекта из эксплуатации. Решения AVEVA позволяют инжиниринговым компаниям
максимально эффективно осуществлять проектные работы по всем дисциплинам, а эксплуатирующим
организациям дают возможность управлять всеми данными и процессами на базе единой платформы, что в
разы сокращает материальные и временные затраты.
ООО “АВЕВА” – дочерняя компания Aveva Group Plc., осуществляющая свою деятельность на территории
России и стран СНГ. Решения, прошедшие проверку многолетним международным опытом работы
крупнейших организаций и ставшие мировым стандартом, на сегодняшний день адаптированы к условиям
российского рынка. Клиенты ООО “АВЕВА” - это ведущие компании энергетической промышленности,
нефтегазового сектора и судостроения.
AVEVA MARINE – это набор интегрированных программных продуктов для проектирования и постройки
судов в сочетании с открытыми и гибкими решениями по управлению жизненным циклом объекта в целом.
Эти продукты обеспечивают быстрое и продуктивное проектирование без рисков, постройку и
эксплуатацию судов и средств освоения шельфа любых размеров и сложности.
04.Терминология
Для правильного понимания сущности проектирования с использованием AVEVA PDMS и AVEVA MARINE
необходим владеть соответствующей терминологией. Далее приведены некоторые термины, важные для
понимания в первую очередь.
Базовый синтаксис:
if ( УСЛОВИЕ ) then
--код, выполняемый при выполнении УСЛОВИЯ
--если УСЛОВИЕ не выполняется, код тоже не будет выполнен
endif
Пример:
Выполнение действия в зависимости от типа текущего элемента
(вернуться к содержанию)
Базовый синтаксис:
VAR !items COLLECT ALL что_искать FOR где_искать
где
что_искать - тип элемента для поиска
где_искать - место в иерархии где будет происходит поиск
Результат:
В переменную !items запишется массив значений типа STRING референтных номеров найденных элементов.
При отсутствии элементов размер массив будет равен 0 (для использования с условными операторами)
Пример:
VAR !items COLLECT ALL VALV FOR CE
в этом случае в переменную !items запишется массив референтных номеров, найденных элементов типа
VALV. Поиск будет осуществлен внутри текущего элемента.
(вернуться к содержанию)
Синтаксис:
do !x from ИНДЕКС_СТАРТА to КОНЕЧНАЯ_ТОЧКА
--действия, которые выполняются с элементами относительно индекса !x
enddo
Пример:
Напечатать в командной строке значений от 1 до 10
do !x from 1 to 10
$P $!x
enddo
В результате в командную строчку будут выведены значения переменной !x, являющейся индексом.
Приращение индекса, или шаг цикла в данном случае = 1. Соответственно выводимые значения будут
начинаться с единицы, как стартовой точки, и далее с шагом 1 до десяти..
(1,2,3,4,5,6,7,8,9,10)
Другой пример:
do !x from 1 to 10 by 0.5
$P $!x
enddo
В результате в командную строчку будут выведены значения переменной !x, являющейся индексом. В
данном случае приращение указано специально и составляет 0.5. Соответственно выводимые значения
будут начинаться с единицы как стартовой точки, и далее с шагом 0.5 до десяти.
(1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,8.5,9,9.5,10)
(вернуться к содержанию)
Решение:
необходимо использовать синтаксис обращения к базе для запроса элементов, далее в запустить цикл по
полученном массиву, запросить необходимые атрибуты и вывести на экран
Задача:
вывести на экран результаты умножения цифры из ряда на все цифры из ряда по очереди.
Решение:
--Вводим массив цифр. Далее приведен один из способов генерации массива из строки
!digitString = '1 2 3 4 5 6 7 8 9'
--с помощью метода .Split(), который применен к строковой переменной, мы получаем массив данных.
--Если .Split() применен без параметров, тогда применяется разделитель по умолчанию - пробел
!digitArray = !digitString.Split()
--Запускаем первый цикл для того, чтобы определить множимое число
do !x from 1 to !digitArray.Size()
--записываем первый множитель в переменную, которая будет использована во втором цикле
!var1 = !digitArray[!x].Real()
--запускаем второй цикл по той же самой конечной точке для того, чтобы выполнить операцию умножения
--множимого числа.
--Метод .Real() применятся к строковому значению для преобразования его в число, чтобы производить арифметические операции
--NB: переменная-индекс внутри вложенного цикла не должна иметь одинаковое имя с переменной индекса циклов-хозяев
do !y from 1 to !digitArray.Size()
!var2 = !digitArray[!y].Real()
--умножаем два элемента: первый из первого цикла, неменяющийся пока не кончится второй цикл, второй – из второго цикла,
--меняющийся по ходу работы второго цикла
!resultReal = !var1 * !var2
--формируем визуальное составляющее - строчку для печати
!resultToPrint = !var1.String() + 'x' + !var2.String() + '=' + !resultReal.String()
--печатаем на экран
$P $!resultToPrint
enddo
NB. не забывайте следить, чтобы каждый цикл был "закрыт" командой enddo
(вернуться к содержанию)
Задача:
найти и вывести все элементы типа EQUI, у которых в атрибуте Desc встречается слово "Насос"
Вариант 1.
Запрос типа без фильтра и фильтрация в цикле (долгий вариант)
Вариант 2.
Запрос типа с указанием фильтра (быстрый вариант)
--запрашиваем элементы типа EQUI сразу включая фильтр, чтобы в коллекцию попали элементы типа EQUI у которых в
--атрибуте Desc было слово Насос
VAR !equi COLLECT ALL EQUI WITH ( MATCHWILD(NAME,'*Насос*') ) FOR CE
--запускаем цикл с конечной точкой = размер полученного массива элементов
do !x from 1 to !equi.Size()
--сразу выводим на печать, так как в найденном массиве уже есть нужные элементы
$P $!equi[$!x]
Enddo
(вернуться к содержанию)
Пример 1.
Открыть файл с определенным именем и считать информацию в массив
Пример 2.
Считать содержимое файла и проверить нахождение слова "Задвижка" в каждой из строк
Синтаксис:
ID @
после выполнения этой команды система переходит в режим ожидания, когда пользователь выберет на
экран элемент (любой). После выбора элемент станет текущим в иерархии.
Разновидности синтаксиса:
ID ТИП_ЭЛЕМЕНТА @
явное указание какой тип элемента должен быть выбран. Система будет находиться в режиме ожидания
пока не будет выбран корректный тип элемента.
Пример 1.
указать элемент типа EQUI
ID EQUI @
Пример 2.
указать элемент типа либо EQUI либо VALV
ID EQUI VALV @
Пример 3.
диалог с пользователем - перед тем как войти в режим указания элемента, пользователю будет открыто
окно с подсказкой
!!Alert.Message('Укажите EQUI')
ID EQUI @
(вернуться к содержанию)
Пример 1.
Отделение части строки ДО определенного символа или выражения
!resultVar = !stringVar.Before('#')
В результате в переменную !resultVar запишется значение 'Задвижка клиновая с выдвижным шпинделем ', то
есть то, что находится ДО значения, указанного в качестве параметра метода, то есть в примере это #.
Применяется метод .Before('СТРОКОВОЕ_ЗНАЧЕНИЕ_ВЫРАЖЕНИЯ_ДО_КОТОРОГО')
NB: пробелы тоже считаются
Пример 2.
Отделение части строки ПОСЛЕ определенного символа или выражения
!resultVar = !stringVar.After('#')
В результате в переменную !resultVar запишется значение ' 30c41нж/30нж41нж', то есть то, что находится
ПОСЛЕ значения, указанного в качестве параметра метода.
Применяется метод .After('СТРОКОВОЕ_ЗНАЧЕНИЕ_ВЫРАЖЕНИЯ_ПОСЛЕ_КОТОРОГО')
NB: пробелы тоже считаются
Пример 3.
Отделение подстроки указанной длины, начиная с определенного места (по порядковому номеру в строке)
!resultVar = !stringVar.Substring(1,8)
В результате в переменную !resultVar запишется значение 'Задвижка' - то есть, начиная с первого символа и
длиной 8.
Применяется метод .Substring(начало(тип Real),длина(тип Real))
NB:Если не указывается длина (то есть будет указан только один параметр), то будет взята вся оставшаяся
строка, начиная с указанного места
Пример 4.
Разбить строку на массив строковых значений по указанному разделителю
!resultArray = !stringVar.Split('#')
Пример 5.
Разбить исходную строку таким образом, чтобы в первую переменную записалось наименование,
расположенное до символа '#', а во вторую переменную - массив фигур (ячейка=фигура)
!description = !stringVar.Before('#').Trim()
!figuresArray = !stringVar.After('#').Split('/')
Последовательно применяется несколько методов к одному объекту. В объектно-ориентированном языке,
каким является PML 2, методы применяются последовательно. В первом случае применено два метода:
сначала получаем то, что следует до указанного строкового значения, а потом сразу метод .Trim(),
позволяющий убрать пробелы по краям строки. Во втором случае тоже используется два метода
последовательно: сначала получаем то, что следует после указанного строкового значения, а затем, зная
разделитель, получаем массив, разбив значение.
(вернуться к содержанию)
Указание P-точек.
В отличии от обычной команды указания элемента, команда указания точек используется только в виде
запроса:
Q IDP @
после выполнения команды система переходит в режим ожидания указания P-Точки
Для того, чтобы обработать информацию, взятую из точки, можно использовать следующий синтаксис:
VAR !ppointData IDP @
При этом система переходит в режим выбора точки и, после того, как пользователь указал точку в
переменную !ppointData запишется атрибутика точки, например:
'Ppoint 1 =23584/378 100 U E 9630 N 3463 U 9295 FBB'
где
Ppoint 1 - точка и ее номер,
=23584/378 - референтный номер элемента, которому принадлежит точка,
100 - диаметр в точке (если точка имеет его, в противном случае это значение будет пропущено),
U - направление точки,
E 9630 - координата по E/W,
N 3463 - координата по N/S,
U 9295 - координата по U/D и
FBB - тип присоединения (если точка имеет его, в противном случае значение будет пропущено)
Указание P-линий
По аналогии с точкам команда указания P-линий используется только для запроса атрибутики:
Q IDPLI @
после выполнения команды система переходит в режим ожидания указания P-линии
(вернуться к содержанию)
Задача:
необходимо найти все элементы типа VALV, у которых в наименовании есть слово 'Задвижка' и присвоить
каждому найденному элементу уникальный идентификатор, базирующийся на атрибуте Styp из
спецификации + номер суффикса.
Решение:
(вернуться к содержанию)
Причем в переменную !answer будет записано либо 'YES' либо 'NO' в зависимости от нажатой кнопки
(вернуться к содержанию)
Решение:
делаем запросы к базе на предмет нахождения элементов типа PIPE, далее запускаем
цикл, в цикле обрабатываем каждый элемент на предмет нахождения диаметра (функция .Before(), .After()),
присвоения атрибута Bore в найденное значение, учитывая что это должно быть число, вывод на экран и
раскраской согласно указанной фильтрации
HANDLE ANY
SKIP
ENDHANDLE
--задаем атрибут через обращение к объекту массива
!pipes[!x].Dbref().Bore = !boreB
--вычисляем нужный цвет
if (!boreS EQ '40') then
!colour = 'BLUE'
elseif (!boreS EQ '80') then
!colour = 'RED'
elseif (!boreS EQ '100') then
!colour = 'GREEN'
elseif (!boreS EQ '150') then
!colour = 'YELLOW'
elseif (!boreS EQ '200') then
!colour = 'GREY'
elseif (!boreS EQ '250') then
!colour = 'DARKBROWN'
else
!colour = 'WHITE'
endif
--добавляем элемент
ADD $!pipes[$!x]
--раскрашиваем
ENHANCE $!pipes[$!x] COLOUR $!colour
enddo
--далее следует набор команд для выполнения операции
--Walk to drawlist (центрирование всех объектов экрана)
var !collection COLLECT ALL FROM DRAWLIST
!block = OBJECT BLOCK('!collection[!evalindex].dbref()')
!list = !collection.evaluate(!block)
!volume = object volume(!list)
!lim = OBJECT GPHVIEWS()
!lim.limits(!!gph3ddesign1.view, !volume)
(вернуться к содержанию)
Решение:
состоит из двух частей - коллекция и запись в файл и считывание файла и запись атрибута
Часть первая (код первого макроса): собираем все элементы типа EQUI внутри текущего элемента -->
формируем массив для вывода во внешний файл --> выводим в файл, затем файл редактируется средствами
Excel
--собираем коллекцию
VAR !allEqui COLLECT ALL EQUI FOR CE
--запускаем цикл для формирования массива данных на вывод
--разделитель - точка с запятой для того, чтобы Excel автоматически разбил по столбцам при открытии
do !x from 1 to !allEqui.Size()
!outputArray[!x] = !allEqui[!x].Dbref().Name + ';' + !allEqui[!x].Dbref().Desc
enddo
--формируем файл
!fileName = 'c:\equips.csv'
!fileObj = OBJECT FILE(!fileName)
--записываем информацию, используя метод .Writefile(‘СПОСОБ_ЗАПИСИ’,МАССИВ_ДАННЫХ)
!fileObj.Writefile('OVERWRITE',!outputArray)
Часть вторая (код второго макроса): считываем файл и загружаем данные, присваивая атрибут
!fileName = 'c:\equips.csv'
!fileObj = OBJECT FILE(!fileName)
--считываем данные в массив
!fileData = !fileObj.Readfile()
$!equiName
DESC |$!equiDesc|
Enddo
(вернуться к содержанию)
Пример:
получить текущую дату и время в формате <день>-<месяц>-<год>,<час>:<минуты>:<секунды>
Результатом будет:
<STRING> '12-3-2011,13:38:6'
(вернуться к содержанию)
SKIP IF (!nozzles[!x].DbRef().Cref.Unset())
!link = !nozzles[!x].DbRef().Cref
ADD $!link
enddo
(вернуться к содержанию)
Для того, чтобы понять вход или выход потока на штуцере необходимо запросить псевдоатрибут CEND, в
который записывается либо HEAD либо TAIL (выход и вход соответственно)
(вернуться к содержанию)
В этом и нескольких следующих темах рассмотрим примеры автоматизации некоторых рутинных действий
администратора.
Процедура описанная в блоке 1, позволяет автоматически закрыть работу всех пользователей. Безусловно
такая операция должна выполнять только ночью на сервере в автоматическом режиме. Для запуска
автоматического режима необходимо предусмотреть обычный планировщик Windows в который прописать
команду запуска PDMS в терминальном режиме (без интерфейса) и дать команду на выполнение
необходимого макроса.
Пример: свойства запускаемого ярлыка - \.....\pdms.bat TTY SAM SYSTEM/XXXXXX /SAMPLE $M/d:\night-
process-run.pmlmac
При этом в файле night-process-run.pmlmac будет записан рассматриваемый код автоматизации действий
администратора.
(вернуться к содержанию)
do !x from 1 to !DBS.Size()
--пропускаем если база является Foreign
skip if (!DBS[!x].DbRef().Fore EQ 'FOREIGN')
!dbName = !DBS[!x].DbRef().Name
endif
enddo
enddo
--выводим результаты проверки первого лог-файла во второй лог файл
!outputLOGFILE.WriteFile('OVERWRITE',!outputLOG)
--Конец части 2
В строчке !outputLOGFILE = object file('$!folders[1]' + '!TotalLOG-DB.log') упоминается переменная !folder[1]. См. первую
часть
Эта часть является продолжением. Соответственно все части кода могут объединяться в один файл или
запускать по очереди из разных
(вернуться к содержанию)
Пример:
Есть элемент технологического оборудования, у которого есть штуцер (NOZZ). К штуцеру впоследствии
должен быть присоединен участок трубопровода (BRAN). В момент создания BRAN мы указываем точку –
штуцер и система понимает, как присоединять трубу. При этом у элемента BRAN есть атрибут Href и Tref, в
которые, в момент указания штуцера присоединения и в зависимости от того, что мы присоединяем (голову
- Href или хвост - Tref) записывается имя этого штуцера (или его референтный номер).
У штуцера же в свою очередь заполняется атрибут Cref, в который попадает имя присоединенного BRAN (а
если запросить еще и псевдоатрибут CEND, можно понять - голова или хвост бранча присоединены в этот
штуцер).
Таким образом устанавливается двухсторонняя связь между элементами...
Запрос на PML1
VAR !nozzcref CREF
В переменную !nozzcref запишется строчка с именем бранча. При этом идет попытка запросить атрибут у
текущего элемента (CE), и если у CE нет такого атрибута, будет ошибка.
Запрос на PML2
!ncref = !!CE.Cref
В переменную !ncref запишется объект (типа Dbref()) (!) базы данных со всеми атрибутами. Это большое
отличие от запроса на PML1, где все результаты трактуются как строковые объекты.
Соответственно, продолжив цепочку обращений к объекту, указанному в ссылке, можно получить любой
атрибут. Например, обращаясь к штуцеру, нужно получить значение Description присоединенного бранча
Пример:
!brandesc = !!CE.Cref.Desc
То есть через ’точку’ можно получить любой атрибут, главное чтобы в цепочке появился объект. В данном
случае он появляется с выражением !!CE.Cref
Другой пример
В модели есть задвижка. Необходимо обратиться через модель к каталогу и получить атрибут Description из
SCOM (каталожного компонента).
Предположим, что текущий элемент это VALV, тогда, зная, что у элемента трубопроводов в модели есть
атрибут Spref, указывающий на компонент спецификации (SPCO), а у того в свою очередь есть атрибут Catref,
указывающий на каталожный компонент, выражение будет выглядеть следующим образом:
!scomdesc = !!CE.Spref.Catref.Desc
В переменную !scomdesc запишется значение атрибута Desc из SCOM. (Следует, учитывать, что если ссылка не
установлены, тогда система выдаст ошибку. Как ее отследить – в других темах.)
(вернуться к содержанию)
(вернуться к содержанию)
Проверки
--Блок 5. Проверка трубопроводов. На примере проекта SAM
--Встаем на SITE
SITE /STABILIZER
ZONE /PIPES
--собираем трубы
!pipes = !!CollectAllFor('PIPE',||,CE)
--формируем лог
!outputLOG = object array()
!outputLOGFILE.WriteFile('OVERWRITE',!outputLOG)
--Конец блока 5
(вернуться к содержанию)
--Блок 6. Создание модели Review для просмотра на совещаниях. На примере проекта SAM
--переходим на сайт
SITE /STABILIZER
!CEName = !!CE.Name
--формируем файл ревью
VAR !projcode PROJ CODE
!revFile = object file('$!folders[3]' + '$!projcode' + '_model.rvm')
EXPORT ALL PIPE WITH (MATCHWILD(NAME,'*A*') AND NAME OF ZONE EQ '/PIPES') FOR CE COLOUR 2
EXPORT ALL PIPE WITH (MATCHWILD(NAME,'*B*') AND NAME OF ZONE EQ '/PIPES') FOR CE COLOUR 3
EXPORT ALL PIPE WITH (MATCHWILD(NAME,'*C*') AND NAME OF ZONE EQ '/PIPES') FOR CE COLOUR 6
EXPORT FINISH
--Конец блока 6
Подшивка сессий
(вернуться к содержанию)
endfunction
Код функции необходимо сохранить в файле с именем таким же как и имя функции, то есть в данном случае
- arrepr и расширением .pmlfnc. Файл должен находиться в PMLLIB. После создания функции нужно
обновить индекс файлов командой PML REHASH ALL .
Пример вызова функции - !!arrepr('INSU')
(вернуться к содержанию)
Необходимо создать функцию PML2 для выполнения определенных действий, например мы будем
проверять соответствует ли расстояние между опорой и ее смежными элементами введенному
минимальному значению, предполагая, что это расстояние от сварного шва.
do !x from 1 to !coll.Size()
$!coll[$!x]
--высчитываем расстояние слева от опоры
VAR !distL CONST DIST P1 OF CE TO P2 OF PREV
HANDLE (2,113)
VAR !distL CONST DIST P1 OF CE TO PH
ENDHANDLE
enddo
return !return
endif
return !return
endfunction
Далее в папке с дефолтами проекта (%PDMSDFLTS% или %proj_idDFLTS%) создаем файл des-checks.pmldat и
вписываем в него определение правила
(вернуться к содержанию)
31.Файловый проводник
В следующем коде показан пример сохранения и открытия файла с помощью диалога Windows.
--Открытие
--Подключаем драйвер
using namespace 'Aveva.Pdms.Presentation'
Import 'pmlfilebrowser'
handle any
endhandle
--открытие
!browser = object PMLFILEBROWSER('LOAD')
!filePath = 'D:\'
!browser.show(!filePath, '', 'Открытие текстового файла’, false, 'Файлы txt (*.txt)|*.txt', 2)
!FileName = !browser.file()
--Сохранение
using namespace 'Aveva.Pdms.Presentation'
Import 'pmlfilebrowser'
handle any
endhandle
!browser = object PMLFILEBROWSER('SAVE')
!filePath = 'D:\'
!browser.show(!filePath, '', 'Сохранение текстового файла’, false, 'Файлы txt (*.txt)|*.txt', 2)
!FileName = !browser.file()
(вернуться к содержанию)
Пример:
необходимо при создании элемента типа OLET (врезка) автоматически ставить значение атрибута
MTOC=OFF, то есть выключать его из в спецификацию
Здесь lsa – это просто метка, которая впоследствии поможет быстро найти место редактирования. Всегда,
при редактировании стандартных файлов, рекомендуется использовать метки, показывающие место
редактирования
Теперь при создании элемента, если это OLET, система будет спрашивать - Установить ли значения MTOC.
(вернуться к содержанию)
--путь вывода
!outputFolder = 'd:'
--собираем листы
VAR !sheets COLLECT ALL SHEE FOR CE
--переходим на лист
$!sheets[$!x]
--печать в файл
PLOT CE DXF/$!outputFolder\$!fileNameDXF OVER
PLOT CE PDF/$!outputFolder\$!fileNamePDF 'MINL 0.22,COL BW' OVER
enddo
--открываем папку
SYSCOM 'EXPLORER $!outputFolder &'
Указанный макрос можно запускать в модуле Draft, прикрепив его вызов к кнопке. Либо делать массовую
печать в фоновом режиме.
(вернуться к содержанию)
(вернуться к содержанию)
do !f from 1 to !z.size()
!z[!f]
!x = !!collectallfor(!outelem, '', !z[!f])
!m = !x.size()
$p $!f) $!z[$!f].namn : $!m
!counter = !counter + !m
!x.clear()
enddo
$p
$p ВСЕГО ЭЛЕМЕНТОВ $!outelem: $!counter
$p
$p ==================================
(вернуться к содержанию)
enddo
--возвращаемся к элементу
$!backCE
---2.Блок 2. Отдельно сварные швы - WELD
--очищаем предыдущий вспомогательный массив
!outputA.Clear()
VAR !welds COLL ALL WELD FOR CE
do !x from 1 to !welds.Size()
$!welds[$!x]
enddo
(вернуться к содержанию)
Решение:
(вернуться к содержанию)
--определяем функцию
define function !!arwalktodrawlist()
--вводим объем типа Drawlist
!draw = object drawlist()
--получаем содержимое
!glbDraw = !draw.Globaldrawlist().Members()
--проверяем что Dralist не пустой
if (!glbdraw.size() EQ 0) then
RETURN
Endif
--обрабатываем элементы
!RT = object array()
do !x from 1 to !glbDraw.Size()
!RT[!x] = !glbDraw[!x].String()
enddo
Endfunction
--определяем функцию
define function !!arwalktodrawlist()
Endfunction
(вернуться к содержанию)
Решение:
enddo
EXIT
--вывести коллизии выполнив команды добавления и раскраски, записанные ранее
do !x from 1 to !clashesArr.Size()
$!clashesArr[$!x]
enddo
Решение:
--собираем опоры
VAR !attas COLL ALL ATTA FOR CE
do !x from 1 to !attas.Size()
$!attas[$!x]
--запрашиваем позиции по высоте
VAR !CEU U
--если позиция по U в указанном диапазоне, назначаем текст
if (!CEU.Real() GT -1000 AND !CEU.Real() LT 1000) then
Stext |Уровень 0|
endif
if (!CEU.Real() GT 1000 AND !CEU.Real() LT 5000) then
Stext |Уровень 1|
endif
enddo
(вернуться к содержанию)
Решение:
(вернуться к содержанию)
if ( !CurSelEl.Size() EQ 0 ) then
!!Alert.Message('Выделите элементы')
return
endif
--Удаляем в цикле все найденное
do !Entity values !CurSelEl
!ElName = !Entity.Name
!ElType = !Entity.Type
delete $!ElType
$P Удалено $!ElName
Enddo
(вернуться к содержанию)
Вместо названия цвета можно использовать его код. Ниже приведены коды основных цветов:
Grey 1
Red 2
Orange 3
Yellow 4
Green 5
Cyan 6
Blue 7
Violet 8
Brown 9
White 10
Pink 11
Mauve 12
Turquoise 13
Indigo 14
Black 15
Magenta 16
(вернуться к содержанию)
Запускать макрос можно находясь в иерархии на спецификации, или можно собрать компоненты
спецификации по всей MDB - для этого достаточно удалить фразу for ce в первой строчке кода.
(вернуться к содержанию)
У всех текстовых примитивов на чертеже (TEXP) есть псевдо-атрибут extent btext, в котором содержится
массив координат x,y габаритного прямоугольника, в котором размещается текст. Нумерация точек
начинается с верхней левой и далее по часовой стрелке. Характерная особенность: запросить extent btext
можно только на PML1.
Далее можно продолжить и написать функцию для переноса части текста в случае, если он не помещается в
колонку.
(вернуться к содержанию)
Решение:
--Что ищем
!what = !!Alert.Input('Тип для поиска',|SCTN|)
--Какой атрибут
!att = !!Alert.Input('Атрибут для маркирования',|DESC|)
--собираем элементы
VAR !items COLLECT ALL $!what FOR CE
do !x from 1 to !items.Size()
$!items[$!x]
--запрашиваем атрибут
var !scAtt $!att
--маркируем
MARK WITH '$!scAtt' CE
enddo
(вернуться к содержанию)
Решение:
(вернуться к содержанию)
(вернуться к содержанию)
-- Глобальная переменная !!Rndx0 - стартовое значение для фукнции генерирования случайных чисел (см. формулу)
-- Реализация генератора псевдослучайных чисел см. http://support.microsoft.com/kb/231847
!!Rndx0 = 327680
endmethod
-- *Метод .div(), вычисляющий неполное частное*
-- Подразумевается val1 - делимое, val2 - делитель
-- Используется стандратная функция INT(), отбрасывающая дробную часть
define method .div(!val1 is real, !val2 is real) is real
!this.Result = INT(!val1 / !val2)
return !this.Result
endmethod
(вернуться к содержанию)
Заключение
В дальнейшем в класс Math можно включить различные функции, которые могут пригодиться в
повседневной работе.
(вернуться к содержанию)
BTEXT '$!TextOutput'
(вернуться к содержанию)
Далее по циклу делаем с ними то, что нужно, например добавляем на экран, таким образом, получая
отображение обвязки:
do !x from 1 to !network.Size()
$!network[$!x]
ADD CE
Enddo
(вернуться к содержанию)
-- текущий вид
if (!!CE.Type NEQ 'VIEW') then
VIEW
handle (2,111)
!!alert.Message('Перейдите на Вид...')
return
endhandle
endif
!view = !!CE
!draw = !!CE.Owner.Owner
!vdir = !!CE.dir
!viewname = !!CE.name.String()
if (!vdir eq D) then
!defdir = 'N'
!defSectdir = 'U'
elseif (!vdir eq U) then
!defdir = 'N'
!defSectdir = 'D'
elseif (!vdir eq E) then
!defdir = 'N'
!defSectdir = 'W'
elseif (!vdir eq W) then
!defdir = 'N'
!defSectdir = 'E'
elseif (!vdir eq N) then
!defdir = 'E'
!defSectdir = 'S'
elseif (!vdir eq S) then
!defdir = 'E'
!defSectdir = 'N'
else
!!alert.Message('Данная утилита работает только для ортогональных видов')
return
endif
!libraryName = !viewname & '/PLANES'
!standardLibrary = object DBREF(!libraryName)
handle ANY
-- ищем все библиотеки PLLB вида
-- если нет - создаем новую
!!ce = !view
end
var !planeLibraries COLLECT ALL (PLLB) FOR CE
if (!planeLibraries.size() gt 0) then
!standardLibrary = !planeLibraries[1].dbref()
else
!!ce = !view
NEW PLLB $!libraryName
!standardLibrary = !!ce
endif
endhandle
-- формируем имя SPLA
do !i from 1 to 10
!newName = !viewname & '/SP' & !i.string()
!unusedTestName = object DBREF(!newName)
handle (2,109)
-- если имя еще не используется - выход из цикла
break
elsehandle ANY
!!alert.error(!!error.text)
return
break
elsehandle NONE
-- Имя уже используется - продолжаем цикл
endhandle
enddo
!scale = !view.vscale
!size = !view.size[1]
!position1 = !view.thpos
!position1.east = (!position1.east - ((!size / 2) / !scale) - ((!size * 0.05) / !scale))
!position2 = !view.thpos
endhandle
enddo
-- создание Drawlist
NEW IDLIST $!idlistname
NEW ADDENTRY
IDNM $!owntype $!own
--расчет положения и ориентации плоскости
!ortd = !vdir.Orthogonal($!pldir)
!ort = !ortd.String().Before('WRT')
!opd = !ortd.Opposite()
!op = !opd.String().Before('WRT')
--обновляем плоскость
-- ссылка на Drawlist
$!vsecName
IDLN IDLIST $!idlistname
!delta = !bor
-- точка 1
WPOS 1 of SPLANE $!newName
!pos1 = !posR.Offset($!pldir,-($!delta))
!pos11 = !pos1.Offset($!op,$!delta)
POS $!pos11
-- точка 2
WPOS 2 of SPLANE $!newName
!pos2 = !posR.Offset($!pldir,-($!delta))
!pos22 = !pos2.Offset($!ort,$!delta)
POS $!pos22
-- точка 3
NEW WPOS
!pos3 = !posR.Offset($!pldir,$!delta)
!pos33 = !pos3.Offset($!ort,$!delta)
POS $!pos33
-- точка 4
NEW WPOS
!pos4 = !posR.Offset($!pldir,$!delta)
!pos44 = !pos4.Offset($!op,$!delta)
POS $!pos44
--обновляем вид
$!view
UPDATE ALL
(вернуться к содержанию)
using Aveva.PDMS.PMLNet;
namespace AVEVA.PDMS.NetRandom
{
//Атрибутом PMLNetCallable помечается класс, публикуемые члены, а так же сборка
[PMLNetCallable()]
public class NetRandom
{
//Число знаков после запятой
private int _decim = 4;
//Задаем свойство
[PMLNetCallable()]
public double Decimals
{
get { return _decim; }
set { _decim = (int)value; }
}
//Конструктор по умолчанию
[PMLNetCallable()]
public NetRandom()
{
}
//Метод Assign
[PMLNetCallable()]
public void Assign(NetRandom that)
{
}
//Генерирование случайного числа в диапазоне от 0 до 1
[PMLNetCallable()]
public double GetRnd()
{
Random rnd = new Random();
return Math.Round(rnd.NextDouble(), (int)Decimals);
}
//Генерирование случайного числа в диапазоне от min до max
[PMLNetCallable()]
public double GetRnd(double min, double max)
{
Random rnd = new Random();
return Math.Round((int)min, (int)max);
}
}
}
Компилируем dll библиотеку и выкладываем ее по пути установки PDMS. Обращение к классу NetRandom из
кода PML выглядит следующим образом:
(вернуться к содержанию)
Вариант 1
При запуске модуля обрабатывается файл с синонимами, называемый VARS, который расположен в пути
%PDMSUI%\des\admin\
Соответственно, копируем это файл в точно такой же путь, но в нашу собственную папку, например
%MYPDMSUI%\des\admin\, чтобы не трогать оригинальный путь (при этом наша папка должна быть указана
в запускаемом бат-файле на первом месте перед оригинальным %PDMSUI%) и редактируем следующим
образом, добавляя в конец (перед строчкой CHOOSE AUTOC OFF) следующие строчки:
Теперь при запуске модуля Design автоматически будут выполняться указанные команды.
PS.Таким образом можно писать любые выражения на автозапуск
Вариант 2
Использовать файл start, расположенный по такому же пути. Действия одинаковые. Автовызов добавляется
в конец файла
(вернуться к содержанию)
Решение:
--собираем нужные элементы внутри текущего (в примере - арматура) и запускаем цикл обработки
var !allValves COLLECT ALL VALV FOR CE
do !x from 1 to !allValves.Size()
--первый массив - массив диаметров, взятых из каталога. ВАЖНО - массив имеет тип REAL для последующей сортировки
!DuArray[!x] = !allValves[!x].Dbref().Spref.Catref.Para[1]
--второй массив - массив Наименований, взятых из Dtxr, каждая ячейка соответствует ячейке первого массива
--и перехватываем ошибку на случай, если не задана ссылка на каталог
!dtxrArray[!x] = !allValves[!x].Dbref().Dtxr
HANDLE ANY
!dtxrArray[!x] = 'нет наименования-проверьте каталог/ссылку Detref'
ENDHANDLE
--третий массив - массив Материалов, взятых из Mtxx, каждая ячейка соответствует ячейке первого (И второго) массива
--и перехватываем ошибку на случай, если не задана ссылка на каталог
!mtxxArray[!x] = !allValves[!x].Dbref().Mtxx
HANDLE ANY
!mtxxArray[!x] = 'нет материала-проверьте каталог/ссылку Matext'
ENDHANDLE
--формирование выходного, несортированного массива
!nonSortedArray[!x] = !DuArray[!x].String() + ';' + !dtxrArray[!x] + ';' + !mtxxArray[!x]
enddo
--вывод несортированного массива
q var !nonSortedArray
--запоминаем массив индексов, как если бы была применена операция сортировки
--пример
--!q[1] = 200 !q[2] = 50 !q[3] = 100 - здесь индексы (indexes) 1=200,2=50,3=100
--операция sortedindices вернет следующее:
--1=2,2=3,3=1 то порядок следования ячеек прошлого массива как если бы была сортировка
!changedOrder = !DuArray.SortedIndices()
--запускаем цикл и формируем новый массив
--ячейки которого будут сформированы путем вытаскивания нужных (по сортированному порядку) ячеек из оригинальных
массивов
do !x from 1 to !changedOrder.Size()
--формирование массива
!sortedArray[!x] = !DuArray[!changedOrder[!x]].String() + ';' + !dtxrArray[!changedOrder[!x]] + ';' + !mtxxArray[!changedOrder[!x]]
enddo
--вывод сортированного массива
q var !sortedArray
(вернуться к содержанию)
Решение:
Базовый синтаксис для коллекции элементов из Drawlist
VAR !itemInDrawlist COLLECT ALL FROM DRAWLIST
Базовый синтаксис для коллекции элементов внутри определенного объема
VAR !itemInVolume COLLECT ALL WITHIN En1 Sn1 Un1 TO En2 Sn2 Un2
где ESU - мировые оси, по которым нужно провести объем (могут быть E или W, N или S, U или D), а n1, n2 -
значения координат по этим осям. При этом если представить себе объем в виде куба, то En1 Sn1 Un1 - это
координата нижнего левого ближнего угла, а En2 Sn2 Un2 - координата верхнего правого угла куба, то есть
диагональ. (См.рисунок внизу)
А вот код, который позволяет провести сравнение двух коллекций и выполнить поставленную задачу:
(вернуться к содержанию)
if (!getItems.Size() EQ 0) then
!!Alert.Message('Элементов типа $!getTypeFind не найдено внутри CE. Остановлено...')
RETURN
endif
--подсвечиваем найденные
do !x from 1 to !getItems.Size()
$!getItems[$!x]
ENHANCE CE COLOUR RED
MARK WITH '$!getTypeFind' CE
enddo
--снимаем маркировку
UNMARK ALL
--запускаем процесс
do !x from 1 to !getItems.Size()
enddo
OWNER
var !badMembers COLLECT ALL BRAN MEM WITH ( BADREF ( SPREF ) ) FOR CE
--открыть файл
if (!getConfirm EQ 'YES') then
SYSCOM '$!repFilePath &'
endif
--открыть на экране
if (!getConfirm EQ 'NO') then
do !x from 1 to !output.Size()
ADD $!output[$!x]
ENHANCE $!output[$!x] COLOUR RED
enddo
---масштабировать
!draw = object drawlist()
!glbDraw = !draw.Globaldrawlist().Members()
if (!glbdraw.size() EQ 0) then
RETURN
endif
!RT = object array()
do !x from 1 to !glbDraw.Size()
!RT[!x] = !glbDraw[!x].String()
enddo
endif
endif
--сообщение
$P ==========================
$P <СИСТЕМА ПОЛЬЗОВАТЕЛЮ>Сообщение: Drawlist сохранен в $!FileName