Библиотека материалов: как получать / создавать данные?

Автор Тема: Библиотека материалов: как получать / создавать данные?  (Прочитано 5459 раз)

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

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Здравствуйте, коллеги!
Прошу, подскажите, где можно почитать о программном управлении данными из библиотеки материалов?

Заранее благодарю.

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Евгений, привет. На сколько мне известно, такого API нет. По крайней мере года два назад не было, и вроде ничего не поменялось в этом направлении. Если пояснишь по подробней что имеется ввиду под "управлением данными", смогу точно сказать.

Оффлайн catexis

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Доброго времени суток, коллеги! Вопрос был от меня по факту. Поясню ситуацию: необходимо проработать библиотеку материалов в очень большом объёме - задать правильные параметры идентификации, графики и представления. Общиё объём данных - 500+ позиций. Выполнять данный процесс вручную крайне нудно и тяжело, поэтому и возник вопрос об автоматизации этого процесса.
Так же хотел бы пояснить, что до этого с этим делом справлялся с помощью языка AutoIT - писал кликер, который у нужные окна подставляет нужную информацию и производит нужные клики в нужных местах окна. И в целом оно работает, но это не совсем корректный путь, да и способ доступа к библиотеке получается не унифицировать.
Задача наполнения библиотеки ещё осложняется тем, что в перспективе данную базу придётся модифицировать добавлением физических и термальных представлений.
Ниже приведу код, сразу оговорюсь, что программировать стал не так давно, поэтому понимаю, что код можно улучшить и упростить  ::)
; Кликер для добавления нужных материалов в библиотеку материалов Revit
#include <Array.au3>
#include <Excel.au3>
#include <MsgBoxConstants.au3>
#include <Date.au3>
#include <File.au3>

HotKeySet("{ESC}", "Terminate")
AutoItSetOption("MouseCoordMode",0)

Global $nSchot
$nSchot = 0 ; Глобальный счётчик

;~ $hWindow = _OpenMaterialManager()

;~ $sExcelFile = "D:\kad\documents\Задания\clicker_revit_materials\gost_14332.xlsx"

; Для автоматического подсчёта количества всей проделанной работы
$aExcelFiles = _FileListToArray('D:\kad\documents\Задания\clicker_revit_pipes\xlsx','*',$FLTA_FILES,True)
For $ni5 = 1 to $aExcelFiles[0] Step 1
   $sExcel = _OpenExcel($aExcelFiles[$ni5])  ; Открыли Excel и получили ссылку на таблицу
   $nNumberStroks = _KolStrokVExcel($sExcel) ; Получили количество строк в файле
Next


; Для диспетчера материалов
;~ $nMMWindow = _MaterialWinMove() ; Получили переименованное окно Диспетчера материалов
;~ _DeleteOldMaterials($nMMWindow)

;~ For $ni2 = 1 to $nNumberStroks Step 1 ; Удаляем старые
;~    _DeleteWrongMaterials(); материалы
;~ Next                      ; из библиотеки

;~ $sExcel = _OpenExcel($sExcelFile) ; Открыли Excel и получили ссылку на таблицу
;~ $s = 1
;~ $sMatWindow = _AddNewMaterial($s,$sExcel)
;~ _AddNewMaterialToLib($sMatWindow)
;~ _DeleteNewMat()

;~ $sExcel = _OpenExcel($sExcelFile) ; Открыли Excel и получили ссылку на таблицу
;~ For $s = 1 to $nNumberStroks Step 1
;~    $sMatWindow = _AddNewMaterial($s,$sExcel) ; Добавляет новый материал в ПРОЕКТ
;~    _AddNewMaterialToLib($sMatWindow) ; Добавляет новый материал в БИБЛИОТЕКУ
;~    _DeleteNewMat()
;~ Next
;~ ConsoleWrite(@ScriptLineNumber & ' ' & $nSchot & @CRLF)

; Возвращаемся в редактор кода
$hWnd1 = WinWait('[CLASS:SciTEWindow]','Source',2)
$hWnd2 = WinActivate($hWnd1)

