Тема: Копирование блоков из файла в файл через ActiveX

При помощи функций ActiveX создан указатель на библиотечный файл с несколькими блоками. Этот файл запускается через ActiveX в фоновом режиме. Создается указатель на один из блоков.
Вопрос: каким образом, через какие функции (методы и свойства объектов) можно вставить это блок в активный в данный момент файл.

Re: Копирование блоков из файла в файл через ActiveX

Андрей Г. пишет:

При помощи функций ActiveX создан указатель ...

в какой программной среде? В автолиспе? В VBA? По всей видимости, речь идёт о внешней по отношению к текущему сеансу Акада программе (например, на VB или Delphi). Тогда вам надо реализовать эту внешнюю программу как сервер автоматизации (очевидно, outproc-типа, потому что он внешний, хотя это терминологические тонкости), и реализовать соответствующие "методы и свойства объектов", которые вы надеетесь получить. Если такая внешняя программа уже кем-то создана до вас, то надо смотреть её документацию (описание), или исследовать её TLB или DLL - файлы на предмет "методов и свойств" с помощью VBA-шного Object Browser'a, предварительно подключив эти файлы в перечень объектов с помощью меню Tools->References->Browse...
А вообще-то, имхо, можно всё сделать в акаде, не прибегая к внешней программе, на автолиспе (результат не гарантирован:)) либо на VBA. Только вот фонового режима не получится, да и зачем? Просто чертёж-библиотека будет скрыт активным (текущим) чертежом, в сущности, тот же фоновый режим:).
Напишите точнее, что за задача, что это за ActiveX у вас, уж не лабы ли сдаёте;).

Re: Копирование блоков из файла в файл через ActiveX

Михаил, спасибо за ответ.
Я для решения своей задачи пробую использовать COM технологию. Для решения хотелось бы использовать только расширение AutoLISP реализующее ActiveX. Файл с библиотекой блоков открыт уже и является скрытым (фоновый режим это терминологические тонкости).  Активным является рабочий чертеж, в который нужно вставлять в виде блоков вентиляционное оборудование. Интерфейс сделан на DCL. Уже реализовано открытие библиотечного файла, выбор из него блока (создается VLA-объект), осталось реализовать вставку этого блока в активный чертеж и ... никак.
Вот и весь вопрос.

Re: Копирование блоков из файла в файл через ActiveX

Извините описался
Спасибо, Maxim T

Re: Копирование блоков из файла в файл через ActiveX

> Андрей Г.
Теперь всё понятно. Имхо, в вашем случае совершенно не нужно создавать VLA-объект из выбранного блока, потому что потом этот объект абсолютно ни на что не нужен, как вы и написали в своём первом постинге. Надо вместо этого записать выбранный блок во временный файл при помощи команды _wblock, а затем сразу в активном чертеже вставить этот файл командой _insert, и тут же стереть временный файл. Имхо, это единственно правильный:) способ. Есть ещё вариант: скопировать выбранный блок в буфер обмена и затем вставить его оттуда в активный чертёж, используя соответственно команды _copyclip и _pasteclip, но это, имхо - ламерство и недостойно настоящего автокадчика:))) Если серьёзно, то при втором способе при вставке создаются временные блоки, которые потом надо purge, а кто это будет делать? Хотя есть и плюс - не надо заботиться о месте размещения временного файла. Маленький нюанс: чтобы команда _wblock не выводила диалоговое окно, надо перед её вызовом установить системную переменную FILEDIA в 0, а сразу после вызова - вернуть в 1 (чтобы вернуть диалоговые окна обратно).

Re: Копирование блоков из файла в файл через ActiveX

> Андрей Г.
Попробуй код ниже (то, что в угловых скобках замени на своё):

