| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > как создать список блоков, содержащихся в файле

как создать список блоков, содержащихся в файле

Ответ
Поиск в этой теме
Непрочитано 15.08.2005, 17:03 #1
как создать список блоков, содержащихся в файле
Александер
 
Регистрация: 15.06.2005
Сообщений: 184

как можно из файла *.dwg считать инфу о содержащихся в нем блоках, т.е. надо чтобы программка создала список из названий блоков, содержащихся в указанном файле. вобщем должен получиться такой список:
"блок1" "блок2" "блок3" "блок4" и т.д. ....
файл при этом не открываем.
Просмотров: 6423
 
Непрочитано 15.08.2005, 19:50
#2
{Smirnoff}

Инженер по системам безопасности
 
Регистрация: 23.11.2003
Рига
Сообщений: 1,099


Цитата:
файл при этом не открываем.
Ну что значит не открываем? Не получится так, во всяком случае средствами LISP и VBA.

Скорее так:
1) Открываем файл, но не делаем его активным.
2)Считываем список блоков.
3)Закрываем файл.

Вот как то писал програмульку для множественного масшабирования файлов из дюймов в миллиметры. Если поменять несколько строчек внутри то она точно также сможет считывать список блоков в каждом файле, писать это в текстовый файл или к примеру в Excel. Программа использует библиотеку DosLib, для того чтобы обрабатывать директории и субдиректории:
Код:
[Выделить все]
(defun c:mscale(/ pathList scFactor docColl curDoc plotObj errList errCount sucCount
		allSet layCol layerState selSets newSet)
 
  (defun asmi-doslib-load (/)
    (cond
      ((=(substr(getvar "ACADVER")1 2) "15")
       (progn
  (if(not(member "doslib15.arx" (arx)))
      (arxload "doslib15.arx" "File doslib15.arx.arx not found! ")
    ); end if
  );end progn
       )
      ((=(substr(getvar "ACADVER")1 2) "16")
       (progn
  (if(not(member "doslib16.arx" (arx)))
       (arxload "doslib16.arx" "File doslib16.arx.arx not found! ")
    ); end if
  );end progn
       )
       ); end cond
    (if(or
       (member "doslib15.arx" (arx))
       (member "doslib16.arx" (arx))
       ); end or
      T
      ); end if
  ); end of asmi-doslib-load


 

  (defun asmi-all-folder-dwgs (/ rootDir dirList newFiles fileList)
  (if
  (setq
    rootDir(dos_getdir "Folder to select DWG's " "C:\\" "Select folder select DWG's")
   ); end setq
  (progn
   (setq dirList(dos_dirtree rootDir)
    fileList '()
   ); end setq
  (foreach dir dirList
    (if
      (setq newFiles(dos_dir(strcat dir "*.dwg")0))
      (progn
   (setq newFiles(mapcar '(lambda (x)(strcat dir x))newFiles)
              fileList(append fileList newFiles)
   ); end setq
       ); end progn
      ); end if
    ); end foreach
  fileList
   ); end progn
  ); end if
); end of asmi-all-folder-dwgs


 
  (if(asmi-doslib-load)
    (progn
      (if
       (setq pathList(asmi-all-folder-dwgs))
        (progn
          (while(not scFactor)
	    (setq scFactor(getreal "\*** Specify scale factor: "))
		  ); end while
          (setq docColl(vla-get-Documents(vlax-get-acad-object))
           errList '()
      errCount 0
      sucCount 0
          ); end setq
  (foreach path pathList
   (if
     (not
        (vl-catch-all-error-p
         (setq curDoc
          (vl-catch-all-apply 'vla-open(list docColl path)))))
       (progn
	 (setq selSets(vla-get-SelectionSets curDoc)
	       newSet(vla-Add selSets "ScaleSet")
	       ); end setq
	 (vla-Select newSet acSelectionSetAll)
	 
	 (if(/= 0(vla-get-Count newSet))
	   (progn
	     
	     (setq layCol(vla-get-Layers curDoc))
	     
     (vlax-for l layCol 
       (setq layerState 
            (append layerState 
             (list 
              (list 
                l 
               (vla-get-Lock l))))) 
               (vla-put-lock l :vlax-false) 
       ); end vlax-for


     (vlax-for obj newSet
          (if
            (not
            (vl-catch-all-error-p
                (vl-catch-all-apply 'vla-ScaleEntity
		  (list obj (vlax-3D-point '(0.0 0.0 0.0)) scFactor))))
                    nil
	    ); end if
       ); end vlax-for

	     (vla-regen curDoc acAllViewports)

         (foreach l layerState 
      (vla-put-Lock (car l)(cadr l)) 
   ); end foreach


(vlax-release-object newSet)(setq newSet nil)
      (vla-save curDoc)
      (vla-close curDoc :vlax-false)
(vlax-release-object curDoc)(setq curDoc nil)
(setq layerState nil)	     
      (setq sucCount(1+ sucCount))
     ); end progn
     (progn
     (setq errList(append errList(list path)))
     (setq errCount(1+ errCount))
     ); end progn
   ); end if
	 ); end progn
     ); end if
      ); end foreach
    ); end progn
       (princ "\n!!! *.DWG FILES NOT FOUND IN SELECTED DIRECTORY AND SUBDIRECTORIES !!! ")
   ); end if
      
  ); end progn
 ); end if
      
  (if(/= 0 errCount)
    (progn
      (princ "\n!!! ISN'T OPENED FILES !!!")
      (princ "\n------------------------------------------------")
      (foreach file errList
   (princ(strcat "\n" file))
   ); end foreach
      (princ "\n------------------------------------------------")
      (princ(strcat "\n!!! TOTAL ISN'T SCALED FILES: " (itoa errCount) " !!! \n"))
       ); end progn
      ); end if
    (if(/= 0 sucCount)
    (princ(strcat "\n*** " (itoa sucCount) " FILES SCALED *** "))
    (princ "\n*** NO FILES SCALED! ***")
      ); end if
    (textscr)
(princ)
); end of c:mscale

(vl-load-com)
{Smirnoff} вне форума  
 
Непрочитано 15.08.2005, 19:52
#3
{Smirnoff}

Инженер по системам безопасности
 
Регистрация: 23.11.2003
Рига
Сообщений: 1,099


Хотя наерное через VBA, возможно обратится к AutoCAD к примеру из Excel и открыв его в бекграунде открывать файлы и считывать инфу туда. Но я не пробывал
{Smirnoff} вне форума  
 
Непрочитано 15.08.2005, 20:12
#4
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,407
Отправить сообщение для Александр Ривилис с помощью Skype™


Можно на ObjectARX без загрузки чертежа в редактор AutoCAD:
Код:
[Выделить все]
  int get_list_of_blocknames(void)
  {
    resbuf *pArgs    = acedGetArgs ();  acedRetNil();
    if (pArgs && pArgs->restype == RTSTR) {
      char         *dwgname = pArgs->resval.rstring;
      AcDbDatabase *pDwg    = new AcDbDatabase(Adesk::kFalse);
      if (Acad::eOk == pDwg->readDwgFile(dwgname)) {
        resbuf *pRbFirst = acutBuildList(RTLB,0), 
               *pRb      = pRbFirst;
        AcDbBlockTable *pTbl = NULL;
        pDwg->getBlockTable(pTbl, AcDb::kForRead);
        AcDbBlockTableIterator *pIterator = NULL;
        if (Acad::eOk == pTbl->newIterator(pIterator) && pIterator) {
          AcDbBlockTableRecord *pRcd = NULL;
          for(; !pIterator->done(); pIterator->step()) {
            if (Acad::eOk == pIterator->getRecord(pRcd, AcDb::kForRead) && pRcd) {
              char *pName = NULL;
              if (Acad::eOk == pRcd->getName(pName) && pName) {
                while (pRb && pRb->rbnext) pRb = pRb->rbnext;
                pRb->rbnext = acutBuildList(RTSTR,pName,0);
              }
              pRcd->close();
            }
          }
          delete pIterator;
        }
        pTbl->close();
        while (pRb && pRb->rbnext) pRb = pRb->rbnext;
        pRb->rbnext = acutBuildList(RTLE,0);
        acedRetList(pRbFirst); 
        acutRelRb(pRbFirst);
      }
      delete pDwg;
    }
    return (RSRSLT) ;
  }
}
Пример вызова этой функции из LISP:
Код:
[Выделить все]
(get_list_of_blocknames "C:\\Projects\\Sample.dwg")
Сам сабой, что этой функции недостаточно... Нужно создать проект в MS VS .NET при помощи ObjectARX Wizard, поместить туда эту функцию и скомпилировать все это в arx-файл.
Александр Ривилис вне форума  
 
Непрочитано 15.08.2005, 22:27 Re: как создать список блоков, содержащихся в файле
#5
fixo

Lisp/VBA/VB.NET Hobbyist
 
Регистрация: 24.03.2005
Славен Град Петров
Сообщений: 367


Цитата:
Сообщение от Александер
как можно из файла *.dwg считать инфу о содержащихся в нем блоках, т.е. надо чтобы программка создала список из названий блоков, содержащихся в указанном файле. вобщем должен получиться такой список:
"блок1" "блок2" "блок3" "блок4" и т.д. ....
файл при этом не открываем.
Вот образец, ядро можно использовать при подобных действиях с посторонними файлами, в том числе легко для массовых операций
и чтения и редактирования и т.д.

~'O'~
Код:
[Выделить все]
(defun other_blocks (/		acapp	   adoc	      block_list
		     fn		fname	   mdmod      
		     other_doc	
		    )
  (vl-load-com)
  (or acapp (setq acapp (vlax-get-acad-object)))
  (or adoc (setq adoc (vla-get-activedocument acapp)))
  (vla-endundomark adoc)
  (vla-startundomark adoc)
  (setq mdmod (vla-getvariable adoc "SDI"))
  (vla-setvariable
    adoc
    "SDI"
    (vlax-make-variant 0 vlax-vbinteger)
  )
  ;; following grabbed from LUCAS:

 ;;*** (if (> (atoi (getvar "AcadVer")) 15)
    (setq other_doc (vla-getinterfaceobject
		      acapp
		      "ObjectDBX.AxDbDocument.16"
		    )
    )
    (progn
      (if (not (vl-registry-read
		 "HKEY_CLASSES_ROOT\\ObjectDBX.AxDbDocument\\CLSID"
	       )
	  )
	(startapp "regsvr32.exe"
		  (strcat "/s \"" (findfile "axdb15.dll") "\"")
	)
      )
      (setq other_doc (vla-getinterfaceobject
			acapp
			"ObjectDBX.AxDbDocument"
		      )
      )
    )
  )
  
 ;;***
  (setq
    fn (getfiled "Выбрать файл для чтения блоков"
		 ""
		 "dwg"
		 16
       )
  )

  (if
    (setq fname (findfile fn))
     (progn
       (vla-open other_doc fname)
       (vlax-for a (vla-get-blocks other_doc)
	 (if (and (not (eq (vla-get-isxref a) :vlax-true))
	   (not (eq (vla-get-islayout a) :vlax-true)))
	 (setq block_list (cons (vla-get-name a) block_list))
       )
	 )
       (vlax-release-object other_doc)
       (setq other_doc nil)
     )
     (princ "\File Not Found")
  )
  (vla-setvariable adoc "SDI" mdmod)
  (vla-endundomark adoc)
 (acad_strlsort block_list)
)
;CaLL:(other_blocks)
fixo вне форума  
 
Непрочитано 15.08.2005, 23:27
#6
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,352
<phrase 1=


2Александер
Если под "неоткрывая" имеется ввиду на компе без установленного автокада то http://opendwg.org, замена DWG на DXF всё сильно упростит.
zamtmn вне форума  
 
Непрочитано 16.08.2005, 08:28
#7
Лентяй

Project Engineer
 
Регистрация: 05.01.2005
Лос Анджелес
Сообщений: 1,392


Fatty, прогнал вашу порграммку - понравилось. Одно "Но". функция other_blocks ывдает ошибку. Когда прогнал построчно, то оказалось, что строка
Код:
[Выделить все]
(setq other_doc (vla-getinterfaceobject acapp "ObjectDBX.AxDbDocument.16")
выдает некий осмысленнымый результат, а вот
Код:
[Выделить все]
(setq other_doc (vla-getinterfaceobject acapp "ObjectDBX.AxDbDocument" ))
генерирует ту самую ошибку. которую возвпращает функция. Нет ли здесь какого-нить глюка-бага?
Лентяй вне форума  
 
Непрочитано 16.08.2005, 08:37
#8
Лентяй

Project Engineer
 
Регистрация: 05.01.2005
Лос Анджелес
Сообщений: 1,392


Александер,
Вам нужен просто список ВСЕХ блоков, входящих в файл, или результат контекстного поиска: например, список блоков, в названии (не имени!) или описании (комментарии) которых содержится ключевое слово? Я использую эту программу для поиска типовых деталей, созданных в виде блоков, составляющих мастер-файл.
Лентяй вне форума  
 
Непрочитано 16.08.2005, 09:27
#9
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,381


Цитата:
Сообщение от Лентяй
Fatty, прогнал вашу порграммку - понравилось. Одно "Но". функция other_blocks ывдает ошибку. Когда прогнал построчно, то оказалось, что строка
Код:
[Выделить все]
(setq other_doc (vla-getinterfaceobject acapp "ObjectDBX.AxDbDocument.16")
выдает некий осмысленнымый результат, а вот
Код:
[Выделить все]
(setq other_doc (vla-getinterfaceobject acapp "ObjectDBX.AxDbDocument" ))
генерирует ту самую ошибку. которую возвпращает функция. Нет ли здесь какого-нить глюка-бага?
Похоже, что та функция на основе "ObjectDBX Drawing Scan Example for Visual LISP Developers Bible book" от David Stein.

Это хороший пример использование ObjectDBX, но надо тщательнЕе. Если есть несколько Автокадов и они запускаются попеременно, то всегда будет конфликты имен - ObjectDBX.AxDbDocument, ObjectDBX.AxDbDocument.16, ObjectDBX.AxDbDocument.15 и т.д.

Также надо разбираться, с axdb15.dll (или axdb16.dll) в зависимости от версий.

Правильную идею, заложенную в other_blocks еще надо обрамлять кучей проверок, по максимуму уходя от строковых констант.
ShaggyDoc вне форума  
 
Непрочитано 29.08.2005, 01:51
#10
Лентяй

Project Engineer
 
Регистрация: 05.01.2005
Лос Анджелес
Сообщений: 1,392


Уважаемые гуры, гурии и прочие мастера и просто магистры!
Для начала цитата из себя, либимого(http://dwg.ru/forum/posting.php?mode=reply&t=4457)
Цитата:
Добавлено: 15 Авг 2005 21:37 Заголовок сообщения: Александер,
Вам нужен просто список ВСЕХ блоков, входящих в файл, или результат контекстного поиска: например, список блоков, в названии (не имени!) или описании (комментарии) которых содержится ключевое слово? Я использую эту программу для поиска типовых деталей, созданных в виде блоков, составляющих мастер-файл.
Так вот. эта пргорамма призводит котекстный поиск в ОТКРЫТОМ файле, который открывается обычнвм способом.
Код:
[Выделить все]
(setq	dwg_n (getfiled "Select Detail File" "C:\\IES\\Design Center\\" "dwg" 4))
  (setq dwg (vla-open (vla-get-documents (vlax-get-acad-object)) dwg_n)
	bks (vla-get-Blocks dwg));setq
Далее формируется запрос на конектстный поиск String
Код:
[Выделить все]
 (setq string (strcat "*" (strcase (getstring T "\nEnter Search Partern: ")) "*"));setq
И производится собственно поиск.
Код:
[Выделить все]
(vlax-for dt bks (b_name dt)
     (setq dls (cons dtnt dls)));vlax-for
dtnt - название детали, извлекаемое подпрограммой B_NAME из блока названия детали входящего в состав блока самой детали.
Код:
[Выделить все]
(defun b_name (dt / dtnt)
 (vlax-for blk dt
  (if (= (vla-get-ObjectName blk) "AcDbBlockReference")
    (cond ((or (= (vla-get-name blk) "SPN013")(= (vla-get-name blk) "DT-1"))
	   (foreach at (vlax-safearray->list (vlax-variant-value (vla-getattributes blk)))
	     (if (wcmatch (vla-get-TextString at) string)
	       (setq dtnt (strcat dtn ": " (vla-get-TextString at)))
	  )));single line
	  ((or (= (vla-get-name blk) "SPN014")(= (vla-get-name blk) "DT-2"))
	   (foreach at (vlax-safearray->list (vlax-variant-value (vla-getattributes blk)))
	     (cond ((= (vla-get-TagString at) "D_N1")(setq tl1 (vla-get-TextString at)))
		   ((= (vla-get-TagString at) "D_N2")(setq tl2 (vla-get-TextString at))));cond
	     (if (or (wcmatch tl1 string) (wcmatch tl2 string))
	       		(setq dtnt (strcat dtn ": " tl1 " " tl2))
	   )));doublе line
     );cond
    );if
  );vlax-for
);b_name
SPN013, DT-1, SPN014, DT-2 - имена блоков названий деталей, состояших из соответсвенно одно- и двустрочных имен.
Теперь собственно проблема. Пограмма работаела прекрасно с ACAD-2000 и 2002. Список DLS содержал только отысканные имена независимо от числа просмотренных блоков. При переходе на ACAD-2005 с ToolPAK-9 и прочими прибамбасами открытие файла стало занимать намного больше времени, и стал использовать НЕЯВНОЕ открытие файла, как предложил Fatty:
Код:
[Выделить все]
(слегка изменено)
(setq acapp (vlax-get-acad-object)
         adoc (vla-get-ActiveDocument acapp)
         n_doc (vla-getinterfaceobject acapp "ObjectDBX.AxDbDocument.16"));setq
  (vla-endundomark adoc)
  (vla-startundomark adoc)
  (vla-open n_doc (findfile (getfiled "Select Detail File" "C:\\IES\\Design Center\\" "dwg" 4)))
Далее - как обычно
Код:
[Выделить все]
(setq string (strcat "*" (strcase (getstring T "\nEnter Search Partern: ")) "*")
         bks (vla-get-Blocks n_doc));setq
(vlax-for dt bks (b_name dt)
     (setq dls (cons dtnt dls)));vlax-for
Так вот, тепреь список DLS содержит тоже спсое отысканных имен, только общее число элементов этого списка равно числу прсмотренных блоков, т.е. при просмотре блока, неудовлетворяющего условиям поиска, в список DLS вносится либо nil, либо последнее отысканное имя. Это особенно эффектно, когда отыскивается пара имен из 50-ти. Кто может объяснить сей печальный феномен?
Да, очистку списка от повторных вхождений не предлагать - сообразил сам. Но хотелось бы излечить самму программу от создания дублей.
Лентяй вне форума  
 
Непрочитано 31.10.2007, 15:50
#11
maximas

проектирование. автоматика
 
Регистрация: 18.10.2007
Литва
Сообщений: 104


select all > attext ecли exel установлен
maximas вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > как создать список блоков, содержащихся в файле

Размещение рекламы