Func _OpenExcel($sExcelFile); Открываем наш excel файл
Local $oExcel = _Excel_Open()
If @error Then Exit MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_RangeRead Example", "Error creating the Excel application object." & @CRLF & "@error = " & @error & ", @extended = " & @extended)
Local $oWorkbook = _Excel_BookOpen($oExcel, $sExcelFile)
If @error Then
    MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_RangeRead Example", "Error opening workbook '" & $sExcelFile & @CRLF & "@error = " & @error & ", @extended = " & @extended)
    _Excel_Close($oExcel)
    Exit
 EndIf
 Return $oWorkbook
EndFunc

Func _OpenMaterialManager()
   Local $hWnd1, $hWnd2, $hWnd3, $hWnd4
   $hWnd1 = WinWait('Диспетчер материалов - Аналитическая модель поверхности перекрытия','',2) ; Нашли окно Диспетчер материалов
   If $hWnd1 = 0 Then ; Если окно закрыто
  $hWnd2 = WinWait('Autodesk Revit 2015 - [План этажа: Уровень 1 - Проект1]','', 2) ; Нашли окно Revit
  $hWnd3 = WinActivate($hWnd2) ; Нашли окно Revit
  WinSetState ($hWnd3, '', @SW_MAXIMIZE ) ; Развернули на весь экран
  MouseClick("main",895,35,1,10) ; Кликнули Управление
  MouseClick("main",103,65,1,10) ; Кликнули Материалы
   EndIf
   $hWnd1 = WinWait('Диспетчер материалов - Аналитическая модель поверхности перекрытия','',2) ; Нашли окно Диспетчер материалов
   If $hWnd1 = 0 Then
  Exit 0
   EndIf
   $hWnd4 = WinActivate($hWnd1) ; Активировали окно Диспетчер материалов
   ControlClick($hWnd4, '', '[CLASS:QWidget; INSTANCE:1]', "main",1,66,102)
   Return $hWnd4
EndFunc

Func _DeleteOldMaterials($hWindow)
   $hWnd1 = WinActivate($hWindow) ; Активировали окно Диспетчер материалов
   ControlClick($hWnd1, '', '[CLASS:QWidget; INSTANCE:1]', "main",1,85,140) ; Щёлкнули по первому материалу
   For $ni1 = 1 to 17 Step 1
  Send("{DEL}")
   Next
EndFunc

Func _AddNewMaterial($s,$sExcel)
   Local $hWnd1, $hWnd2, $hWnd3, $hWnd4
   BlockInput(1)
   $hWnd1 = WinWait('Диспетчер материалов','WinWidget',2) ; Нашли окно Диспетчер материалов
   $hWnd2 = WinActivate($hWnd1) ; Активировали окно Диспетчер материалов

   ; Считываем информацию из таблицы excel
   $sReadColumnA = _Excel_RangeRead($sExcel, Default, "A" & $s) ; ГОСТ
   $sReadColumnB = _Excel_RangeRead($sExcel, Default, "B" & $s) ; Наименование ГОСТ
   $sReadColumnC = _Excel_RangeRead($sExcel, Default, "C" & $s) ; Тип материала
   $sReadColumnD = _Excel_RangeRead($sExcel, Default, "D" & $s) ; Суффикс "_GAL"
   $sReadColumnE = _Excel_RangeRead($sExcel, Default, "E" & $s) ; Комментарий
   $sReadColumnJ = _Excel_RangeRead($sExcel, Default, "J" & $s) ; Марка

   ; Копируем исходный материал
   ControlClick($hWnd2, '', '[CLASS:QWidget; INSTANCE:1]', "right",1,75,110) ; ПКМ вызвали меню
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{ENTER}")
   Sleep(25)

   ; Заполняем наименование
   $hWnd2 = WinActivate($hWnd1) ; Активировали окно Диспетчер материалов
   For $ni1 = 1 To 16 Step 1    ; Добираемся табами до поля ввода
  Send("{TAB}")
  Sleep(20)
   Next                         ; Добрались
   Send("{DEL}")
   $sToSend = $sReadColumnJ & "_" & $sReadColumnA & $sReadColumnD
   Send($sToSend)
   Sleep(50)
   Send("{TAB}") ; Перешли на Описание

   ; Заполняем описание
   Sleep(25)
   Send("^a")
   Sleep(25)
   Send("{DEL}")
   $sToSend = $sReadColumnB
   Send($sToSend)
   Sleep(50)
   Send("{TAB}") ; Перешли на Класс
   Sleep(25)

   ; Заполняем класс
   Send("^a")
   Sleep(25)
   Send("{DEL}")
   $sToSend = $sReadColumnC
   Send($sToSend)
   Sleep(50)
   Send("{TAB}")
   Sleep(25)
   Send("{TAB}") ; Перешли на комментарий
   Sleep(25)

   ; Заполняем комментарий
   $sToSend = $sReadColumnE
   Send($sToSend)
   Sleep(25)
   Send("{ENTER}")
   $sToSend = _NowCalc()
   Send($sToSend)
   Sleep(50)
   Send("{TAB}") ; Перешли на Ключевые слова
   Sleep(25)

   ; Заполняем ключевые слова
   $sToSend = $sReadColumnJ & ', ' & $sReadColumnA & ', ' & $sReadColumnC
   Send($sToSend)
   Sleep(50)
   Send("{TAB}")
   Sleep(25)
   Send("{TAB}")
   Sleep(25)
   Send("{TAB}")
   Sleep(25)
   Send("{TAB}")
   Sleep(25)
   Send("{TAB}")
   Sleep(25)
   Send("{TAB}")
   Sleep(25)
   Send("{TAB}")
   Sleep(25)
   Send("{TAB}") ; Перешли на маркировку
   Sleep(25)

   ; Заполним маркировку
   $sToSend = $sReadColumnJ
   ConsoleWrite(@ScriptLineNumber & ' ' & $sToSend & @CRLF)
   Send($sToSend)
   ControlClick($hWnd2, '', '[CLASS:QWidget; INSTANCE:1]', "main",1,440,230) ; Сбросили выделение

   BlockInput(0)
   $nSchot = $nSchot + 1
   Return $hWnd2