(setq docs (vla-get-Documents (vlax-get-acad-object))
      fdsr (vla-item docs <FileSourse.dwg>)
)
(vla-CopyObjects
  fdsr
  (vlax-make-variant
    (vlax-safearray-fill
      (vlax-make-safearray vlax-vbObject '(0 . 0))
      (list (vla-item (vla-get-blocks fdsr) <BlockName>))
    )
  )
  (vla-get-Block (vla-get-ActiveLayout (vla-item docs <FileTarget.dwg>)))
)

Это только набросок.
На глючность не проверял.

Re: Копирование блоков из файла в файл через ActiveX

А попробуй такой вариант, у меня работает
нормально. Не совсем по теме, но
кому-нибудь может и пригодится...
__________________________________
;LISP-file;
(vl-load-com)
(defun C:ins_block ( / dcl_id  blk_list)
(setq dcl_id (load_dialog "BIBLIOTHEKA.DCL")
    blk_list (vl-directory-files "C:\\MyLisp" "*dwg" 1))
  (if (and dcl_id (new_dialog "sel_blocks" dcl_id))
    (progn
      (start_list "sel1")
      (mapcar 'add_list blk_list)
      (end_list)
      (action_tile "sel1" "(blk_select $value)")
      (start_dialog)
      (unload_dialog dcl_id)
    )
  )
(setq old_ech (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq adoc (vla-get-activedocument
                      (vlax-get-acad-object))
      mdsp (vla-get-modelspace adoc)
      appd (vla-get-application adoc))
(vla-startundomark adoc)
(setq ip (vlax-3d-point
       (getpoint "\nТочка вставки : ")))
(setq blk
       (vl-catch-all-apply
     (function (lambda ()
             (vla-insertblock
               mdsp ip bname 1. 1. 1. 0)
           ))))
(vla-explode blk);удалить по ситуации
(vla-delete blk);удалить по ситуации
(if (vlax-object-released-p blk)
      (vlax-release-object blk)
      )
(vla-zoomextents appd)
(vla-regen adoc acActiveViewport)
(vla-endundomark adoc)
(setvar "cmdecho" old_ech)
(prompt "\nКопирование выполнено.")
(princ)
)
(defun blk_select (val)
(setq val (nth (atoi val) blk_list)
      bname (strcat "C:\\MyLisp\\" val))
(alert (strcat "Выбран блок: " bname));удалить по ситуации
)
_____________________________________
;DCL-file;
sel_blocks : dialog {               
      label = "Б И Б Л И О Т Е К А   Б Л О К О В" ;   
       : row {               
    : boxed_column {
    label = "&ВЫБОР БЛОКА :";
         : list_box {           
        key = "sel1";           
    value = "";
        }               
    }
    }
   
     ok_cancel ;               
     : row {               
     : paragraph {           
     : text_part {           
     label = "Это всего лишь";       
     }                   
     : text_part {           
     label = "вариант копирования";       
     }
     : text_part {               
     label = "содержимого одного";   
     }
     : text_part {           
     label = "файла в другой";   
         }
         }                       
         }                           
           
     }                   
_____________________________________
Можно также вместо DCL использовать любой
из следущих вариантов:
(setq fname (strcat "C:\\MyLisp\\"
            (getstring "\nИмя файла :  ") ".dwg"))
Самый удобный по интерфейсу (IMHO):
(setq fname (getfiled "ПОИСК ЧЕРТЕЖА" "C:\\MyLisp\\" "dwg" 8))
И самые непродуктивные - сразу прописывать полное имя:
(setq fname (findfile "C:\\MyLisp\\TEST1.dwg")) или:
(setq fname "C:\\MyLisp\\TEST1.dwg")

Re: Копирование блоков из файла в файл через ActiveX

Большое спасибо всем за ответы
Пока воспользовался предложенным ЯR и (с незначительными исправлениями) все получилось так, как хотел.
Позже обязательно опробую другие решения.

Re: Копирование блоков из файла в файл через ActiveX

> Андрей Г.
На VBA такая же задача мною решена в этой ветке: https://www.caduser.ru/forum/topic14721.html

Re: Копирование блоков из файла в файл через ActiveX

люди помогите!! нужно написать программу на лиспе: строка ввода
введенное значение или NIL
Параметры:-координаты начала строки
          -длина строки
          -длина видимой части
          -цвет

Re: Копирование блоков из файла в файл через ActiveX

Через DBX!

;;;* Утилита импорта и вставки блока из другого рисунка *
;;;-----------------------------------------------------
;;;
;;; Позволяет вставить блок из другого рисунка, выбранный
;;; в списке из окна диалога
;;; Файл диалого создается динамически как временный,
;;; после вывполнения программы удаляется
;;; Предусмотрен возврат к исходному состоянию при нажатии
;;; клавиши Esc или кнопки Undo
;;; Тестирована только в версии AutoCAD 2005
;;; Без обработчика ошибок
;;; Все права удалены, чувствуйте себя сбоводными
;;; для любых изменений кода
;;; Сохраните код в виде файла cbo.lsp в директории
;;; на путях файлов поддержки
;;; Возможный макрос для кнопки:
;;;
;;;^C^C^P(progn (terpri)(if (not C:CBO)(load "cbo"))(princ)(C:CBO))
;; начало кода
;; written by Fatty T.O.H (c) 2004
;; all rights removed
;; get ObjectDBX document
;; edited 4/20/06
;; edited 5/28/06 by Jeff M (see commented lines)
;; edited 10/5/06
;; edited 3/19/07
;; edited 3/20/07
(defun odbx-test  (/ dbx_doc)
  ;; edited 5/28/06 by Jeff M
  ;; modified slightly to work with more versions
  (or (vl-load-com))
  (if (< (setq dbxver (atoi (getvar "ACADVER"))) 15)
    (progn
      (alert
    "ObjectDBX method not applicable\nin this AutoCAD version")
      (exit)
      (princ)
      (gc))
    (progn
      (if (= (atoi (getvar "ACADVER")) 15)
    (progn
      (if
        (not
          (vl-registry-read
        "HKEY_CLASSES_ROOT\\ObjectDBX.AxDbDocument\\CLSID"))
         (startapp "regsvr32.exe"
               (strcat "/s \"" (findfile "axdb15.dll") "\"")))
      (setq    dbx_doc    (vla-getinterfaceobject
              (vlax-get-acad-object)
              "ObjectDBX.AxDbDocument")))
    (setq dbx_doc (vla-getinterfaceobject
            (vlax-get-acad-object)
            (strcat    "ObjectDBX.AxDbDocument."
                (itoa (fix dbxver)))))))))
(defun BlockList  (dwg / blst bname)
  (vlax-for a  (vla-get-blocks dwg)
    (setq bname (vla-get-name a))
    (if    (and (equal :vlax-false (vla-get-isxref a))
         (equal :vlax-false (vla-get-islayout a))
         (not (wcmatch bname "_*,*$*,*|*"))
         (not (vl-string-search "*" bname)))
      (setq blst (cons bname blst))))
  (reverse blst))
(defun make-lib-dial  ()
  (setq fname (vl-filename-mktemp "libris.dcl"))
                    ; (setq fname (strcat (getvar
                    ; "dwgprefix")
                    ; "librys.dcl"))
  (setq fn (open fname "w"))
  (write-line "libres : dialog {" fn)
  (write-line
    (strcat "label = " "\"" "COPY BLOCK" "\"" ";")
    fn)
  (write-line ": boxed_column {" fn)
  (write-line
    (strcat "label = " "\"" "Select Block" "\"" ";")
    fn)
  (write-line ": list_box {" fn)
  (write-line (strcat "key = " "\"" "b_list" "\"" ";") fn)
  (write-line "width = 30; height = 20;}" fn)
  (write-line "}" fn)
  (write-line "spacer;" fn)
  (write-line "ok_cancel; " fn)
  (write-line "}" fn)
  (close fn))
                    ; ;
(defun set_list     (name lst)
  (start_list name)
  (mapcar 'add_list lst)
  (end_list))
                    ; ;
(defun run-lib-dial  (blk_lst)
  (setq dcl_ex (load_dialog fname))
  (new_dialog "libres" dcl_ex)
  (set_list "b_list" blk_lst)
  (action_tile
    "b_list"
    (strcat "(progn "
        "(setq b_name (nth (atoi $value) blk_lst)))"))
  (action_tile "accept" "(done_dialog 1)")
  (action_tile "cancel" "(done_dialog 0)")
  (setq knock (start_dialog))
  (unload_dialog dcl_ex)
  (done_dialog)
  (vl-file-delete fname)
  b_name)
;; main programm :
(defun C:CBO  (/ acapp acsp adoc blk_col blk_lst b_name    cert_blk fn
           fname ipt knock odbx x)
  (vl-load-com)
  (or acapp (setq acapp (vlax-get-acad-object)))
  (or adoc (setq adoc (vla-get-activedocument acapp)))
  (or acsp
      (setq acsp (if (= (getvar "CVPORT") 1)
           (vla-get-paperspace adoc)
           (vla-get-modelspace adoc))))
  (vla-startundomark adoc)
  (setq odbx (odbx-test))
  (setq fn (getfiled "Select file to copy block from it" "" "dwg" 16))
  (if (setq fname (findfile fn))
    (progn
      (vla-open odbx fname)
      (setq blk_lst (BlockList odbx))
      (make-lib-dial)
      (setq b_name (run-lib-dial blk_lst))
      (if (= knock 1)
    (progn
      (setq blk_col (vla-get-blocks odbx))
      (if
        (not (vl-catch-all-error-p
           (vl-catch-all-apply
             (function
               (lambda () (vla-item blk_col b_name))))))
         (progn
           (setq cert_blk (vla-item blk_col b_name))
           (not
         (vl-catch-all-error-p
           (vl-catch-all-apply
             (function
               (lambda ()
             (vla-copyobjects
               odbx
               (vlax-safearray-fill
                 (vlax-make-safearray
                   vlax-vbobject
                   '(0 . 0))
                 (list (vla-item
                     (vla-get-blocks odbx)
                     b_name)))
               (vla-get-blocks adoc))))))))
         (princ "\Block Not Found")))))
    (princ "\File Not Found"))
  ;; check if desired block already in the current database:
  (if (not
    (vl-catch-all-error-p
      (vl-catch-all-apply
        (function
          (lambda () (vla-item (vla-get-blocks adoc) b_name))))))
    ;; insert block
    (progn (setq ipt (getpoint "\nSpecify insertion point: "))
       (vlax-invoke acsp 'InsertBlock ipt b_name 1 1 1 0))
    (alert "Problem with block copying"))
  (vlax-release-object odbx)
  (setq odbx nil)
  (mapcar (function
        (lambda (x)
          (vl-catch-all-apply
        (function (lambda () (vlax-release-object x))))))
      (list cert_blk blk_col))
  (vla-endundomark adoc)
  (gc)
  (gc)
  (princ))
                    ; ;
(princ
  "\n\t\t***\tType CBO to import block from other file ...\t***")
(princ)
;; окончание кода