Author Topic: Adding Numbers  (Read 8121 times)

0 Members and 1 Guest are viewing this topic.

cmwade77

  • Swamp Rat
  • Posts: 1443
Adding Numbers
« on: August 18, 2015, 07:05:38 PM »
I have searched for some routines to do this, but haven't been able to find anything that does what I need. We often have to add multiple numbers together and previously my routine required selecting each number, one at a time. I have rewritten it to use a crossing window. The problem is it doesn't always work with mleaders with blocks that have multiple attributes and I can't figure out why.

Here is the code, if someone could take a look at it and help me out, I would greatly appreciate it.

<<EDIT: Code is now too long to add inside the message, please see attached file>>
<<EDIT: 08/21/2015 - Code updated to latest version. Provides visual feedback as to which pieces of text was included in the total and fixes some decimal point issues>>
« Last Edit: August 21, 2015, 07:52:05 PM by cmwade77 »

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Adding Numbers
« Reply #1 on: August 19, 2015, 06:16:07 AM »
I think what you are doing is strange and can confuse the average user. Your code rejects attributes whose insertion point does not fall in a crossing window even though these attributes have been highlighted during the selection process.

You use this code to calculate the insertion point of an attribute:
Code: [Select]
(setq TestPt1
  (polar
    (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint Att)))
    (angle '(0 0 0) InsPt1)
    (distance '(0 0 0) InsPt1)
  )
)
This could be replaced by:
Code: [Select]
(setq TestPt1 (mapcar '+ InsPt1 (vlax-get Att 'insertionpoint)))
Both pieces of code have the same result. Both do not take account of the scaling and rotation of the block and I suspect that may be the cause of your problem. Two other thing to consider: The OCS of the mleader does not have to match the WCS and (vla-get-insertionpoint) will return a point that does not always match the insertion point as perceived by the user (another reason for confusion).

Edit: Typo.
« Last Edit: August 19, 2015, 07:28:47 AM by roy_043 »

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Adding Numbers
« Reply #2 on: August 19, 2015, 12:34:25 PM »
I think what you are doing is strange and can confuse the average user. Your code rejects attributes whose insertion point does not fall in a crossing window even though these attributes have been highlighted during the selection process.

You use this code to calculate the insertion point of an attribute:
Code: [Select]
(setq TestPt1
  (polar
    (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint Att)))
    (angle '(0 0 0) InsPt1)
    (distance '(0 0 0) InsPt1)
  )
)
This could be replaced by:
Code: [Select]
(setq TestPt1 (mapcar '+ InsPt1 (vlax-get Att 'insertionpoint)))
Both pieces of code have the same result. Both do not take account of the scaling and rotation of the block and I suspect that may be the cause of your problem. Two other thing to consider: The OCS of the mleader does not have to match the WCS and (vla-get-insertionpoint) will return a point that does not always match the insertion point as perceived by the user (another reason for confusion).

Edit: Typo.

Yeah, it's not quite clear which attributes are selected, not sure what I can do about that portion, as it needs the ability to select individual attributes in blocks with more than one attribute, but I also want the ability to select multiple pieces of text, attributes, etc. at once.

As for WCS, this text is always drawn in world coordinates and at a scale of 1 with no rotation, so I don't think that is an issue for my purposes, I do admit that it would be an issue for some people using it though.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Adding Numbers
« Reply #3 on: August 19, 2015, 02:07:35 PM »
In your OP you have said 'it doesn't always work with mleaders'. It would help if you have a dwg and a scenario to demonstrate the problem.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Adding Numbers
« Reply #4 on: August 20, 2015, 04:18:57 AM »
Looking again at the code again I think there are two other issues:
  • You do not check if the variable 'et' references 'ent'.
  • I think you should allow duplicate entities in the selection set ("_:D").
Perhaps the "_:V" option of ssget will be useful? Note: both the "_:D" and the "_:V" option do not work on BricsCAD V14.

