Kevin Chiha
Kevin Chiha

Reputation: 69

Lisp - bad argument type: numberp: nil

I am writing a function that removes background mask from all mtext, however, I am getting a bad argument type: numberp: nil error after running the code:

(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)
    )
)

Any ideas why?

Upvotes: 0

Views: 2776

Answers (2)

gileCAD
gileCAD

Reputation: 2493

The error is probably due to:

(ssname ss1 counter)

where counter is nil. You should use sscount instead. You also have to decrement the sscount value to iterate through the selection set.

(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)
    )
  )
)

Upvotes: 2

Lee Mac
Lee Mac

Reputation: 16025

There are a number of issues with your code:

  1. If the ssget expression does not obtain a selection (i.e. if there are no objects present in the drawing which fulfil the selection criteria), then ssget will return nil, and consequently the sslength function will error when supplied with a null argument.

    To avoid this, test the value returned by the ssget function using an if statement before proceeding with the remaining code:

    (if (setq ss1 (ssget "_X" '((0 . "MTEXT") (-4 . "<OR") (90 . 1) (90 . 3) (-4 . "OR>"))))
        (progn
            (setq sscount (sslength ss1))
            ...
        )
    )
    
  2. You reference the variable counter in your ssname function, which is not defined in the scope of the c:bgm function:

    (ssname ss1 counter)
    

    This should instead be sscount as defined earlier in your code.

  3. You seem to be confused between entity names and vla-objects:

    • ssname returns an entity name, however, you are passing this to the vlax-vla-object->ename function, which converts a vla-object to an entity name.

    • You are using the vla-put-backgroundfill function to change the backgroundfill property of a vla-object, however, you are passing this function the variable defined by the value returned by entget, which is a DXF data list, not a vla-object.

    • You are using entmod to modify the DXF data assigned to the variable mtxtobj - this is not required when changing ActiveX properties of a vla-object.


Taking the above into consideration, I would suggest the following solution:

(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)

Upvotes: 2

Related Questions