EndFunc

Func _AddNewMaterialToLib($sMatWindow)
   Local $hWnd1, $hWnd2, $hWnd3, $hWnd4
   $hWnd1 = WinWait($sMatWindow,'',2) ; Нашли окно Диспетчер материалов
   $hWnd2 = WinActivate($hWnd1) ; Активировали окно Диспетчер материалов
   ControlClick($hWnd2, '', '[CLASS:QWidget; INSTANCE:1]', "right",1,147,150)
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{RIGHT}")
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{RIGHT}") ; Перешли на последнее вложение
   Sleep(25)
   Send("{DOWN}") ; 1
   Sleep(25)
   Send("{DOWN}") ; 2
   Sleep(25)
   Send("{DOWN}") ; 3
   Sleep(25)
   Send("{DOWN}") ; 4
   Sleep(25)
;~    Send("{DOWN}") ; 5
;~    Sleep(25)
;~    Send("{DOWN}") ; 6
;~    Sleep(25)
;~    Send("{DOWN}") ; 7
;~    Sleep(25)
;~    Send("{DOWN}") ; 8
;~    Sleep(25)
;~    Send("{DOWN}") ; 9
;~    Sleep(25)
;~    Send("{DOWN}") ; 10
;~    Sleep(25)
;~    Send("{DOWN}") ; 11
;~    Sleep(25)
   Send("{ENTER}")
EndFunc

Func _DeleteNewMat()
   $hWnd1 = WinWait('Диспетчер материалов','WinWidget',2) ; Нашли окно Диспетчер материалов
   $hWnd2 = WinActivate($hWnd1) ; Активировали окно Диспетчер материалов
   ControlClick($hWnd2, '', '[CLASS:QWidget; INSTANCE:1]', "right",1,70,150)
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{DOWN}")
   Sleep(25)
   Send("{ENTER}")
EndFunc

Func _MaterialWinMove() ; Двигаем наше окно
   $hWnd1 = WinWait('Диспетчер материалов','WinWidget',2) ; Нашли окно Диспетчер материалов
   $hWnd2 = WinActivate($hWnd1) ; Активировали окно Диспетчер материалов
   $hWnd3 = WinMove($hWnd1,'',0,0,(1920/2),(1040/2)) ; Активировали окно Диспетчер материалов
   Sleep(500)
;~    $hWnd4 = WinSetTitle($hWnd2,'','Manager') ; Активировали окно Диспетчер материалов
   Return $hWnd2
EndFunc

Func Terminate()
   Exit 0
EndFunc

