Jump to content

Error in AutoLISP Line Drawing: "VEVAL-STR+ ARX Command Exception"


Recommended Posts

Posted (edited)

Hello everyone,

I'm using AutoCAD 2022 and developing an AutoLISP application that involves reading data from a file and drawing lines based on this data. However, I'm encountering an error when trying to use the _LINE command to draw lines. The error message is as follows:

 

Exception in VEVAL-STR+ ARX Command
Unhandled Exception c0000027 (c0000027h)

 

(setq x1 (atof (nth 0 values)))
(setq y1 (atof (nth 1 values)))
(setq x2 (atof (nth 2 values)))
(setq y2 (atof (nth 3 values)))

(if (and (numberp x1) (numberp y1) (numberp x2) (numberp y2))
  (command "_LINE" (list x1 y1 0.0) (list x2 y2 0.0) "")
)

 

What I've Tried:

Checked that x1, y1, x2, and y2 are indeed numbers using numberp.

Verified that the values are not nil before calling the command function.

Added debug messages to print the values of x1, y1, x2, and y2.

Despite these checks, I still get the error. Could it be an issue with the type conversion or the way the _LINE command is being called? Any insights or suggestions on how to resolve this issue would be greatly appreciated.

 

AutoCAD Version: AutoCAD 2022

 

image.png.948a194bef472b0232e2a212da8c832f.png

Edited by DeEng
  • DeEng changed the title to Error in AutoLISP Line Drawing: "VEVAL-STR+ ARX Command Exception"
Posted

maybe :

(defun c:DeEng ( / values x1 x2 y1 y2 )
  (vl-load-com)
  (setq values (list "1" "2" "3" "4"))
  (setq x1 (atof (nth 0 values))) (setq y1 (atof (nth 1 values)))
  (setq x2 (atof (nth 2 values))) (setq y2 (atof (nth 3 values)))
  (if (and (numberp x1) (numberp y1) (numberp x2) (numberp y2))
    (vl-cmdf "_LINE" (list x1 y1 0.0) (list x2 y2 0.0) ""))
)

 

Posted

I keep getting the same error. I am sharing the entire code, what could be the reason for the error?

; LISP File
(vl-load-com)

(setq selectedFolderPath nil)

(defun c:MAIN ()
  (setvar "OSMODE" 0)
  (setq dcl_id (load_dialog "kart.dcl"))
  (if (not dcl_id)
    (alert "DCL file could not be loaded!")
  )

  (if (new_dialog "main_dialog" dcl_id)
    (progn
      (action_tile "btn_open_model" "(open_model_file)")
      (action_tile "btn_open_card" "(open_card_file)")
      (action_tile "btn_working_directory" "(select_working_directory)")
      (action_tile "btn_exit" "(exit)")
      (start_dialog)
    )
  )
  (unload_dialog dcl_id)
)

(defun select_working_directory ()
  (setq file_dialog_result
        (getfiled "Select a File" "" "crd;dat;upe;inp;txt" 0)
  )

  (if file_dialog_result
    (progn
      (setq selectedFolderPath (vl-filename-directory file_dialog_result))
    )
    (alert "No file was selected.")
  )
)

(defun open_file_dialog (types)
  (if (or (not selectedFolderPath) (= selectedFolderPath ""))
    (alert "Please select a working directory first!")
    (progn
      (if (and selectedFolderPath (findfile selectedFolderPath))
        (setq initialDir (strcat selectedFolderPath "\\"))
        (setq initialDir ""))

      (setq selected_file (getfiled (strcat "Select " types " File") initialDir "crd;dat;upe;inp" 0))
      (if selected_file
        (progn
          (analyze_file selected_file types)
        )
        (alert "No file was selected.")
      )
    )
  )
)

(defun open_model_file ()
  (open_file_dialog "Model")
)

(defun open_card_file ()
  (open_file_dialog "Card")
)

