Меню

Ошибка неверный тип аргумента vla object nil

OK, so I guess the version that outputs this wouldn’t be any good?

Coordinate dump with LAYER
Line on layer 0
5.5138,14.1206,0.0000,10.8269,13.3799,0.0000
2dPolyline on layer 0
13.4834,15.4170,0.0000,14.4623,16.4663,0.0000,15.8001,16.6824,0.0000,16.6420,16.0676,0.0000,17.4373,15.5404,0.0000,18.8165,16.1499,0.0000,20.3718,16.9911,0.0000,21.1669,16.9596,0.0000
Polyline on layer 0
13.1745,12.7317,0.0000,14.8425,14.1206,0.0000,19.4142,11.0342,0.0000,21.0823,13.3799,0.0000
3dPolyline on layer 0
8.1086,6.9909,0.0000,10.2709,9.7996,0.0000,14.5645,7.7008,0.0000,15.7383,10.1391,0.0000

wrote in message news:5633644@discussion.autodesk.com…
Jeff,
Not 3d polylines. Individual pline segments. The cross sections were
created in LDD and displayed in 2D. The z value is redundent because all I
need is the X and Y. I have this other routine that will export all the
vertices of a polyline but not the layer (see attached).

KH

  • Печать

Страницы: [1] 2  Все   Вниз