Func _DeleteWrongMaterials()
   $hWnd1 = WinWait('Диспетчер материалов','WinWidget',2) ; Нашли окно Диспетчер материалов
   $hWnd2 = WinActivate($hWnd1) ; Активировали окно Диспетчер материалов
   ControlClick($hWnd2, '', '[CLASS:QWidget; INSTANCE:1]', "right",1,300,351)
   Sleep(100)
   Send("{DOWN}")
   Sleep(100)
   Send("{DOWN}")
   Sleep(100)
   Send("{ENTER}")
   Sleep(100)
EndFunc

Func _KolStrokVExcel($sExcel) ; Автоматический подсчёт строк в екселе
   Local $s, $sReadColumnA
   $s = 1
   $sReadColumnA = 1
   While $sReadColumnA <> ''
  $sReadColumnA = _Excel_RangeRead($sExcel, Default, "A" & $s)
  $s = $s + 1
   WEnd
   $s = $s - 2
;~    ConsoleWrite(@ScriptLineNumber & ' ' & $s & @CRLF)
   ConsoleWrite($s & @CRLF)
   Return $s
EndFunc

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

' Build: 20140322_1515(x64)
' Branch: RELEASE_2015_RTM
Dim Jrn
Set Jrn = CrsJournalScript

' Открываем новый, пустой проект
Jrn.Command "StartupPage" , "Create a new project , ID_FILE_NEW_CHOOSE_TEMPLATE"
Jrn.PushButton "Modal , New Project , Dialog_Revit_NewProject" , "OK, IDOK"
Jrn.Directive "DocSymbol" , "[Project1]"
Jrn.Data "TaskDialogResult" , "Which system of measurement do you want to use in your project?", "Metric", "1002"
Jrn.Data "Transaction Successful" , "Create Type Previews"

' Жмакаем на панельку с материалами
Jrn.RibbonEvent "TabActivated:Manage"

' Открываем материалы
Jrn.Command "Internal" , "Modify materials , ID_SETTINGS_MATERIALS"

' Добавляем новый материал

Jrn.WidgetEvent "MaterialSelected" , "Modal , Material Browser , Dialog_Revit_MaterialBrowser"
Jrn.Data        "AssetIdName" , "PhysMat", "Default"

Jrn.WidgetEvent "ShowMaterialEditor" , "Modal , Material Browser - Default , Dialog_Revit_MaterialBrowser"
Jrn.Data        "ShowMaterialEditor" , 1, "Default", 1
' Выбор того чего будем дублировать
Jrn.WidgetEvent "SelectAspect" , "Modal , Material Browser - Default , Dialog_Revit_MaterialBrowser"
Jrn.Data        "AssetAspect" , "Graphics"
' Процедура дублирования
Jrn.WidgetEvent "DuplicateAsset" , "Modal , Material Browser - Default , Dialog_Revit_MaterialBrowser"
Jrn.Data        "AssetInfo" , "", "", "Default" , ""
' Выбор дублированного материала
Jrn.WidgetEvent "MaterialSelected" , "Modal , Material Browser - Default , Dialog_Revit_MaterialBrowser"
Jrn.Data        "AssetIdName" , "PhysMat", "Default(1)"
' Переименование дублированного материала
Jrn.WidgetEvent "RenameAsset" , "Modal , Material Browser - Default(1) , Dialog_Revit_MaterialBrowser"
Jrn.Data        "RenameAsset" , "Default(1)", "New material over GOST"

' Удаление выделенного материала

'Jrn.PushButton  "Modal , Material Browser - Default(1) , Dialog_Revit_MaterialBrowser" , "OK, IDOK"
'Jrn.Data        "Transaction Successful" , "Materials"

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Андрей, добрый день.
Подход с нажатием клавиш - это конечно решение, но только уж самое крайнее.

Работать с такой информацией можно, но этот момент не очень то документирован. Там все хранится в виде ключ-значение. А вот какой ключ и какое значение - надо искать опытным путем.
Рекомендую для начала ознакомиться с вот этой статьей. В ней описываются базовые знания о том, как хранится информация.

Оффлайн catexis

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Виктор, благодарю за информацию! В общем и целом всё же решил биться с этой штукой через кликер (ибо сроки по наполнению крайне сжатые, а опыта в ООП крайне мало). Показывал уже свои наработки Евгению - он оценил  :) Поэтому в дальнейшем, если будет интересно - выложу результат работы.