(defun analyze_file (file profile)
  (setq ext (get_file_extension file))
  (setq lines (read_file_lines file))

  (cond
    ((or (equal ext ".CRD") (equal ext ".UPE") (equal ext ".INP"))
     (AnalyzeAngleFile lines)
    )
    ((equal ext ".DAT")
     (AnalyzePlateFile lines)
    )
    (T
     (alert (strcat "Unsupported file extension: " ext))
    )
  )
)

(defun read_file_lines (filename)
  (setq lines '())
  (setq file (open filename "r"))
  (while (setq line (read-line file))
    (if (and line (not (equal line "")))
      (setq lines (append lines (list (vl-prin1-to-string line))))
    )
  )
  (close file)
  lines
)

(defun is-string (value)
  (eq (type value) 'STR)
)

(defun AnalyzeAngleFile (lines)

  (setq firstLine (nth 0 lines))
  (setq splitParts (split_first firstLine "-"))
  (setq towerType (nth 0 splitParts))
  (setq poseNumber (nth 1 splitParts))

  (setq secondLine (nth 1 lines))
  (setq profile (parse_angle_profile secondLine))
  (setq firstFlange (nth 0 profile))
  (setq secondFlange (nth 1 profile))
  (setq thickness (nth 2 profile))

  (setq len (nth 2 lines))

  (setq weight (nth 3 lines))

  (setq quality (nth 4 lines))

  (setq sixthLine (nth 5 lines))
  (setq parts (split_by_whitespace sixthLine))
  (setq quantity (nth 0 parts))
  (setq revision (nth 1 parts))
  (setq date (nth 2 parts))

  (setq referenceNumber (nth 6 lines))

  (setq projectName (nth 7 lines))

  (setq drawingNumber (nth 8 lines))

  (setq drawnBy (nth 9 lines))

  (setq checkedBy (nth 10 lines))

  (setq note (nth 11 lines))

  (AnalyzeAdditionalLines lines 12)

)

(defun AnalyzePlateFile (lines)
  (if (< (length lines) 10)
    (progn
      (setq firstLine (nth 0 lines))
      (setq splitParts (split_first firstLine "-"))
      (setq towerType (nth 0 splitParts))
      (setq poseNumber (nth 1 splitParts))

      (setq secondLine (nth 1 lines))
      (setq dimensions (parse_plate_dimensions secondLine))
      (setq thickness (nth 0 dimensions))
      (setq width (nth 1 dimensions))
      (setq len (nth 2 dimensions))

      (setq quality (nth 2 lines))

      (setq sixthLine (nth 3 lines))
      (setq parts (split_by_whitespace sixthLine))
      (setq quantity (nth 0 parts))
      (setq revision (nth 1 parts))
      (setq date (nth 2 parts))

      (setq referenceNumber (nth 4 lines))

      (setq projectName (nth 5 lines))

      (setq drawingNumber (nth 6 lines))

      (setq drawnBy (nth 7 lines))

      (setq checkedBy (nth 8 lines))

      (setq note (nth 9 lines))
    )
  )
  (AnalyzeAdditionalLines lines 10)
)

(defun AnalyzeAdditionalLines (lines startLine)
  (setq lineCount (length lines) currentIndex startLine)
  (while (< currentIndex lineCount)
    (setq currentLine (trim-string (vl-string-trim "\"" (nth currentIndex lines))))
    (setq firstChar (substr currentLine 1 1))
    
    (cond
      ((= firstChar "L")
       (setq values (parse_values (substr currentLine 2)))
       (if (= (length values) 4)
         (progn
           
           (setq x1 (atof (nth 0 values)))
           (setq y1 (atof (nth 1 values)))
           (setq x2 (atof (nth 2 values)))
           (setq y2 (atof (nth 3 values)))

           (if (and (numberp x1) (numberp y1) (numberp x2) (numberp y2))
             (command "_LINE" (list x1 y1 0.0) (list x2 y2 0.0) "")
           )
         )
       )
      )
      (T (alert "Unknown line type detected."))
    )
    (setq currentIndex (1+ currentIndex))
  )
)

(defun trim-string (str)
  (while (and (> (strlen str) 0) (= (substr str 1 1) " "))
    (setq str (substr str 2)))
  (while (and (> (strlen str) 0) (= (substr str (strlen str) 1) " "))
    (setq str (substr str 1 (- (strlen str) 1))))
  str
)

(defun parse_values (str)
  (setq values '())
  (setq str (trim-string str))
  (while (/= str "")
    (setq pos (vl-string-search " " str))
    (if pos
      (progn
        (setq values (append values (list (substr str 1 pos))))
        (setq str (trim-string (substr str (+ pos 1))))
      )
      (progn
        (setq values (append values (list str)))
        (setq str "")
      )
    )
  )
  values
)

(defun get_file_extension (file)
  (setq ext (strcase (vl-filename-extension file)))
  ext
)

(defun split_first (str delim)
  (setq pos (vl-string-search delim str))
  (if pos
    (list (substr str 1 pos) (substr str (+ pos 2)))
    (list str ""))
)

(defun split_by_whitespace (str)
  (setq result '())
  (setq str (vl-string-trim " " str))
  (while (setq pos (vl-string-search " " str))
    (if (> pos 0)
      (progn
        (setq result (cons (substr str 1 pos) result))
        (setq str (vl-string-trim " " (substr str (+ pos 1)))))
      (setq str nil)))
  (if str (setq result (cons str result)))
  (reverse result)
)

(defun parse_plate_dimensions (str)
  (setq str (substr str 4))
  (setq dimensions (string-split-alt str "x"))
  (setq thickness (nth 0 dimensions))
  (setq width (if (>= (length dimensions) 2) (nth 1 dimensions) ""))
  (setq len (if (>= (length dimensions) 3) (nth 2 dimensions) ""))
  (list thickness width len)
)

(defun parse_angle_profile (str)
  (setq str (substr str 3))
  (setq profileParts (string-split-alt str "."))
  (setq firstFlange (nth 0 profileParts))
  (setq secondFlange (if (>= (length profileParts) 2) (nth 1 profileParts) ""))
  (setq thickness (if (>= (length profileParts) 3) (nth 2 profileParts) ""))
  (list firstFlange secondFlange thickness)
)

(defun string-split-alt (str delim / result pos)
  (setq result '())
  (while (setq pos (strpos str delim))
    (setq result (cons (substr str 1 (1- pos)) result))
    (setq str (substr str (+ pos (strlen delim)))))
  (reverse (cons str result))
)

(defun strpos (str delim / i)
  (setq i 1)
  (while (and (<= i (strlen str)) (/= (substr str i (strlen delim)) delim))
    (setq i (1+ i)))
  (if (<= i (strlen str)) i nil)
)

(defun exit ()
  (unload_dialog dcl_id)
  (princ)
)

(princ "Program loaded successfully. Use 'MAIN' command to start.")
(princ)

; DCL File
main_dialog : dialog {
    label = "Main Menu";

    : boxed_column {
        label = "Main Menu Options";
        
        : button { key = "btn_open_model"; label = "OPEN MODEL"; width = 30; }
        : button { key = "btn_open_card"; label = "OPEN CARD"; width = 30; }
        : button { key = "btn_working_directory"; label = "WORKING DIR"; width = 30; }

        : button { key = "btn_exit"; label = "Exit"; width = 30; is_cancel = true; }
    }
}
Posted (edited)

@DeEng

 

Ok - here are some thoughts:

 

1) It's very difficult to diagnose the problem if a) we don't have any way to run it, and 2) we don't understand the purpose. However - I can see the following:

2) The first obvious thing I see wrong with the code is this line:

(action_tile "btn_exit" "(exit)")

You should never use "exit" here as it stops all code processing and sends to the error handler, which doesn't allow the dialog to close or unload properly. It should rather be:

(action_tile "btn_exit" "(done_dialog)")

3) The second obvious thing i see is that you MUST close the dialog before you run (command). You are trying to run the LINE command while the dialog is still open which is not allowed. You have to close the dialog before you can do the LINE command. Your defun (AnalyzeAdditionalLines) tries to run while the dialog is open, hence the main problem I think. I suggested changing:

(action_tile "btn_open_model" "(open_model_file)")
(action_tile "btn_open_card" "(open_card_file)")

to this:

(action_tile "btn_open_model" "(done_dialog)(open_model_file)")
(action_tile "btn_open_card" "(done_dialog)(open_card_file)")

Or you have to rearrange your function (AnalyzeAdditionalLines) to run after the dialog closes. You can use an argument (done_dialog n) with an integer that can be captured with (start_dialog), such as (setq retval (start_dialog )) and use a conditional statement example (cond ((= ret 1) (do_this1)) ((= ret 2) (do_this2)...) etc to do different things after the dialog closes, then optionally re-load the dialog after within a (while) loop such as (while (> ret 0) ....)

Edited by pkenewell
  • Thanks 1
Posted

Thanks for the help. After editing the main file like this, the program worked.

 

(defun c:MAIN ()
  (setvar "OSMODE" 0)
  (create-layers)
  (setq dcl_id (load_dialog "kart.dcl"))
  (if (not dcl_id)
    (alert "DCL file could not be loaded!")
  )

  (if (new_dialog "main_dialog" dcl_id)
    (progn
      (action_tile "btn_info" "(setq userAction 1) (done_dialog 1)")
      (action_tile "btn_holes" "(setq userAction 2) (done_dialog 1)")
      (action_tile "btn_open_model" "(setq userAction 3) (done_dialog 1)")
      (action_tile "btn_open_card" "(setq userAction 4) (done_dialog 1)")
      (action_tile "btn_working_directory" "(setq userAction 5) (done_dialog 1)")
      (action_tile "btn_exit" "(setq userAction 0) (done_dialog 0)")
      (start_dialog)
    )
  )
  (unload_dialog dcl_id)

  (cond
    ((= userAction 1) (show_info_dialog))
    ((= userAction 2) (show_holes_dialog))
    ((= userAction 3) (open_model_file))
    ((= userAction 4) (open_card_file))
    ((= userAction 5) (select_working_directory))
    ((= userAction 0) (exit))
    (T (alert "No valid action selected."))
  )
)

 

Posted (edited)

@DeEng I suggest the following code instead. The value of (done_dialog) is returned from (start_dialog) when a call to (done_dialog) is made with an integer argument.

(defun c:MAIN ()
  (setvar "OSMODE" 0)
  (create-layers)
  (setq dcl_id (load_dialog "kart.dcl"))
  (if (not dcl_id)
    (alert "DCL file could not be loaded!")
  )

  (if (new_dialog "main_dialog" dcl_id)
    (progn
      (action_tile "btn_info" "(done_dialog 1)");<---set return value in (done_dialog) to be captured by the result of (start_dialog)
      (action_tile "btn_holes" "(done_dialog 2)")
      (action_tile "btn_open_model" "(done_dialog 3)")
      (action_tile "btn_open_card" "(done_dialog 4)")
      (action_tile "btn_working_directory" "(done_dialog 5)")
      (action_tile "btn_exit" "(done_dialog 0)")
      (setq useraction (start_dialog));<---- Capture result of (done_dialog)
    )
  )
  (unload_dialog dcl_id)

  (cond
    ((= userAction 1) (show_info_dialog))
    ((= userAction 2) (show_holes_dialog))
    ((= userAction 3) (open_model_file))
    ((= userAction 4) (open_card_file))
    ((= userAction 5) (select_working_directory))
    ((= userAction 0) (princ "\nDone."));<---- Exit is not necessary here.
    (T (alert "No valid action selected."))
  )
)

The AutoCAD Help is not very clear on this, but you can use ANY integer value in (done_dialog) and it will be returned to (start_dialog).

https://help.autodesk.com/view/ACDLT/2024/ENU/?guid=GUID-A150544E-ACE5-415F-AAB4-930E2715FDC7

 

ALSO: as i noted previously, (exit) is not necessary. It evokes the error handler, which is not desired to exit a function cleanly.

Edited by pkenewell
  • Agree 2

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...