Search code examples
autocadautolisp

My code works, although only on my machine


I'm creating some AutoLisp commands for my team, and now that I'm finished, the code breaks apart in their computer and I can't figure out why. Works fine in mine.

The idea of the code is to stretch a polyline and update the block attributes that is grouped with. The code asks to select the block, the actual width of the polyline and the fraction that is is supposed to take (ex: 0.75 to reduce to 75%). Then, and here is were the problem starts, select the sides to stretch. On their computers, he does not allow to select, it simply jumps ahead.

(defun c:MRV (/ a b c d e)
;ungroup
(command "pickstyle" 0)
;variables
(setq blk (entsel "\nSelect block to modify: "))
(initget (+ 1 2 4))
(setq a (getreal "\nWidth?"))
(initget (+ 1 2 4))
(setq b (getreal "\nNew module fraction? (>0;1<)"))


    ;distance to reduce
    (setq c (- 1 b))
    (setq d (* a c -0.5))
    (setq e (* -1 d))

    ;stretch
    (command "stretch" pause pause "" "0,0" (polar '(0 0) (/ pi 2) d))

    (command "stretch" pause pause "" "0,0" (polar '(0 0) (/ pi 2) e))

    ;open layer
    (setq LayerTable (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
(if (and (tblsearch "LAYER" "MC_BLOCO_INFO_AREAS")
         (setq layname (vla-item layertable "MC_BLOCO_INFO_AREAS"))
         (= (vlax-get-property layname 'lock) :vlax-true)
         )
  (vla-put-lock layname :vlax-false))
    ;change attribute
    (setq l (cons "CAMPO_6" (rtos b 2 2)))
    (LM:SetAttributeValues (car blk) (list l))



    ;close layer
    (setq LayerTable (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
(if (and (tblsearch "LAYER" "MC_BLOCO_INFO_AREAS")
         (setq layname (vla-item layertable "MC_BLOCO_INFO_AREAS"))
         (= (vlax-get-property layname 'lock) :vlax-false)
         )
  (vla-put-lock layname :vlax-true))


    ;update block width
    (command "regenall")
    ;regroup
    (command "pickstyle" 1)
    (print "Modulo modificado.")
    (princ)
    )
(defun LM:SetAttributeValues ( blk lst / enx itm )
    (if (= "ATTRIB" (cdr (assoc 0 (setq enx (entget (setq blk (entnext blk)))))))
        (if (setq itm (assoc (strcase (cdr (assoc 2 enx))) lst))
            (progn
                (if (entmod (subst (cons 1 (cdr itm)) (assoc 1 enx) enx))
                    (entupd blk)
                )
                (LM:SetAttributeValues blk lst)
            )
            (LM:SetAttributeValues blk lst)
        )
    )
)

What should be happening:

what should be happening


Solution

  • When the AutoCAD STRETCH command issues the prompt for a selection of objects selected using a crossing window (crossing the segments that are to be stretched), the prompt is a standard selection prompt and the STRETCH command will subsequently obtain information about how the selection was acquired in the same way as you might using the AutoLISP ssnamex function.

    As such, I would suggest supplying the STRETCH command with a selection set which has already been acquired using a crossing window selection method.

    For example, you might define a function such as:

    (defun mystretch ( dis / pt1 pt2 sel )
        (while
            (and
                (setq pt1 (getpoint "\nSpecify first point of crossing window: "))
                (setq pt2 (getcorner pt1 "\nSpecify opposite point of crossing window: "))
                (not (setq sel (ssget "_C" pt1 pt2)))
            )
            (princ "\nNo objects were found within the crossing window.")
        )
        (if sel
            (progn
                (command "_.stretch" sel "" "_non" '(0 0) "_non" (list 0 dis))
                t
            )
        )
    )
    

    You can then evaluate the above function with the distance that you wish to stretch the objects in the Y-direction, e.g.:

    (mystretch 10.0)
    

    Or, using the variables in your code:

    (mystretch d)
    (mystretch e)
    

    The function will then return t (True) if the user has supplied two valid points and the STRETCH command has been issued - you can test for this in your program before proceeding.

    Using this approach you can ensure that the user has supplied two points defining a crossing window which intersects one or more objects prior to issuing the AutoCAD STRETCH command.

    The use of the ssget crossing mode string (C) also ensures that you are always supplying the STRETCH command which has been obtained using a crossing selection method.

    You may also wish to refer to this answer regarding the use of the _non object snap modifier and also the _. command prefix in the above example code.