Тема: запись данные в Excel  (Прочитано 8343 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Привет!
Не нашел информации по свойствам и методам работы с Excel из Autolisp.

Задача вроде бы простая:
 Создать файл .xlsx (без запуска приложения), и записывать данные в нужный лист и ячейку.
Кто подскажет есть ли готовые функции или перечень свойств и методов работы с эксель.


Записан



Записан


спасибо, приступаю к изучению!


Записан


; ошибка: no function definition: VLAX-GET-OBJECT

не первый раз — в чем причина? Это из серии когда надо нечто (vl-load-com) подключать? только для VLAX


Записан


;D(vl-load-com) помогло -странно обычно всегда в коде присутствовал


Записан


Приветствую еще раз!

  1. (defun PutCell (StartCell$ Data@ / Cell$ Column# ExcelRange Row#)

  2. (if (= (type Data@) ‘STR)

  3. (setq Data@ (list Data@))

  4. )

  5. (setq ExcelRange (vlax-get-property *ExcelApp% «Cells»))

  6. (if (Cellp StartCell$)

  7. (setq Column# (car (ColumnRow StartCell$))

  8.           Row# (cadr (ColumnRow StartCell$))

  9. );setq

  10. (if (vl-catch-all-error-p

  11. (setq Cell$ (vl-catch-all-applyvlax-get-property

  12. (list (vlax-get-property *ExcelApp% «ActiveSheet») «Range» StartCell$))

  13. );setq

  14. );vl-catch-all-error-p

  15. (alert (strcat «The cell ID «» StartCell$ «» is invalid.»))

  16. (setq Column# (vlax-get-property Cell$ «Column»)

  17.               Row# (vlax-get-property Cell$ «Row»)

  18. );setq

  19. );if

  20. );if

  21. (if (and Column# Row#)

  22. (foreach Item Data@

  23. (vlax-put-property ExcelRange «Item» Row# Column# (vl-princ-to-string Item))

  24. (setq Column# (1+ Column#))

  25. );foreach

  26. );if

  27. (princ)

  28. )

при команде:

  1. (GetExcel «C:\Users\Desktop\1\Filename.xlsx» «Sheet1» «L30»)

  2. (PutCell «A1» «PART_NUMBER»)

ругается на строку:

  1. (setq ExcelRange (vlax-get-property *ExcelApp% «Cells»))

ошибка Automation. Отсутствует описание. В консоли.
А в командной строке:
; ошибка: неверный тип аргумента: VLA-OBJECT nil

что не так?

« Последнее редактирование: 27-03-2017, 11:46:50 от Александр Ривилис »


Записан


Отмечено как Решение tujn08 27-03-2017, 20:22:07

Разобрался:
1. OpenExcel
2. PutCell
3. CloseExcel

Спасибо!


Записан


Напоминаю про правило форматирования кода на форуме.


Записан


Приносим свои извинения- привычка «DWG».

Как пользоваться разобрался. Но как создать файл эксель? Все функции написаны так, что файл уже должен существовать.


Записан


Приносим свои извинения- привычка «DWG».

Как пользоваться разобрался. Но как создать файл эксель? Все функции написаны так, что файл уже должен существовать.

Вопрос конечно интересный. Боюсь, что тебе придётся иметь заготовку xlsx-файла и копировать его с нужным именем.

« Последнее редактирование: 27-03-2017, 21:02:22 от Александр Ривилис »


Записан


Разобрался:

  1. (vlax-invoke-method (vlax-get-property *ExcelApp% «ActiveWorkbook»)

  2. «SaveAs» «путь +имя.xlsx» 4143 «» «» :vlax-false :vlax-false nil

  3. )

Спасибо!
Единственная проблема в  .xls и .xlsx.
На открытие файла .xlsx ошибка в формате или расширении файла. Печально… Будем думать дальше.

А форматирование по инструкции у меня не получилось — вписал вручную…


Записан


На VBA сообщения об ошибках более осмысленные, там удобнее тестировать COM
Думаю Excel вопросы задаёт разные — стоит сделать ручками и посмотреть, что за вопросы


Записан


Без подробностей и без проверок. Вся информация взята из справки по VBA для Excel:

  1. (defun test (filename / obj wbooks xls_wb xls_sheet xls_cells)

  2. (if (not (setq obj (vlax-get-object «Excel.Application»)))

  3. (progn (setq obj (vlax-get-or-create-object «Excel.Application»)) (vla-put-visible obj :vlax-false))

  4. ) ;_ end of if

  5. (if obj

  6. (progn (setq wbooks    (vlax-get-property obj ‘workbooks)

  7.                  xls_wb    (vlax-invoke-method (vlax-get-property obj ‘wbooks) ‘add)

  8.                  xls_sheet (vlax-get-property (vlax-get-property xls_wb ‘worksheets) ‘item 1)

  9.                  xls_cells (vlax-get-property xls_sheet ‘cells)

  10. ) ;_ end of setq

  11. ;; Заполнение данными элементов из xls_cells

  12. (vlax-invoke-method

  13.              xls_wb

  14.              ‘saveas

  15.              filename

  16. (cdr (assoc (atof (vlax-get-property obj ‘version))((10.0 . 43) (11.0 . 43) (12.0 . 56))))

  17.              nil

  18.              nil

  19. :vlax-false

  20. :vlax-false

  21. 1

  22. 2

  23. :vlax-true

  24. ) ;_ end of vlax-invoke-method

  25. (vlax-invoke-method xls_wb ‘close)

  26. (vlax-invoke-method xls_app ‘quit)

  27. ;; Очистка от мусора

  28. (foreach item (list xls_cells xls_sheet xls_wb wbooks obj)

  29. (vl-catch-all-apply (function (lambda () (vlax-release-object item) (setq item nil))))

  30. ) ;_ end of foreach

  31. ) ;_ end of progn

  32. ) ;_ end of if

  33. ) ;_ end of defun


Записан


Подскажите пожалуйста, как задать ячейке формат, интересует числовой и точность отображения знаков?
Научился только создавать файллист и записывать в ячейку значение

  1. (vlax-put-property Excell_Cells «Item» Row Column (vl-princ-to-string value))

Подозреваю вместо «Iten» нужно указать что-то типа «Format» и потом после адреса ячейки нужное значение какое-то, где бы это подглядеть?


Записан


Я бы поднял справку по VBA самого Excel’a и в нем смотрел. Фактически перевести из VBA в VLISP не так уж и сложно.
Могу выдрать кусок из большого проекта, но он будет касаться только установки значений для ячейки… Искать?


Записан


  • Печать

Страницы: [1] 2  Все   Вверх

Страницы 1

Чтобы отправить ответ, вы должны войти или зарегистрироваться

#1 14 марта 2012г. 16:18:08

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Тема: Отрисовка в AutoCad’e.

Есть переменная str_web, которая содержит набор команд для отрисовки. Отрисовка выполняется следующим образом:

(setq actdoc (vla-get-activedocument (vlax-get-acad-object)))
(vla-SendCommand actdoc str_web)

Все бы хорошо, но на экране отрисовка происходит неравномерно. Пример здесь. Причем, иногда более равномерно, иногда менее, редко — совсем равномерно.

Кто-нибудь знает, с чем это связано и как лечится?
Заранее благодарен!

#2 Ответ от kpblc 14 марта 2012г. 16:32:59

  • kpblc
  • kpblc
  • Активный участник
  • Откуда: С.-Петербург
  • На форуме с 29 ноября 2004г.
  • Сообщений: 8,347
  • Спасибо: 23

Re: Отрисовка в AutoCad’e.

Связано с применением командных методов. Лечится изменением кода 🙂

#3 Ответ от fixo 14 марта 2012г. 16:34:41

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

Леонид пишет:

vla-SendCommand

Этот метод работает асинхронно никак не вылечишь

[FONT=Arial]~’J’~[/FONT]

#4 Ответ от baliev 14 марта 2012г. 16:48:36 (изменено: Леонид, 14 марта 2012г. 16:54:07)

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Re: Отрисовка в AutoCad’e.

Кулик Алексей aka kpblc пишет:

Связано с применением командных методов. Лечится изменением кода

А намекнуть? 🙂 Использовать методы типа AddLine, что ли?

#5 Ответ от fixo 14 марта 2012г. 17:41:08

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

Из того что видно да
юзай VLA-add методы, тебе еще понадобится возможно
для симметричной детали
vla-mirror
vla-arraypolar, vla-arrayrectangular
vla-copy, vla-move …

[FONT=Arial]~’J’~[/FONT]

#6 Ответ от baliev 14 марта 2012г. 18:08:47 (изменено: Леонид, 14 марта 2012г. 18:09:11)

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Re: Отрисовка в AutoCad’e.

fixo пишет:

Из того что видно да

юзай VLA-add методы,  …

Спасибо! А не подскажешь, как установить ActiveX’ом текущий цвет (аналог команды «color»). А то я что-то не найду никак…

#7 Ответ от fixo 14 марта 2012г. 18:11:28

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

Леонид пишет:

Спасибо! А не подскажешь, как установить ActiveX’ом текущий цвет (аналог команды «color»). А то я что-то не найду никак…

(vla-setvariable adoc ‘cecolor 256)

не оно?

#8 Ответ от baliev 14 марта 2012г. 18:19:08

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Re: Отрисовка в AutoCad’e.

fixo пишет:

(vla-setvariable adoc ‘cecolor 256)

Ну, что могу сказать: практически чудо! ❗  Спасибо!

#9 Ответ от fixo 14 марта 2012г. 19:44:21

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

Посмотри быстрый пример, может извлеччешь оттуда что
полезное:

;;------------------------------------ code start ----------------------------------;;
(defun C:VDRAW(/ *error* acsp adoc circ gap gp hstep leng num p0 p1 p2 p3 p4 pc pline pt_list rad result util wid wstep)
  (defun *error* (msg)
      (vla-endundomark (vla-get-activedocument
              (vlax-get-acad-object))
          )
    (cond ((or (not msg)
           (member msg '("console break" "Function cancelled" "quit / exit abort"))
           )
       )
      ((princ (strcat "nError: " msg)))
      )

    (princ)
    )
  
  (defun var->list (value)
   (if (not (vl-catch-all-error-p
      (setq result (vl-catch-all-apply '(lambda()
    (vlax-safearray->list
      (vlax-variant-value value)))))))
     result
     (vl-catch-all-error-message result))      
)
  
  ;;                main part            ;;
 
 (setq adoc (vla-get-activedocument
              (vlax-get-acad-object))
       acsp (vla-get-block (vla-get-activelayout adoc))
       util (vla-get-utility adoc)
       )
  
  (vla-startundomark adoc)

  (setq pc (vla-getpoint util nil "nPick center point: "));<-- WCS
  (setq p0 (trans (var->list pc)1 0))
  
  (vla-initializeuserinput util 6 nil);<-- equivalent to (initget 6)
  (if (vl-catch-all-error-p
    (setq leng (vl-catch-all-apply '(lambda()
        (vla-getdistance util nil "nEnther a length of the shape <20>: ")))))
  (setq leng 20.0))
(vla-initializeuserinput util 6 nil);<-- equivalent to (initget 6)
  (if (vl-catch-all-error-p
    (setq wid (vl-catch-all-apply '(lambda()
        (vla-getdistance util nil "nEnther a width of the shape <10>: ")))))
  (setq wid 10.0))
  
       (setq p1 (trans (mapcar '+ p0 (list (/ leng -2) (/ wid -2))) 1 0))
         
    (setq pt_list (list
            (setq p1 (reverse (cdr (reverse p1))))
            (setq p2 (mapcar '+ p1 (list leng 0)))
            (setq p3 (mapcar '+ p2 (list 0 wid)))
            (setq p4 (mapcar '+ p1 (list 0 wid)))))
     (vla-put-closed
       (setq pline (vlax-invoke acsp 'addlightweightpolyline (apply 'append pt_list)))
       :vlax-true)
(vla-setbulge pline 1 2.5)
(vla-setbulge pline 3 2.5)
    (vla-initializeuserinput util 6 nil);<-- equivalent to (initget 6)
  (if (vl-catch-all-error-p
    (setq num (vl-catch-all-apply '(lambda()
        (vla-getreal util  "nNumber of shapes ? <8>: ")))))
  (setq num 8))

  
    (vla-initializeuserinput util 6 nil);<-- equivalent to (initget 6)
  (if (vl-catch-all-error-p
    (setq rad (vl-catch-all-apply '(lambda()
        (vla-getreal util  "nEnther a radius <1.0>: ")))))
  (setq rad 1.0)
    )


    (if (vl-catch-all-error-p
    (setq gap (vl-catch-all-apply '(lambda()
        (vla-getreal util  "nDistance between circles and borders <1.5>: ")))))
  (setq gap 1.5)
      )
 (setq p1 (trans (mapcar '+ p0 (list (* leng -2) (* wid -2)))1 0))
  
 (setq gp (trans (mapcar '+ p1 (list gap gap))1 0))
  
    (setq pt_list (list
            (setq p1 (reverse (cdr (reverse p1))))
            (setq p2 (mapcar '+ p1 (list (* leng 4) 0)))
            (setq p3 (mapcar '+ p2 (list 0 (* wid 4))))
            (setq p4 (mapcar '+ p1 (list 0 (* wid 4))))))
     (vla-put-closed
       (setq pline (vlax-invoke acsp 'addlightweightpolyline (apply 'append pt_list)))
       :vlax-true)
  
(setq circ (vlax-invoke acsp 'addcircle gp rad))
(setq wstep (/ (- (* wid 4)(* gap 2)) 2))
(setq hstep (/ (- (* leng 4)(* gap 2)) (1- num)))
  
(vla-arrayrectangular circ 3 8 1 wstep hstep 0)
  
(vla-regen adoc acactiveviewport)
  
(alert "Done")
  
 (princ)
  )

(princ "nType VDRAW to execute...")
(princ)
(or (vl-load-com)
    (princ))
;;------------------------------------ code end ----------------------------------;;

[FONT=Arial]~’J’~[/FONT]

#10 Ответ от fixo 14 марта 2012г. 20:28:42

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

Я бы создал небольшие функции для отрисовки
всяких там штучек, например нарисовать закругленный
прямоугольник

  (defun draw-slot(center leng wid)
        (setq p1 (trans (mapcar '+ center (list (/ leng -2) (/ wid -2))) 1 0))
         
    (setq pt_list (list
            (setq p1 (reverse (cdr (reverse p1))))
            (setq p2 (mapcar '+ p1 (list leng 0)))
            (setq p3 (mapcar '+ p2 (list 0 wid)))
            (setq p4 (mapcar '+ p1 (list 0 wid)))))
     (vla-put-closed
       (setq pline (vlax-invoke acsp 'addlightweightpolyline (apply 'append pt_list)))
       :vlax-true)
(vla-setbulge pline 1 1.0)
(vla-setbulge pline 3 1.0)
  pline
  );_draw-slot

А вызывать так

 (setq pc (vla-getpoint util nil "nPick center point of slot: "));<-- WCS
 (setq p0 (trans (var->list pc)1 0))
(setq pline (draw-slot p0 8. 2.))
  
(vlax-put pline 'color  161);<--(vlax-put color pline 161)
(vlax-put pline 'lineweight  30);<--(vla-put-lineweight pline 30)
(vlax-put pline 'linetype  "center");<--(vla-put-linetype pline "center")
(vlax-put pline 'linetypescale  0.2);<--(vla-put-linetypescale pline 0.2)

[FONT=Arial]~’J’~[/FONT]

#11 Ответ от baliev 15 марта 2012г. 12:53:50 (изменено: Леонид, 15 марта 2012г. 12:58:08)

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Re: Отрисовка в AutoCad’e.

fixo пишет:

Я бы создал небольшие функции для отрисовки

всяких там штучек, например нарисовать закругленный

прямоугольник

  ~’J’~

Спасибо большое! Я ActiveX’ом пользуюсь только, когда припрет, поэтому «слету» читать пока не могу. Нужно будет поизучать твой код (он у меня сходу почему то не работает). Но в любом случае, думаю, что пригодится для дела.

#12 Ответ от fixo 15 марта 2012г. 13:43:38

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

Леонид пишет:

(он у меня сходу почему то не работает).

Какое сообщение об ошибке в командной строке?
Скопируй и вставь сюда

[FONT=Arial]~’J’~[/FONT]

#13 Ответ от baliev 15 марта 2012г. 14:07:39

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Re: Отрисовка в AutoCad’e.

fixo пишет:

Какое сообщение об ошибке в командной строке?

Скопируй и вставь сюда

~’J’~

Ну, например в коде для отрисовки прямоугольника ввожу строку:

(setq pc (vla-getpoint util nil "nPick center point of slot: "))

Выдает ошибку: «; ошибка: неверный тип аргумента: VLA-OBJECT nil»

#14 Ответ от fixo 15 марта 2012г. 15:54:19

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

Ты случаем не отдельно это вызываешь?

(setq pc (vla-getpoint util nil "nPick center point of slot: "));<-- WCS 
(setq p0 (trans (var->list pc)1 0)) 
(setq pline (draw-slot p0 8. 2.)) 
   
(vlax-put pline 'color  161);<--(vlax-put color pline 161) 
(vlax-put pline 'lineweight  30);<--(vla-put-lineweight pline 30) 
(vlax-put pline 'linetype  "center");<--(vla-put-linetype pline "center") 
(vlax-put pline 'linetypescale  0.2);<--(vla-put-linetypescale pline 0.2) 

я думал сам догадаешься вставить это в основную программу
VDRAW

#15 Ответ от baliev 15 марта 2012г. 16:34:09

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Re: Отрисовка в AutoCad’e.

Да, действительно, я посчитал их двумя разными скриптами. Сорри…

#16 Ответ от fixo 15 марта 2012г. 16:42:01

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

Ничего страшного, бывает 🙂

[FONT=Arial]~’J’~[/FONT]

#17 Ответ от baliev 19 марта 2012г. 19:38:48

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Re: Отрисовка в AutoCad’e.

fixo пишет:

Ничего страшного, бывает 

  ~’J’~

А чем строку выводить, если метод vla-SendCommand работает ассинхронно?

#18 Ответ от fixo 19 марта 2012г. 23:19:48

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

У объекта AcadUtility есть метод Prompt
(объект  util из примера выше):

(vla-prompt util "nt< Здесь твоё сообщение >")

Неплохо в конце кода освобождать объекты,
хотя это не критично:

(vlax-release-object util)

[FONT=Arial]~’J’~[/FONT]

#19 Ответ от baliev 27 марта 2012г. 18:49:30

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Re: Отрисовка в AutoCad’e.

fixo пишет:

У объекта AcadUtility есть метод Prompt

(объект    util   из примера выше):

(vla-prompt util "nt< Здесь твоё сообщение >")

Неплохо в конце кода освобождать объекты,

хотя это не критично:

(vlax-release-object util)

  ~’J’~

Метод Prompt это, как мне кажется, все-таки не то, что нужно… Использовал SendCommand. В принципе получилось то, что хотел ==> здесь. Но, остался последний штрих: скорость вывода зависит от характеристик видеокарты, поэтому хотелось бы иметь возможность управлять этим процессом через задержку вывода. Единственное, что нашел это команду delay, но она при выводе больших массивов команд не работает… 🙁 Может быть ты знаешь лисп-функцию либо метод-activeX, которые выполняют задержку графического вывода?

#20 Ответ от fixo 27 марта 2012г. 20:04:38

  • fixo
  • fixo
  • Активный участник
  • Откуда: СПб
  • На форуме с 7 февраля 2009г.
  • Сообщений: 869
  • Спасибо: 41

Re: Отрисовка в AutoCad’e.

Извини ничего такого не встречал, к сожалению, тут я пас

[FONT=Arial]~’J’~[/FONT]

#21 Ответ от baliev 28 марта 2012г. 10:45:31

  • baliev
  • Участник
  • На форуме с 19 марта 2009г.
  • Сообщений: 56
  • Спасибо: 1

Re: Отрисовка в AutoCad’e.

fixo пишет:

Извини ничего такого не встречал, к сожалению, тут я пас

  ~’J’~

Не беда, dll-ку напишу. Или мы не программисты?* 😀
Еще раз спасибо за помощь! Всех благ!

Страницы 1

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Динамические блоки стали очень полезными элементами современного Автокада. Широкое применение динамических блоков значительно ускоряет процесс проектирования.

В этом уроке мы рассмотрим, как можно вставлять динамический блок и присваивать значения его атрибутам из LISP-программы. Для этого нам понадобятся материалы прошлых уроков. 

Вначале мы создадим блоки куба с дополнительными данными при помощи программы, рассмотренной нами в уроке: «LISP. Создание блока».

 Скачать программу Mp_kub3.lsp Скачать программу Mp_kub3.lsp (Размер файла: 993 bytes)

Затем извлечем из блока дополнительные данные.

Вставим динамический блок, созданный нами в уроке: «Создание динамического блока», и внесем в него дополнительные данные из блока куба.

 Скачать динамический блок Скачать динамический блок (Размер файла: 30 kB)

И так приступим:

Запустите AutoCAD.

Откройте Редактор Visual LISP, набрав в командной строке VLIDE (или VLISP)

Откройте программу mp_kub3, созданную в уроке: «LISP. Создание блока». См. Рис. 1

LISP. Динамический блок.

Рис. 1.   Программа mp_kub3.

Нажимаем кнопку «Загрузить активное окно редактора».

Затем на кнопку «Активизация AutoCAD».

Вводим в командной строке: mp_kub3 и нажмите <Enter>.

На запрос «Задайте длину стороны куба :» введите 300 и нажмите <Enter>

На запрос «Укажите базовую точку :» щелкните мышкой в рабочем окне Автокад.

Программа создаст блок куба с размерами сторон 300.

Повторно запустите программу (нажмите <Enter>).

На запрос «Задайте длину стороны куба :» введите 400 и нажмите <Enter>

На запрос «Укажите базовую точку :» щелкните мышкой в рабочем окне Автокад.

Программа создаст блок куба с размерами сторон 400.

В результате получим два куба, один со сторонами 300, другой 400. См. Рис. 2.

LISP. Динамический блок.

Рис. 2.   Создание блоков.

Вернемся в Редактор Visual LISP.

Создадим новый файл. Сохраним его под именем Udim.lsp.

Добавим в него строку для работы с функциями, входящими в расширение языка AutoLISP.

(vl-load-com)  - загружает функции расширения

Далее при помощи функции entsel попросим пользователя выбрать блок:

(entsel "Выберите блок: ")

Функция entsel возвращает имя указанного блока и координату точки указания.

При помощи функции car оставляем, только имя указанного блока:

(car (entsel "Выберите блок: "))

Функция car извлекает первый элемент из списка.

При помощи функции setq сохраняем имя блока в переменной obj:

(setq obj (car (entsel "Выберите блок: ")))

Далее преобразуем выбранный блок в vla-объект:

(setq vla_obj (vlax-ename->vla-object obj))

Имя vla-объекта сохраняем в переменной vla_obj.

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

Для этого используем функцию vlax-ldata-get:

(setq V (vlax-ldata-get vla_obj "obem")) – извлекает данные 
из VLA-объекта vla_obj по коду "obem", и сохраняет их в переменной V.
(setq po (vlax-ldata-get vla_obj "tochka")) – извлекает данные 
из VLA-объекта vla_obj по коду "tochka", и сохраняет их в переменной po.

Выделите весь текст и нажмите на кнопку «Загрузить выделенный фрагмент». См. Рис. 3.

LISP. Динамический блок.

Рис. 3.   Извлекаем данные из VLA-объекта.

На запрос «Выберите блок :» — укажите один из двух блоков.

Чтобы посмотреть значения переменных.

Выделите переменную V и нажмите на кнопку «Добавить контрольное значение».

Затем, выделите переменную ро и снова нажмите на кнопку «Добавить контрольное значение». Откроется окно «Контрольное значение», где можно посмотреть, чему равны переменные. См. Рис. 4.

LISP. Динамический блок.

Рис. 4.  Значения переменных.

Мы видим, что нам удалось получить данные, которые ранние мы добавляли в блок.

Давайте еще извлечем имя блока.

При помощи функции entget получим список с характеристиками примитива (блока).

Откройте консоль Visual LISP.

Добавьте строку (entget obj).

Выделите ее и нажмите на кнопку «Загрузить выделенный фрагмент». См. Рис. 5.

LISP. Динамический блок.

Рис. 5.  Характеристики примитива.

Функция вернет список:

((-1 . <Имя объекта: 7ed146c8>) (0 . «INSERT») (5 . «251») (102 . «{ACAD_XDICTIONARY») (360 . < Имя объекта: 7ed146d0>) (102 . «}») (330 . < Имя объекта: 7ed12cf8>) (100 . «AcDbEntity») (67 . 0) (410 . «Model») (8 . «0») (100 . «AcDbBlockReference») (2 . «kub400») (10 1485.09 652.573 0.0) (41 . 1.0) (42 . 1.0) (43 . 1.0) (50 . 0.0) (70 . 0) (71 . 0) (44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0))

Из этого списка нам нужно извлечь имя блока. Мы видим, что DXF-код имени блока = 2.

Используем для этого функцию assoc .

Функция assoc применяется к сложному списку, каждый элемент которого начинается с DXF-кода. Именно по этому коду функция assoc и извлекает элемент из списка.

(assoc 2 (entget obj))
2  - DXF-код имени блока.
(entget obj) — список с данными блока.

Их списка будет извлечен элемент DXF-кодом 2:

Функция вернет следующее значение:

(2 . "kub400")

Чтобы оставить только имя блока, применим функцию cdr.

(cdr (assoc 2 (entget obj)))

Функция cdr – возвращает список без первого элемента.

Сохраним имя блока в переменной bl_name.

(setq bl_name (cdr (assoc 2 (entget obj))))

Добавьте эту строку, выделите ее, загрузите выделенный фрагмент. В окне консоль Visual LISP появится возвращаемое значение – имя блока. См. Рис. 6.

LISP. Динамический блок.

Рис. 6.   Извлекаем имя блока.

Все необходимые данные мы получили, теперь можно вставлять наш динамический блок Vyn.

Я напомню, что предыдущем уроке («Создание динамического блока») мы сохранили его в папке MyLisp: (D:MyLispVyn.dwg).

Если эта папка добавлена у Вас в пути поддержки Автокад. В программе достаточно использовать имя блока “Vyn”.

Если нет, то нужно использовать полный путь к файлу

“D:MyLispVyn.dwg”.

Как добавить папку в пути поддержки Автокад, показано в уроке «Пример программы LISP с диалоговым окном».

Вставляем динамический блок:

(command "_insert" "Vyn" po 1 1 0 bl_name V)
"_insert" – стандартная команда Автокад вставки блока;
"Vyn" – имя вставляемого блока;
(Если папка, в которой находится блок не прописана вспомогательных путях Автокад,
в качестве имя нужно указать полный путь к файлу “D:MyLispVyn.dwg”)
рo – базовая точка вставки блока;
1 – масштабный коэффициент по оси X;
1 – масштабный коэффициент по оси Y;
0 – угол поворота блока в радианах;
bl_name – значение верхнего атрибута;
V – значение нижнего атрибута;

Добавляем эту строчку и преобразуем нашу программу в пользовательскую функцию defun

(defun c:Udum (/)
      <наша программа>
) ; end_defun

В результате получим. См.Рис. 7.

LISP. Динамический блок.

Рис. 7.  Вставляем динамический блок.

Загружаем активное окно редактора.

Переходим в Автокад.

В командной строке вводим Udim и нажимаем <Enter>.

На запрос «Выберите блок :» — укажите один из двух блоков.

Повторите команду (нажмите <Enter>).

На запрос «Выберите блок :» — укажите второй блок.

Программа построит две выноски. См. Рис. 8.

LISP. Динамический блок.

Рис. 8.  Текстовые выноски.

Мы видим, что у блока kub300 базовая точка не попала в цент верхней грани. Это произошло потому, что в момент вставки блока сработала привязка «середина отрезка». Поэтому когда вставляется блок привязки нужно отключить:

(setq osm (getvar "osmode")) – запоминаем привязки пользователя
(setvar "osmode" 0) – отключаем привязки

     Вставляем блок.

(setvar "osmode" osm) – возвращаем привязки пользователя.

Кроме этого давайте сделаем так, чтобы наша программа бесконечное количество раз просила выбрать блок, до тех пор, пока мы сами не прервем ее нажав <Esc>.

Для этого, добавим бесконечный цикл.

(while Т
      <выражения>
) :end while.

(более подробно об этом рассказано в уроке: «Пример AutoLISP программы: Сумма длин отрезков»)

Если пользователь при выборе блока промахнется и щелкнет на пустом месте, программа прервет свою работу, в командной строке появится надпись:

; ошибка: неверный тип аргумента: lentityp nil

Поэтому добавляем условие, которое будет проверять, чтобы переменная obj не равнялась nil.

(if (not (= obj nil))
   (progn
      <наши выражения>
   ) ;end progn
) ; end if

(более подробно об этом рассказано в уроке: «Пример AutoLISP программы: Сумма длин отрезков»)

В результате получим см. рис. 9.

LISP. Динамический блок.

Рис. 9.  Добавляем строчки.

Проверяем работу программы.

Удаляем динамические блоки.

Загружаем активное окно редактора.

Переходим в Автокад.

В командной строке вводим Udim и нажимаем <Enter>.

На запрос «Выберите блок :» — специально пощелкайте мимо блока. Программа не прерывается. Укажите один блок.

На следующий запрос «Выберите блок :» — выберите второй блок.

На следующий запрос – нажмите <Esc>.

Программа построит две выноски. См. Рис. 10

LISP. Динамический блок.

Рис. 10.   Выноски.

Мы видим, что полки у динамических блоков немного коротковаты. К тому же полку у блока kub400 не помешало бы немного поднять. Поскольку это динамические блоки, мы без особого труда можем сделать это вручную, но все таки хочется, чтобы это делала программа. Этим мы займемся в следующем уроке.

В заключение добавляем  локальные переменные в список временных переменных функции defun. См. Рис. 11.

LISP. Динамический блок.

Рис. 11.    Добавляем локальные переменные.

Код программы:

(defun c:Udim (/ obj vla_obj V po bl_name osm)
     (vl-load-com)  ; загружаем функции расширения 
     (while T 
          (setq obj (car (entsel "nВыберите блок: ")))
          (if (not (= obj nil)) 
               (progn
                    (setq vla_obj (vlax-ename->vla-object obj))  ; переводим в vla-object 
                    (setq V (vlax-ldata-get vla_obj "obem"))      ; объем 
                    (setq po (vlax-ldata-get vla_obj "tochka"))   ; координаты центра 
                    (setq bl_name (cdr (assoc 2 (entget obj)))) ; имя блока

                    (setq osm (getvar "osmode"))                    ; запоминаем привязки пользователя 
                    (setvar "osmode" 0)                                  ; отключаем привязки 
                    (command "_insert" "Vyn" po 1 1 0 bl_name V)  ; вставка блока 
                    (setvar "osmode" osm)    ; возвращает привязки пользователя 
               );end progn 
          ); end if 
     ); end while
 ); end_defun

 Скачать программу Udim.lsp Скачать программу Udim.lsp (Размер файла: 538 bytes)

На этом наш урок окончен.

В следующем уроке мы рассмотрим, как из LISP-программы изменять геометрические характеристики динамического блока.

Пишите в комментариях:

Трудно ли было выполнить этот урок?

Была ли для Вас полезной информация, данная в этом уроке?

На какие вопросы программирования, Вы хотели бы, увидит ответы в следующих уроках?

Я с удовольствием отвечу на ваши вопросы.

Если вы хотите получать новости с моего сайта. Оформляйте подписку.

До новых встреч.

 «Автор: Михаил Орлов»

Google

Также на эту тему Вы можете почитать:

  • Home
  • Forum
  • Discussions and Support
  • Programming
  • AutoLISP
  • Suddenly getting «error: bad argument type: VLA-OBJECT nil» when running lisp

  1. 2018-12-08, 08:17 PM


    #1

    Default Suddenly getting «error: bad argument type: VLA-OBJECT nil» when running lisp

    Hi folks,

    All of a sudden, running the routine below results in an error: «error: bad argument type: VLA-OBJECT nil». This routine has been working or years.

    Additionally, this very same routine works just fine at another office. Same version of AutoCAD Architecture, same drive letter, same file and block names…

    The only recent change is that we moved our support files from one server to another, but that is all still mapped to the same drive letter so AutoCAD should not see any difference.

    The routine is called using the following code in the tool palette:

    Code:

    ^C^C(if DetailSheetr30 (DetailSheetr30) (princ "Detail Sheet r30 not loaded."))

    Main code:

    Code:

    ;Detail Sheet r30
    (defun DetailSheetr30( / CL SCL DBX )
    (setq CL (getvar "CLAYER"))
    (command "_.-Layer" "m" "L-ANNO-SYMB" "c" "3" "L-ANNO-SYMB" "")
    (cond ((= (getvar "INSUNITS") 1) (setq SCL 1))
          ((= (getvar "INSUNITS") 2) (setq SCL 0.08333))
          ((= (getvar "INSUNITS") 4) (setq SCL 25.4))
          ((= (getvar "INSUNITS") 5) (setq SCL 2.54))
          ((= (getvar "INSUNITS") 6) (setq SCL 0.0254))
          (t (alert "Current DWG set to non-standard units.  Check UNITS settings"))
    )
    
    
    
    
    (defun open_dbx (dwg / dbx)
       (if (< (atoi (substr (getvar "ACADVER") 1 2)) 16)
          (setq dbx (vlax-create-object "ObjectDBX.AxDbDocument"))
          (setq dbx (vlax-create-object
          (strcat "ObjectDBX.AxDbDocument."
             (substr (getvar "ACADVER") 1 2)
             )
          )
       )
    )
    (vla-open dbx dwg)
    dbx
    )
    (setq Dbx (open_dbx "Z:/ACA 2019/Drawings/MVVA Callouts r30.dwg"))
    (vla-CopyObjects
    Dbx
    (vlax-safearray-fill
    (vlax-make-safearray vlax-vbObject '(0 . 0))
    (list (vla-item (vla-get-blocks dbx) "Detail Sheet r30"))
    )
    (vla-get-blocks
    (vla-get-activedocument (vlax-get-acad-object))
    )
    )
    (vlax-release-object dbx)
    
    
    (command "-insert" "Detail Sheet r30" "Scale" SCL PAUSE "0")
    
    
    (setvar "CLAYER" CL)
    (princ)
    )
    
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    Thanks for any insight.

    -JP

    Last edited by jpcadconsulting347236; 2018-12-08 at 08:40 PM.


  2. 2018-12-08, 10:34 PM


    #2

    Default Re: Suddenly getting «error: bad argument type: VLA-OBJECT nil» when running lisp

    Well, I repaired my install of AutoCAD and now it’s working fine. The fact that this happened concurrent to a server migration was tripping me up.

    Red Herring!!!!

    Stand down team… all is well.


  • Home
  • Forum
  • Discussions and Support
  • Programming
  • AutoLISP
  • Suddenly getting «error: bad argument type: VLA-OBJECT nil» when running lisp

Similar Threads

  1. Replies: 1

    Last Post: 2013-12-14, 07:15 PM

  2. Replies: 0

    Last Post: 2013-09-04, 08:29 PM

  3. Replies: 4

    Last Post: 2009-05-22, 05:21 AM

  4. Replies: 6

    Last Post: 2006-12-07, 11:42 PM

  5. Replies: 8

    Last Post: 2005-02-14, 11:41 PM


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
  • BB code is On
  • Smilies are On
  • [IMG] code is On
  • [VIDEO] code is On
  • HTML code is Off

Forum Rules

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Ошибка недопустимое для реестра значения виндовс 10
  • Ошибка неверный тип аргумента safearrayp nil