My suggestion for the algorithm:
Code - Auto/Visual Lisp: [Select]
  1. ; ...
  2. (setq ss (ssget "_:D" filter))
  3. ; ...
  4. (setq ssEntDataLst (ssnamex ss))
  5. (setq ssPolyDataLst (vl-remove-if-not '(lambda (itm) (minusp (car itm))) ssEntDataLst))
  6. (setq ssEntDataLst (vl-remove-if '(lambda (itm) (minusp (car itm))) ssEntDataLst))
  7. (while ssEntDataLst
  8.   (setq curEnt (cadar ssEntDataLst))
  9.   (setq curEntDataLst (vl-remove-if-not '(lambda (itm) (equal curEnt (cadr itm))) ssEntDataLst))
  10.   (setq ssEntDataLst (vl-remove-if '(lambda (itm) (equal curEnt (cadr itm))) ssEntDataLst))
  11.   ; ...
  12.   ; ...
  13.   ; ...
  14. )

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Adding Numbers
« Reply #5 on: August 20, 2015, 11:36:47 AM »
I don't think I want duplicate entities, I want to accurately add up numbers, not end up adding the same number twice. But I could be wrong, I am curious what your reasoning for allowing duplicate entities is.

As for the :V option, it isn't documented in the help file, what does this option do?


roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Adding Numbers
« Reply #6 on: August 20, 2015, 12:03:51 PM »
I don't think I want duplicate entities, I want to accurately add up numbers, not end up adding the same number twice. But I could be wrong, I am curious what your reasoning for allowing duplicate entities is.
If an mleader is selected by a crossing that does not include an attribute the user should have the ability to reselect it with a crossing that does. Of course your code should then correctly process the duplicates.

As for the :V option, it isn't documented in the help file, what does this option do?
:V Forces subentity selection. Treats all interactive, graphic selections performed by the user as subentity selections. The returned selection set contains subentities only. This option cannot be combined with the duplicate or nested selection modes. This option is supported only with interactive selections, such as window and crossing. It is not supported for all, filtered, or group selections.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Adding Numbers
« Reply #7 on: August 20, 2015, 12:31:55 PM »
Yeah, interestingly enough, the :V option is no longer documented in 2016. But after further testing, you are right about the duplicate issue, now I just have to figure out how I want to handle duplicates in the rest of my code.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Adding Numbers
« Reply #8 on: August 20, 2015, 02:31:15 PM »
Ok, I have incorporated the suggestion for duplicates, but I am getting a couple of odd results, not sure why. If a Multileader has a block with only one attribute, I am getting "misplaced dot on input" and if there is more than attribute in the block for an mleader, it only uses one of the selected blocks. I am thinking that it is using the handle of the attribute definition instead of the attribute itself to determine if it has already been added, but I am unsure of how to get the handle of the actual attribute with this code. Please see code below.

<<Edit: Code Removed now that it has been debugged to avoid confusion>>
« Last Edit: August 20, 2015, 05:03:47 PM by cmwade77 »

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Adding Numbers
« Reply #9 on: August 20, 2015, 02:33:43 PM »
Most likely your "misplaced dot on input" error is related to something like this: (READ ".01"). You might consider using ATOF.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Adding Numbers
« Reply #10 on: August 20, 2015, 02:48:40 PM »
Most likely your "misplaced dot on input" error is related to something like this: (READ ".01"). You might consider using ATOF.
I just checked and I have nothing like that, in fact, the only . I have anywhere in my code are:
Code: [Select]
; Version 2.0 - Written by Chris Wade - 09/16/2011
; Version 3.0 - Written by Chris Wade - 08/18/2015
;;  Returns a string with all MText formatting codes removed. ;;
;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
(if (setq rx (vlax-get-or-create-object "VBScript.RegExp"))
(foreach pair
'(
("\032"    . "\\\\\\\\")
(" "       . "\\\\P|\\n|\\t")
("$1"      . "\\\\(\\\\[ACcFfHLlOopQTW])|\\\\[ACcFfHLlOopQTW][^\\\\;]*;|\\\\[ACcFfHLlOopQTW]")
("$1$2/$3" . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
("$1$2"    . "\\\\(\\\\S)|[\\\\](})|}")
("$1"      . "[\\\\]({)|{")
)
(setq str (_replace (car pair) (cdr pair) str))
)
(setq Filter '((-4 . "<OR") (0 . "TEXT") (0 . "MULTILEADER") (0 . "*DIMENSION*") (0 . "MTEXT") (-4 . "<AND") (0 . "INSERT") (66 . 1) (-4 . "AND>") (-4 . "OR>")))
(princ "\nNo number found, skipping instance.")

There are absolutely not other . in my code at all.

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Adding Numbers
« Reply #11 on: August 20, 2015, 03:00:26 PM »
Most likely your "misplaced dot on input" error is related to something like this: (READ ".01"). You might consider using ATOF.
I just checked and I have nothing like that, in fact, the only . I have anywhere in my code are:
Code: [Select]
; Version 2.0 - Written by Chris Wade - 09/16/2011
; Version 3.0 - Written by Chris Wade - 08/18/2015
;;  Returns a string with all MText formatting codes removed. ;;
;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
(if (setq rx (vlax-get-or-create-object "VBScript.RegExp"))
(foreach pair
                           '(
                              ("\032"    . "\\\\\\\\")
                              (" "       . "\\\\P|\\n|\\t")
                              ("$1"      . "\\\\(\\\\[ACcFfHLlOopQTW])|\\\\[ACcFfHLlOopQTW][^\\\\;]*;|\\\\[ACcFfHLlOopQTW]")
                              ("$1$2/$3" . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
                              ("$1$2"    . "\\\\(\\\\S)|[\\\\](})|}")
                              ("$1"      . "[\\\\]({)|{")
                           )
                           (setq str (_replace (car pair) (cdr pair) str))
                        )
(setq Filter '((-4 . "<OR") (0 . "TEXT") (0 . "MULTILEADER") (0 . "*DIMENSION*") (0 . "MTEXT") (-4 . "<AND") (0 . "INSERT") (66 . 1) (-4 . "AND>") (-4 . "OR>")))
(princ "\nNo number found, skipping instance.")

There are absolutely not other . in my code at all.
Ummmm...
Code - Auto/Visual Lisp: [Select]
  1. (defun che_str2num (str / test numlst lst)
  2.   (setq test (list 46 48 49 50 51 52 53 54 55 56 57))
  3.   (setq charlst (vl-string->list str))
  4.   (foreach x charlst
  5.     (if   (member x test)
  6.       (setq lst (cons x lst))
  7.       (setq lst (cons 32 lst))
  8.     )
  9.   )
  10.   (read (vl-list->string (reverse lst)))
  11. )
  12. (che_str2num ".01")


Quote
_$


CHE_STR2NUM
; error: misplaced dot on input
_1$

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Adding Numbers
« Reply #12 on: August 20, 2015, 03:02:59 PM »
Most likely your "misplaced dot on input" error is related to something like this: (READ ".01"). You might consider using ATOF.
I just checked and I have nothing like that, in fact, the only . I have anywhere in my code are:
Code: [Select]
; Version 2.0 - Written by Chris Wade - 09/16/2011
; Version 3.0 - Written by Chris Wade - 08/18/2015
;;  Returns a string with all MText formatting codes removed. ;;
;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
(if (setq rx (vlax-get-or-create-object "VBScript.RegExp"))
(foreach pair
                           '(
                              ("\032"    . "\\\\\\\\")
                              (" "       . "\\\\P|\\n|\\t")
                              ("$1"      . "\\\\(\\\\[ACcFfHLlOopQTW])|\\\\[ACcFfHLlOopQTW][^\\\\;]*;|\\\\[ACcFfHLlOopQTW]")
                              ("$1$2/$3" . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
                              ("$1$2"    . "\\\\(\\\\S)|[\\\\](})|}")
                              ("$1"      . "[\\\\]({)|{")
                           )
                           (setq str (_replace (car pair) (cdr pair) str))
                        )
(setq Filter '((-4 . "<OR") (0 . "TEXT") (0 . "MULTILEADER") (0 . "*DIMENSION*") (0 . "MTEXT") (-4 . "<AND") (0 . "INSERT") (66 . 1) (-4 . "AND>") (-4 . "OR>")))
(princ "\nNo number found, skipping instance.")

There are absolutely not other . in my code at all.
Ummmm...
Code - Auto/Visual Lisp: [Select]
  1. (defun che_str2num (str / test numlst lst)
  2.   (setq test (list 46 48 49 50 51 52 53 54 55 56 57))
  3.   (setq charlst (vl-string->list str))
  4.   (foreach x charlst
  5.     (if   (member x test)
  6.       (setq lst (cons x lst))
  7.       (setq lst (cons 32 lst))
  8.     )
  9.   )
  10.   (read (vl-list->string (reverse lst)))
  11. )
  12. (che_str2num ".01")


Quote
_$


CHE_STR2NUM
; error: misplaced dot on input
_1$

But it doesn't get called in this way, or at least it shouldn't, so I will have to check that one.

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Adding Numbers
« Reply #13 on: August 20, 2015, 03:23:11 PM »
I'm not sure I understand "getting called in this way" ? This is easily debugged in the VLIDE.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: Adding Numbers
« Reply #14 on: August 20, 2015, 05:01:31 PM »
I was only dealing with whole numbers, so I couldn't see how it could have gotten called as (che_stre2num ".5"), it wasn't making any sense. Turns out the error was elsewhere, but this did bring up a good point that it wouldn't work with numbers like .5.

Unfortunately atof wouldn't work on a string like "100 FXU" which is why I had to use the routine I have. But thanks to the pointers, I was able to correct for that and I figured out how to determine if the attribute has already been added or not by combing the handle of the attribute definition with the handle of the leader.

I will update the code in the first post with the final code and remove the code from the other post to avoid confusion.

Thank you all for the help and if you find any other errors, please let me know.