How to merge two commands in one, to select entities and add property sets in a quantity schedule table? - autocad

I'm trying to combine to autocad commands to one. The commands is used for selecting entities for a schedule table and adding the property sets.
The first command is: ScheduleSelectionAdd
The second command is: AecAddAllPropSets
My code so far:
(defun c:upDateSchedule()
(command "ScheduleSelectionAdd")
(command "AecAddAllPropSets")
(princ)
)
I have also tried this:
(defun c:upDateSchedule()
(command "ScheduleSelectionAdd" "" "AecAddAllPropSets" "")
(princ)
)
Every time it only adds my selected entities to the table and not updating my property sets, so here I'm stuck.
TIA

Acquire the selection first, using ssget, and then pass the selection to each command, for example:
(defun c:updateschedule ( / sel )
(if (setq sel (ssget "_:L"))
(command
"_.scheduleselectionadd" sel ""
"_.aecaddallpropsets" sel ""
)
)
(princ)
)
Here, the :L mode string excludes objects on locked layers.
Note that the above assumes that these commands only have a single prompt for a selection of objects.

Related

Counting blocks in a specific location (autolisp)

So I'm making a simple function in autolisp to count the number of a specific block in a drawing, and it looks like this:
(defun c:contarblocos()
(setq ss (ssget "x" ' ((0. "INSERT") (2. "Nome do bloco"))))
(setq count (sslength ss))
(alert(strcat "Total de blocos no desenho: " (itoa count)))
)
Now, what I really want is to count the number of blocks in a specific area, defined by the user. In other words, the user will call the function, and then the function will ask for a specific area, where it will look for the specific block and count them, not counting any blocks from outside the selected area.
Rather than using the x mode string of the ssget function (which searches the entire drawing database for all entities which fulfil the criteria of the filter list argument), simply omit this argument to permit the user to make a selection using any valid selection method, e.g.:
(defun c:contarblocos ( / sel )
(if (setq sel (ssget '((0 . "INSERT") (2 . "Nome do bloco"))))
(alert (strcat "Total de blocos no desenho: " (itoa (sslength sel))))
)
(princ)
)
There are a few other issues with your current code:
Always declare the variables whose scope is local to your function: in my above example, you will note that the sel symbol is declared in the variable list within the defun expression. For more information on why this is important, you may wish to refer to my tutorial here.
You should test whether ssget returns a valid selection set before calling the sslength function to obtain the number of items in the set, since (sslength nil) will error. You will see that I use an if statement in my code to accomplish this.
The ssget filter list argument should be an association list of dotted pairs, and as such, there should be a space between the key and the value in each list item, hence this:
(0. "INSERT")
Should become:
(0 . "INSERT")
You should include a final (princ) or (prin1) expression within the defun expression so that the function returns a null symbol to the command line, rather than returning the value returned by the last evaluated expression (i.e. the alert expression, which will return nil). Including a (princ) expression per my example will ensure that the function exits 'cleanly'.

What makes Crystal ignore record selection formula?

Crystal 2008. Have record selection formula ending with
and
( ( "Zero" in {?Credit_Debit} and {V_ARHB_BKT_AGING_DETAIL.AMOUNT} = 0)
or ( "Credit" in {?Credit_Debit} and {V_ARHB_BKT_AGING_DETAIL.AMOUNT} < 0)
or ( "Debit" in {?Credit_Debit} and {V_ARHB_BKT_AGING_DETAIL.AMOUNT} > 0) )
but no matter what combination of values is selected for Credit_Debit the result set is the same.
Also without success, I tried joining the parameter array into a single string and using lines like
or ( {#Cred_Deb_Choices} like "*Credit*" and {V_ARHB_BKT_AGING_DETAIL.AMOUNT} < 0)
Using the first method works in the same formula when the parameter values are integers, as:
and ({?Location ID} = 0 or {V_ARHB_BKT_AGING_DETAIL.LOC_ID} in {?Location ID})
I examined the generated SQL, and saw that the part at the beginning that had no effect was not shown.
I changed a part that tested for a hard-coded value to instead test for a parameter value, and looked at the SQL again. No change.
When you try to create a filter that doesn't fit with the datatype of the field then that doesn't get reflected in record selection formula.
For Integer field give integers in record selection for text give text.
E.g:
ID=0 and Name='XXX' works
ID='Zero' and Name='XXX' doesn't
This should solve your issue

Autocad user variables

Is it possible to use local variables in dwg file and display them in text objects?
For example, I need to numerate objects starting with some value:
value0 = 5
value1 = value0 + 1
value2 = value0 + 2
etc...
Can I put value1 and value2 into some text object on my drawing?
User variables will certainly work. Be aware that they are limited in number and other programs may also set them without your knowing.
If you want simple values to be be displayed as text AutoCAD can do that. The scope of variables is up to you and the api you choose. (VB, VBA, AutoLisp, .NET etc.)
There are other data storage options available in the dwg file.
To display an integer in a TEXT or MTEXT (or attribute) object you insert a field, select DieselExpression as the field type and then type your expression. You can do this for other data types as well.
There are various user variables available for the task. To achieve the above, type the following into the AutoCAD command prompt:
setvar useri1 5 (sets the value of user integer1 to 5)
Then you can use the following DieselExpressions in fields inside different text objects:
$(getvar, useri1) (gets the value of useri1)
$(+,$(getvar,useri1),1) (add 1 to the value of useri1)
$(+,$(getvar,useri1),2) (add 2 to the value of useri1)
etc...
It would help to know what language you prefer to use. This is very easy to do using AutoLISP. Suppose you'd like a program to ask the user for a number, then proceed forward to increment that number and put the increments successively into drawing text (say lot numbers).
Here is a working and complete little sample of how you'd do something like this:
(defun c:consecunum ( / entget_in entsel_in value_in value_out)
(setq
value_in (getint "\nFirst number: ")
value_out value_in
)
(while (setq entsel_in (entsel (strcat "\nText to replace with \"" (itoa value_out) "\": ")))
(setq entget_in (entget (car entsel_in)))
(entmod
(subst
(cons 1 (itoa value_out))
(assoc 1 entget_in)
entget_in
)
)
(setq value_out (1+ value_out))
)
)
If you have any questions about how this works, don't hesitate to ask.

cmd.exe: complex conditions?

in DOS batch files, In an IF statement, is it possible to combine two or more conditions using AND or OR ? I was not able to find any documentation for that
Edit - help if and the MS docs say nothing about using more than one condition in an if.
I guess a workaround for AND would be to do
if COND1 (
if COND2 (
cmd
)
)
but this is exactly what I'm trying to avoid.
No, there is no easier way.
For and you can also just chain them without introducing blocks:
if COND1 if COND2 ...
which frankly isn't any worse than
if COND1 and COND2 ...
However, for or it gets uglier, indeed:
set COND=
if COND1 set COND=1
if COND2 set COND=1
if defined COND ...
or:
if COND1 goto :meh
if COND2 goto :meh
goto :meh2
:meh
...
:meh2
I once saw a batch preprocessor which used C-like syntax for control flow and batch stuff in between and then converted such conditionals into multiple jumps and checks. However, that thing was for DOS batch files and was of little to no use in a Windows environment.
I sometimes wonder, what people learn at school nowadays! Of course 'OR' is possible too. Any system that can provide you with a 'NOT' and an 'AND', automatically provides you with an 'OR' too, because:
x OR y = NOT ( (NOT x) AND (NOT y) ) see http://en.wikipedia.org/wiki/De_Morgan%27s_laws
So as long as the expression "if (x AND y) then do z" can be written like this:
if (x) if (y) (do z)
... we should be able to write the expression "if (x OR y) then do z", but there is a problem:
Where shall we put the first 'NOT'? Well, the answer is nowhere, we should reform the equation above first to:
NOT ( x OR y ) = (NOT x) AND (NOT y)
According to this, we may write "if (NOT(x OR y)) then (do z)" as:
"if ((NOT x) AND (NOT y)) then (do z)"
Having this and knowing how to express AND as shown above, we can now write the expression "if (NOT(x OR y)) then (do z)" as:
if (not x) if (not y) (REM do z)
We also know that the expression:
"if (NOT p) then (do q) else (do r)"
... is equivalent to:
"if (p) then (do r) else (do q)
Thus we can write for "if (x OR y) then (do z)":
"if (NOT(x OR y)) then (do nothing) else (do z)"
So we can express "if (x OR y) then (do z)" as:
if (not x) if (not y) (REM do nothing) else (REM do z)
But this is not complete yet, because this is not a true 'AND' but a "simulated" one. What is missing is the second else. So the complete form to get the correct result should be:
if (not x) ( if (not y) (REM do nothing) else (REM do z) ) else (REM do z) )
... which has the ugly double else part. You can solve that with a 'goto' and we finally have:
rem if (x OR y) then (do z):
if (not x) ( if (not y) (goto :doNothing) )
rem do z
:doNothing
For the AND workaround I agree with Joey, I cannot see another solution.
For the OR workaround I would propose the following 'trick':
Lets say that you want to test if user asked for help on the command line while calling for your batch file, something like: thebatch /?.
But you don't know if the user will type /? or rather (being a Unix accustomed user) --help or -h or even forget to pass any argument at all.
Your code could be like:
for %%P in ("" "-h" "--help") do if "%1"==%%P (
:help
echo this is my help... >&2
exit /b 9
)
Note however that testing "/?" or "-?" strings won't work with that trick (FOR loops don't like the ? meta character).
For that purpose, just add the line: if "%1"=="/?" goto help on top of the block (see the ':help' label inside the for loop ?)
Note too that this syntax won't work (it is just completely ignored and code won't be executed) with batch files under TCC.EXE (the Take Command interpreter, either full or lite edition) but in that case just use their syntax with their .OR. and .AND. keywords.
Hope this helps.
If your conditions are checking for specific values of a variable, you might be able to set it up like a CASE statement. I had a need to check if the TYPE was an individual member or a group (or all).
Note: labels are case insensitive.
If any of the conditions are true (if TYPE==ALL or TYPE==GROUP1 or TYPE==GROUP2), then the code block executes, otherwise execution skips over the block.
goto :TYPE_EQ_%TYPE% 2>NUL
if %ERRORLEVEL% neq 0 goto :END_CASE_TYPE
:TYPE_EQ_ALL
:TYPE_EQ_GROUP1
:TYPE_EQ_GROUP2
rem do what you need
echo GROUP: %TYPE%
:END_CASE_TYPE
I don't like Mehrdad's Electrical Engineering (digital electronics) approach. While accurate, with software engineering, the idea, as indicated by the OP, is to make things simpler to figure out. Nested if statements add Complexity (McCabe). Adding extra NOTs doesn't help.
My solution is a little odd if you don't know the goto-label/error set-up, but it's a flat structure that is roughly set up like an if-statement with several OR'd conditions that are not to hard to decipher.
AND:
IF <COND1> IF <COND2> ACTION
OR:
(SET _=) & (IF <COND1> (SET _= ) ELSE IF <COND2> (SET _= )) & IF DEFINED _ ACTION
For implementing OR this way, you do need command extensions.
As long as command extensions are enabled, you can use compare-operators.
This is directly pasted from "help if":
If Command Extensions are enabled IF changes as follows:
IF [/I] string1 compare-op string2 command
IF CMDEXTVERSION number command
IF DEFINED variable command
where compare-op may be one of:
EQU - equal
NEQ - not equal
LSS - less than
LEQ - less than or equal
GTR - greater than
GEQ - greater than or equal
and the /I switch, if specified, says to do case insensitive string
compares. The /I switch can also be used on the string1==string2 form
of IF. These comparisons are generic, in that if both string1 and
string2 are both comprised of all numeric digits, then the strings are
converted to numbers and a numeric comparison is performed.

How do I disable warnings in lisp (sbcl)

How do I disable all warnings in sbcl? The extra output is rather annoying.
After much faffing about
and slogging through documentation written by people who are apparently allergic to simple concrete examples
(which seems to be most documentation for most things)
I think all you need to do to disable all warnings
is add this line in your .sbclrc file:
(declaim (sb-ext:muffle-conditions cl:warning))
To disable only style-warnings, it's:
(declaim (sb-ext:muffle-conditions cl:style-warning))
I tried to disable specifically the warning that comes up if you enter eg (setq x 1) at a fresh REPL
; in: SETQ X
; (SETQ X 1)
;
; caught WARNING:
; undefined variable: X
;
; compilation unit finished
; Undefined variable:
; X
; caught 1 WARNING condition
By using this:
(declaim (sb-ext:muffle-conditions sb-kernel:redefinition-warning))
but it didn't work,
(apparently redefinition-warning means something else)
and I can't find what it should be.
I guessed sb-kernel:undefined-warning
but that doesn't exist.
Using a macro
Also,
in regards #Bogatyr's answer
(using a macro to automatically run defvar)
and #spacebat's comment
(that the macro evaluated the value twice)
I have this to say:
As another newb coming across this,
I wanted to make demo showing that the macro evals twice,
and showing a version that evaluates only once.
(
I originally edited it in at the end of the question
but it was rejected because:
"This edit was intended to address the author of the post and makes no sense as an edit. It should have been written as a comment or an answer."
Well, you can't answer an answer,
but comments can't take blocks of code,
so I guess I should put it here instead?
)
original
(defmacro sq (var value)
`(progn
(defvar ,var ,value)
(setq ,var ,value)))
(sq v (princ "hi"))
side-effects: prints hihi
return value: "hi"
rewrite 2 - only evals once, always runs defvar
(defmacro sq2 (var value)
(let
((value-to-set value))
`(progn
(defvar ,var)
(setq ,var ,value-to-set))))
(sq2 v (princ "hi"))
side-effects: prints hi
return value: "hi"
rewrite 3 - same as above, but trickier to read
I used value-to-set for clarity,
but you could just use value again with no problems:
(defmacro sq3 (var value)
(let
((value value))
`(progn
(defvar ,var)
(setq ,var ,value))))
(sq3 v (princ "hi"))
rewrite 4 - only runs defvar if the variable is unbound
Running those macros will always define the variable before setting it,
so if v was already "bound" but not "defined"
(ie you had introduced it with setq)
then won't get any more error messages when you use the variable,
or reset it with setq.
Here's a version of the macro
that only runs defvar if the variable is not already bound:
(defmacro sq4 (var value)
(let
((value-to-set value))
(if (boundp var)
`(setq ,var ,value-to-set)
`(progn
(defvar ,var)
(setq ,var ,value-to-set)))))
(sq4 v (princ "hi"))
So if you use it to set a variable that is bound but not defined
it will keep giving you error messages.
(Which is maybe a good thing?
Like, for the same reason-I-don't-actually-know-why the error message exists in the first place.)
[
Also,
I tested the macro on these:
(sq4 value 1 )
(sq4 value 'value )
(sq4 value 'value-to-set )
(sq4 value 'var )
(sq4 value-to-set 1 )
(sq4 value-to-set 'value )
(sq4 value-to-set 'value-to-set )
(sq4 value-to-set 'var )
(sq4 var 1 )
(sq4 var 'value )
(sq4 var 'value-to-set )
(sq4 var 'var )
(You know, checking I hadn't screwed up and... done something weird.)
The ones where I tried to use var as a variable spewed errors.
At first I thought I had messed something up,
but it's actually just reserved for something special in SBCL(?) itself.
(defvar var) gets:
; debugger invoked on a SYMBOL-PACKAGE-LOCKED-ERROR in thread
; #<THREAD "main thread" RUNNING {AB5D0A1}>:
; Lock on package SB-DEBUG violated when globally declaring VAR SPECIAL while
; in package COMMON-LISP-USER.
; See also:
; The SBCL Manual, Node "Package Locks"
So... when in doubt, avoid using the symbol var, I guess.
]
this is what i use to muffle both compile-time and runtime (load-time) redefinition warnings:
(locally
(declare #+sbcl(sb-ext:muffle-conditions sb-kernel:redefinition-warning))
(handler-bind
(#+sbcl(sb-kernel:redefinition-warning #'muffle-warning))
;; stuff that emits redefinition-warning's
))
following this pattern you can install these handlers on superclasses like cl:style-warning to muffle all style warnings.
You can either use SB-EXT:MUFFLE-CONDITIONS as Pillsy said, the other alternative is to read through the warnings and use them to modify your code to remove the warnings. Especially if they're actually warnings (rather than, say, optimization notes).
I couldn't get SB-EXT:MUFFLE-CONDITIONS to work for the highly annoying undefined variable warning even after much googling. That warning drives me nuts when experimenting at the REPL, so I did what all the books suggest we should do: extend lisp to suit my needs/preferences!
I wrote my own setq that shut up the sbcl warnings, my first macro ever :). I'm sure there are better ways to do it but this works great for me, and it's going right into my ~/.sbclrc!
(defmacro sq (var value)
`(progn
(defvar ,var ,value)
(setq ,var ,value)))
You probably want to look at SB-EXT:MUFFLE-CONDITIONS.
If warnings are all you care about you can set:
(setf sb-ext:*muffled-warnings* 'style-warning)
This will only apply to style warnings and allow other warnings and conditions to print out. Any warning that shares the same parent will be automatically muffled.
For me (and probably others), most of the warnings were actually being piped to stdErr.
So this silenced the annoying output:
sbcl 2>/dev/null/
Alternatively, you can pipe to a file.
sbcl 2>myTempLog.txt
When starting sbcl, the problem is that at least in my configuration, alexandria spews out a tonne of method warnings and redifining warnings because of asdf, alexandria and readline, regardless of the mute solutions.
User theoski's solutions (sbcl 2>/dev/null ...) totally work to get rid of those, but at the expense of warnings that might actually be useful.
Still, I always have a repl open in a terminal as a scratch for quick hacks and experimenting, and it's a LOT nicer not seeing that avalanche when loading it up.

Resources