Lee Mac 发表于 2022-7-5 20:34:59

ksperopoulos 发表于 2022-7-5 20:38:02

LeeMac - Thank you for the reference.Maybe I ought to just look on your website for anything I need before asking the questions on here.It seems you have everything covered!
 
I am looking to incorporate something better than what I currently have (see below).While this works, I think it could be cleaned up - which typically means implementing anything you say to do.Do you see any reason to change what I currently have?I only need to go from "A-Z" and "AA-ZZ".
 

(defun c:WID ( / *error* weld lst num1 num2) (defun *error* (msg)   (if (not (member msg '("Function cancelled" "quit / exit abort")))       (princ (strcat "\nError: " msg))   )   (princ) ) (initget "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA BB CC DD EE FF GG HH II JJ KK LL MM NN OO PP QQ RR SS TT UU VV WW XX YY ZZ") (setq weld (getkword "\nEnter weld identification letter: ")      lst (vl-string->list weld)       num1 (car lst)       num2 (cadr lst) ) (while      (if (and (

ksperopoulos 发表于 2022-7-5 20:39:50

It looks like I already found a bug in my code.If the user enters anything with two characters, it throws off the desired values.i.e. user input=CC, value=))

Jef! 发表于 2022-7-5 20:43:53

Yup, that's why I used that in my example

(setq weld(ascii (getkword "\nEnter weld identification letter or enter to exit: "))); here I get the ascii equivalent of the letter provided(while (/= t )      (if (

ksperopoulos 发表于 2022-7-5 20:47:52

 
I did this because the program would increment from A to Z and then from AA to infinity.By using the repeat function, it made the incrementing stop at ZZ.
 
 
Oops!I must have posted some of the code while I was messing around with it.Thanks for the catch.
 
 
I would have to disagree.I am not seeing any errors like this.

Jef! 发表于 2022-7-5 20:49:32

mm.. I don't know how I've checked, but retesting on another computer I get the same result as you, feeding a lower case works.
 
I've spent few (many-many) hours reworking on my side, I got it to workat 100%. It accept both 1 or 2 letters input, if 1 letter is input afterz it goes to AA and keep on. Hitting Enter at any moment exits quietly.Instead of pausing the mleader command, i get input and feed them tothe mleader. That way you can point text than position of arrow tip, orarrow first then text by inverting the 2 setq getpoints (2 lines in green together then 2 lines in blue together)
 

;;code made by Jef!;;2014-02-08(defun c:WID ( / *error* startingweldinput singleletterlist doubleletterlist weldascii counter txtpt leaderpt weldID) (defun *error* (msg)   (if (not (member msg '("Function cancelled" "quit / exit abort")))       (princ (strcat "\nError: " msg))   )   (princ) )(initget "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA BB CC DD EE FF GG HH II JJ KK LL MM NN OO PP QQ RR SS TT UU VV WW XX YY ZZ")   (setq startingweldinput (getkword "\nEnter weld identification letter or enter to exit: ")) (setq singleletterlist (list "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z")   doubleletterlist (list "AA" "BB" "CC" "DD" "EE" "FF" "GG" "HH" "II" "JJ" "KK" "LL" "MM" "NN" "OO" "PP" "QQ" "RR" "SS" "TT" "UU" "VV" "WW" "XX" "YY" "ZZ")       weldascii (ascii startingweldinput)       counter (+ 1 (- weldascii 65)))       (cond ( (member startingweldinput singleletterlist)          (while (and                (not (if(> counter 52)(progn(princ "\n\nout of letters, aborting\n") t )))                     (setq txtpt (getpoint "\nChoose a point for text or enter to exit: "))               (setq leaderpt (getpoint "\nChoose a point for leader or enter to exit: "))         (princ)             )             (if ( counter 26)(progn(princ "\n\nout of letters, aborting\n")t)))                     (setq txtpt (getpoint "\nChoose a point for text or enter to exit: "))               (setq leaderpt (getpoint "\nChoose a point for leader or enter to exit: "))         (princ)             )                  (setq weldID (strcat (chr weldascii)(chr weldascii)))                  (command "mleader" txtpt txtpt weldID leaderpt)                  (setq weldascii (+ 1 weldascii))          (setq counter (+ 1 counter))          (princ)          )                         )   ))Path I took:
I check the input and retrieve the ascii. if double letter it gets ascii of first char.
I start a counter (setq counter (+ 1 (- weldascii 65))). Basically the counter get value 1 for A, 2 for B and so on. I use itto excape the while prevent getting over z (or zz).
I then check if the original input is part of single or double charlist, then proceed with conditional based upon that. The ascii number isused for the WeldID.
When its single input i also use the ascii number and if ascii go over90 (z) I remove 26 from its value (to start back at A) and use it twice(AA) .
 
I so never figured that one out, gurus..
its drove me crazy for hours!!! need a guru to explain...
At the beginning, the orange lines had (exit) instead of t... like this
(not (if(> counter 52)(progn(princ "\n\nout of letters, aborting\n") (exit))))
I cant figure out why, when the counter got to 52, the progn seemed to be evaluated. The (princ "\nOut of letters, routine is interrupted") was processed, but not the (exit). Cad/vlide frooze and I got $1 on console. I tried to monitor variables, but since Cad needed user input I never figured out the way to proceed. Why only half the progn was processed and not the exit?
 
I ended up simply returning true (t), with the "not" before the the routine get interrupted by the and of the while.. so instead of the f stopping it, its the while/and who make all the calcelling. make sense? =D
 
@ksperopoulos. Fully working. I hope you'll enjoy =)
Cheers
Jef!
ps.: all comments are welcome

Lee Mac 发表于 2022-7-5 20:54:39

I would suggest the following:

(defun c:wid ( / lst str )   (while       (not         (or (= "" (setq str (strcase (getstring "\nEnter weld id letter : "))))               (and (wcmatch str "@,@@")                  (apply '= (setq lst (vl-string->list str)))               )         )       )       (princ "\nInvalid weld ID, please enter A-Z or AA-ZZ")   )   (if (/= "" str)       (progn         (while               (and                   (not (equal lst '(91 91)))                   (vl-cmdf "_.mleader" "\\" "\\" (vl-list->string lst))               )               (setq lst (if (equal lst '(90)) '(65 65) (mapcar '1+ lst)))         )         (if (equal lst '(91 91))               (princ "\nExhausted all weld IDs.")         )       )   )   (princ))

ksperopoulos 发表于 2022-7-5 20:56:27

Jef! - I appreciate the effort you put into your code.I had one problem when running it - there was no leader.It only had the text with a dogleg for the leader.
 
Lee - a few questions:
1. In your first IF function, why do you evaluate "" is not equal to str?From what it looks like, if "" then the program exits during your first WHILE.If there is a string, it continues.
2. Why do you use the vl-cmdf instead of command?
3. Is there an advantage to using "\\" over pause?
4. Obviously your code works.I see how you are resetting the variable lst using mapcar and cycling through A-Z.I even understand how you are transitioning from Z to AA.But I don't understand how you are telling it to go from '(65 65) to '(66 66) and so on.Could you explain how you acheived this please?

Lee Mac 发表于 2022-7-5 20:59:30

 
During the initial while loop, the user may exit the loop by pressing Enter, causing the getstring function to return an empty string (""). This is necessary since the user would otherwise need to force an error using Esc to exit this loop if the weld ID format criteria are not fulfilled.
 
Note that the subsequent if expression is not part of this initial while loop, hence the program must test whether there is a valid string before continuing the program operations.
 
 
Because vl-cmdf tests the validity of the supplied arguments before submitting them to the command-line (whereas the command function simply submits all supplied arguments to the command-line), meaning that the program will continue without error if the user presses Esc during the MLEADER command prompt.
 
 
See here.
 
 
Note that the mapcar expression is not 'resetting' the lst variable, but rather incrementing its contents.
 
 
See my tutorial on the evaluation of the mapcar function: Mapcar & Lambda

Jef! 发表于 2022-7-5 21:01:29

mmm. I use the mleader command, and as with mleader command if you put tip too close to text the arrow tip wont be there.
 
maybe: There are some options in mleader, for instance mine asks for 2 points limits for the text, the text than the leader tip.. while it looks like some users only have to specify only 2 points. originally while you use "pause" "pause" text to create your leaders, i had to add one pause at the end for it to work. Nonetheless, even if not as elegant as lee macs (who dont work on my side as my mleader asks for 3 points while yours seems to require only 2), it works with my current mleader settings. Since i use leaders instead of mleaders i never change anything, so i all the original settings.
 
Lee, I have to say that i'm slightly disapointed that it seems you took inspiration from my code and logic without mentionning it, commenting my code or answering my question following it.
页: 1 [2]
查看完整版本: 递增问题