Lisp - неверный тип аргумента: numberp: nil

Я пишу функцию, которая удаляет фоновую маску из всего mtext, однако после запуска кода я получаю ошибку bad argument type: numberp: nil:

(defun c:bgm ()
    (vl-load-com)
    (setq ss1 (ssget "X" '((0 . "MTEXT")(-4 . "<OR")(90 . 1)(90 . 3)(-4 . "OR>")))); selects all mtext with background mask on
    (setq sscount (sslength ss1))
    (repeat sscount
        (setq mtxtobj (entget (vlax-vla-object->ename (ssname ss1 counter))))
        (vla-put-backgroundfill mtxtobj :vlax-false)
        (entmod mtxtobj)
    )
)

Есть идеи, почему?


person Kevin Chiha    schedule 23.06.2018    source источник


Ответы (2)


Есть ряд проблем с вашим кодом:

  1. Если выражение ssget не получает выбор (т. е. если на чертеже нет объектов, удовлетворяющих критериям выбора), то ssget вернет nil, и, следовательно, функция sslength выдаст ошибку, если она будет передана с нулевым аргументом.

    Чтобы избежать этого, проверьте значение, возвращаемое функцией ssget, с помощью инструкции if, прежде чем переходить к оставшемуся коду:

    (if (setq ss1 (ssget "_X" '((0 . "MTEXT") (-4 . "<OR") (90 . 1) (90 . 3) (-4 . "OR>"))))
        (progn
            (setq sscount (sslength ss1))
            ...
        )
    )
    
  2. Вы ссылаетесь на переменную counter в своей функции ssname, которая не определена в области действия функции c:bgm:

    (ssname ss1 counter)
    

    Вместо этого это должно быть sscount, как определено ранее в вашем коде.

  3. Кажется, вы запутались между именами сущностей и вла-объектами:

    • ssname возвращает имя объекта, однако вы передаете его функции vlax-vla-object->ename, которая преобразует объект vla в имя объекта.

    • Вы используете функцию vla-put-backgroundfill для изменения свойства backgroundfill объекта vla, однако вы передаете этой функции переменную, определяемую значением, возвращаемым функцией entget, которая представляет собой список данных DXF, а не объект vla.

    • Вы используете entmod для изменения данных DXF, присвоенных переменной mtxtobj - это не требуется при изменении свойств ActiveX vla-объекта.


Принимая во внимание вышеизложенное, я бы предложил следующее решение:

(defun c:bgm ( / cnt obj sel )
    (if (setq sel (ssget "_X" '((0 . "MTEXT") (-4 . "<OR") (90 . 1) (90 . 3) (-4 . "OR>"))))
        (repeat (setq cnt (sslength sel))
            (setq cnt (1- cnt)
                  obj (vlax-ename->vla-object (ssname sel cnt))
            )
            (vla-put-backgroundfill obj :vlax-false)
        )
    )
    (princ)
)
(vl-load-com) (princ)
person Lee Mac    schedule 24.06.2018
comment
Я понял это после нескольких часов публикации темы. Большое спасибо за вашу помощь, очень признателен. Ура, приятель - person Kevin Chiha; 24.06.2018

Ошибка, вероятно, связана с:

(ssname ss1 counter)

где счетчик равен нулю. Вместо этого вы должны использовать sscount. Вы также должны уменьшить значение sscount, чтобы выполнить итерацию по набору выбора.

(defun c:bgm (/ ss1 sscount)
  (vl-load-com)
  (if (setq ss1 (ssget "X" '((0 . "MTEXT") (-4 . "<OR") (90 . 1) (90 . 3) (-4 . "OR>"))))
    (repeat (setq sscount (sslength ss1))
      (setq sscount (1- sscount)
        mtxtobj (vlax-vla-object->ename (ssname ss1 sscount))
      )
      (vla-put-backgroundfill mtxtobj :vlax-false)
    )
  )
)
person gileCAD    schedule 23.06.2018
comment
Ошибка все еще выскакивала, но я нашел решение! Спасибо, в любом случае - person Kevin Chiha; 24.06.2018