Author Topic: Please help, urgently looking for a lisp routine to fix measurement var issues  (Read 5279 times)

0 Members and 1 Guest are viewing this topic.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
When using the VLIDE, make sure that the options are set so that it doesn't insert Tabs - this will make the code look better when you post it on the forums :-)

Dibbler

  • Guest
I started trying to use vlide, but hated it because I was over complicated for where I'm at, I will probably like it later, but right now it was just an extra layer of complication. Then went to notepad and late on Friday went over to Notepad++ (someone in the office who did some code at school thought it would help) and I agree it’s much better. The section under was created in it, so it should line up better.

The use of (progn in the first few lines is where I had it doing a few things & then stripped it out. I forgot to remove the un-needed code.

So it now works (see attached if you want a look, its getting a little long), I can see how to improve it further. There must be a way to just get a list of linetypes & create a table or array or something & then work through that, rather than listing every possible permutation. It runs fine as is, but there must be a smarter way, but that’s for later as I have to get all this working even if it is the long way round...

Next are the hatches...

I’ve looked in help & on Google, where I found some syntax to crib in order to doctor the linetype code, but it doesn’t work... Please can someone point me in the right direction, I'm sure it will stick out like a sore thumb to someone who knows how it should look. I cant get rid of ; error: malformed string on input but I cant spot why.


Code: [Select]

(DEFUN C:Hatfix (/ FlagANSI31 FlagANSI32)



; Update all the Hatch Patterns ("Out the box" imperial & metric hatch patterns only) that are used in the current drawing.

 
    (if (setq i -1
        Hatch (ssget "_X" '((0 . "hatch"))))
        (progn
            (while (setq selhatch (ssname Hatch (setq i (1+ i)))) ; get first hatch entity
                (if (setq Entity (cdr (assoc 2 (entget selhatch)))) ; open entity, get 2nd element in list (hatch pattern),
                    (progn                                           ; start mutiple commands to find all hatch patterns & reload them.

                        (cond ( (= (strcase Entity) "ANSI31") ; start condition for that hatch pattern
                                (if (/= FlagANSI31 1) ; if the flag for this hatch pattern is not set to 1
                                    (progn ;start mutiple commands to set linetye & change flag
                                        (command ".hatch "P" "ANSI31" "" "" "") ;reload the hatch pattern
                                        (setq FlagANSI31 1) ;set flag for this hatch pattern to 1
                                    ); end progn
                                ); end if
                               );end condition

                            ( (= (strcase Entity) "ANSI32") ;repeat
                                (if (/= FlagANSI32 1)
                                    (progn
                                        (command .hatch "P" "ANSI32" "" "" "")
                                        (setq FlagANSI32 1)
                                    )
                                )
                            )



); end the condition
); end the progn
); end the if
); end the 'while' loop
); end the progn
); end the if
)
« Last Edit: April 20, 2010, 12:55:56 PM by Dibbler »

Hangman

  • Swamp Rat
  • Posts: 566
Ahhh, good call Lee.  I hadn't thought of that myself.  Thanks.

I was going to finish mentioning in my last post before I was pulled away,
Your variables can be (setq Variable nil) at the end of each condition after the flag is set.  From the looks of your code, after the linetype is run, the flag is set to 1 and if the linetype is brought up again, it won't run as the flag is keeping from doing so.
The purpose for setting the variable as a local is so it will not conflict with other variables, whether they be local (from other routines) or global.  So as long as you set your variable back to nil when done with it, you should be able to get away with that.
If anyone else is following along this post, perhaps they can correct me if I'm wrong or if I haven't covered local variables very well.

Also Dibbler, in your 'print list of outcomes ...', you may want to print out only those items that were NOT updated.  It'll save a lot on the coding & a lot on time reading through it all to see what was done and trying to determine if anything was missed.

I formatted your code a bit just to show you a clean format of sorts  (please be aware, this is just MY style, others here have their own styles that help them understand their code better).   The main reason for this is mainly to show you some other options you have for coding.
I rewrote the MyMeas variable section just to show you another way of getting the same information without the use of a variable.
Also, I took out the (progn ...  in the 'print list of outcomes' section, notice the "\n" at the end of the prompts, it will do the same thing.
Anyway, this is just for example purposes  (I do better with examples).  :)
Code: [Select]
(defun c:impfix2 (/ i MyMeas Lines selLine Entity flagBORDER FlagBORDERX2
                 )
;----------------------------------------------------------------------------------------------------------------------------
  (setq MyMeas (getvar "measurement")) ; set MyMeas to current value of Measurement
  (if (= MyMeas 0) ; if value is 0 (is imperial)
    (setvar "measurement" 1) ; Set measurement to 1 & report to user
  ) ; end if
;----------------------------------------------------------------------------------------------------------------------------
; Another way to write the MyMeas check
  (if (= (getvar "measurement") 0)
    (setvar "measurement" 1)
  )
; This way, I didn't have to use a variable (unless you need it again later in the code)
;----------------------------------------------------------------------------------------------------------------------------
  (if (setq i -1
            Lines (ssget "_X" '((0 . "ARC,LINE,CIRCLE,SOLID,ELLIPSE,LWPOLYLINE")))
      ) ; ends the setq
    (progn
      (while (setq selLine (ssname Lines (setq i (1+ i)))) ; get first line entity
        (if (setq Entity (cdr (assoc 6 (entget selLine)))) ; open entity, get 2nd element in list (linetype),
          (progn ; start mutiple commands to find all linetypes & reload them.
            (cond ( (= (strcase Entity) "BORDER") ; start condition for that ltype
                    (if (/= FlagBORDER 1) ; if the flag for this linetype is not set to 1
                      (progn ;start mutiple commands to set linetye & change flag
                        (command ".Linetype" "L" "BORDER" "acadiso.lin" "Y" "") ;reload the linetype
                        (setq FlagBORDER 1) ;set flag for this linestyle to 1
                      ); end progn
                    ); end if
                  );end condition
                  ( (= (strcase Entity) "BORDERX2")
                    (if (/= FlagBORDERX2 1)
                      (progn
                        (command ".Linetype" "L" "BORDERX2" "acadiso.lin" "Y" "")
                        (setq FlagBORDERX2 1)
                      )
                    )
                  )

              ; ##### [the other 70+ linetypes go in here] ####

            ); end the condition
          ); end the progn
        ); end the if
      ); end the 'while' loop
    ); end the progn
  ); end the if
  (command ".regenall")
  (command ".textscr")
;----------------------------------------------------------------------------------------------------------------------------
; print list of outcomes
  (princ "\n----------------------------------------------\n")
  (princ "\nThe following actions have been performed... \n")
  (if (= MyMeas 1)
    (princ "\nmeasurement is set to metric\n")
  )
  (if (= FlagBORDER 1)
    (princ "\nLinetype - BORDER - has been updated\n")
  )
  (if (= FlagBORDERX2 1)
    (princ "\nLinetype - BORDERx2 - has been updated\n")
  )        
  (princ "\n----------------------------------------------")
  (princ)
); end defun lisp

DOHT !!  I move to slow.
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Hangman

  • Swamp Rat
  • Posts: 566
Here's one issue:
Code: [Select]
(progn ;start mutiple commands to set linetye & change flag
   (command ".hatch "P" "ANSI31" "" "" "") ;reload the hatch pattern
   (setq FlagANSI31 1) ;set flag for this hatch pattern to 1
); end progn
and another:
Code: [Select]
(progn
   (command .hatch "P" "ANSI32" "" "" "")
   (setq FlagANSI32 1)
)

Pay close attention to the quote marks in the (command ...  line.


Here's something else you want to be careful with:
Code: [Select]
(if (setq i -1
              Hatch (ssget "_X" '((0 . "hatch")))
        )
        (progn ...

You are using a variable called "Hatch" which is the same as a command and other things in autocad.  Not good.
Try changing your variable "Hatch" to "entHatch" or "entHatchPats" etc., first it tells you it is an entity, second, it seperates the variable from the commands in autocad.  Just make sure you call your variables a unique name that will not conflict with autocads commands.

When you are creating a new routine like this one, you can always check your work.  One simple way to make sure you are indeed selecting hatch patterns when using this:
Code: [Select]
(if (setq i -1
              Hatch (ssget "_X" '((0 . "hatch")))
        )
is to put a piece of hatch on a drawing and then getting the information from it.
Use this to get the info:
Code: [Select]
(defun c:info (/ )
  (setq x (car (entsel))) ; X is the entity selected, CAR gets the first item of the list of X
  (setq y (entget x)) ; Y gets the info of X
)
NOTICE - the X and Y are variables.  Currently they are global as I don't have them declared.
At the command prompt, type in:  !x
You will see 'entity name' and some number.  With other objects you can get two or three items in the name; a coordinate, etc.  By using the subroutine CAR, it selects only the first item of the selected object, the name.
At the command prompt, type in:  !y
You will see in the textscreen a list of stuff.  This stuff is the info of the entity.  If you are selecting a hatch pattern, you will see in the list, this:  (0 . "HATCH")
This will tell you that you can certainly use the code above; (ssget "_X" '((0 . "hatch")))  to select the hatch patterns in a drawing.
To break that piece of code down to help you understand it a little more, look at the following.  This piece of code is condensed;
Code: [Select]
(if (setq i -1
              Hatch (ssget "_X" '((0 . "hatch")))
        )
This is uncondensed;
Code: [Select]
(if
  (progn
    (setq i -1)
    (setq entHatchPats (ssget "_X" '((0 . "hatch"))))
     ...
Again, white space doesn't matter much in LiSP.  you could put that code like this:
Code: [Select]
(if (setq i -1 Hatch (ssget "_X" '((0 . "hatch"))))Notice in the uncondensed, I had to insert a (progn ...  because we have two commands in the 'if' statement.  In the condensed code, there is a single command (setq ...  but it does the same thing as the uncondensed.  The subroutine (setq ...  can do multiple settings with the single subroutine.
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Dibbler

  • Guest
I just wanted to log in & say I haven't given up or run away, I've been unable to touch any lisp for days, its almost finished & I'll post the finished code here as soon as I get chance!