TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: V-Man on July 16, 2004, 09:27:55 AM
-
I'm working on this lisp and I'm a little stumped. This lisp works with a
dialog box (list_box)(with multiple_select option) to select 1 or more
than 1 item in the list and then pass the findings to a variable and eventually
start the (mtext) command, Ask the user mtext starting point and place
in mtext the findings from the selected list_box values.
Can someone aid me with this prob.
Thanks,
This is from Kenny's. Thanks.
(defun C:Test ()
(setq NAMES '("01Monday" "02Tuesday" "Wednesday" "Thursday""Friday" "Saturday" "Sunday"))
(setq dcl_id (load_dialog "popup.dcl"))
(if (not (new_dialog "popup" dcl_id)
)
(exit)
)
(start_list "selections")
(mapcar 'add_list NAMES)
(end_list)
(action_tile "accept"
(strcat "(getans)"
"(done_dialog) (setq userclick T)")
)
(action_tile "cancel"
"(done_dialog) (setq userclick nil)"
)
(start_dialog)
(unload_dialog dcl_id)
(if userclick
(progn
(setq SIZ (fix SIZ))
(setq SIZ (nth SIZ NAMES))
(alert (strcat "You Selected: " SIZ))
)
)
(princ)
)
This basically works great but I want it to be able to display
(i.e. In Mtext format if the user select both 01Monday & 02Tuesday
In the drawing...
01Monday
02Tuesday
2 seperate lines per entry
-
I forgot this part of the code.
(defun getans ();;get values of controls & close the dialog
(setq SIZ (atof (get_tile "selections")))
(done_dialog 0)
)
-
Okay. There are a couple of things to address with this. So here it goes.
1.) the DCL control listbox returns a couple of different things depending on multiple select, when it is actioned, by either "action_tile" or "get_tile". When multiple_select=false; then the value of the listbox is a string containing the integer relative to the selected index (i.e. "3" for the 4th item in the list) or "" (empty string) if none are selected. When multiple_select=true; then the value returns the same as above when only one item is selected, however it returns a single string with all chosen indices concatenated delimited with spaces (i.e. "1 2 3" for the 2 thru 4 items selected).
[Are you following me so far? Good...]
So what you need to do is take the value, parse out the indices, and have them refer back to your first list "NAMES".
2.) Then once you have the items of the list "NAMES" that you want, then you need to concatenate those values using a "\\P" between each to signify you want a new line.
Try that, and if you need help with the actual code, let us know...
-
Even with my routine I cannot get it to return the multiple selections.
-
Dvarino, here's a small test with a multiple_select list box:
// DCL
popup : dialog {
: list_box {
key = "selections";
multiple_select = true;
}
ok_cancel;
}
;; AutoLISP
(defun C:Test ()
(setq NAMES '("01Monday" "02Tuesday" "Wednesday"
"Thursday" "Friday" "Saturday"
"Sunday"
)
)
(setq dcl_id (load_dialog "popup.dcl"))
(if (not (new_dialog "popup" dcl_id))(exit))
(start_list "selections")
(mapcar 'add_list NAMES)
(end_list)
(action_tile "selections" "(setq strLst (setItems $value NAMES))")
(setq userclick (start_dialog))
(unload_dialog dcl_id)
(and (= 1 userclick)
(and strLst (princ strLst))
)
(princ)
)
(defun setItems (val lst / ret)
(foreach n (mapcar (function (lambda (n) (- n 48)))
(vl-remove 32 (vl-string->list val))
)
(setq ret (cons (nth n lst) ret))
)
(reverse ret)
)
It should return a list of the items that were chosen. If you don't like the MAPCAR thingie then the help files shows an alternative way of parsing the value of a multiple_select list box. It's in the section Managing Dialog Boxes -> List Boxes and Pop-up Lists -> Processing List Elements and is called MK_LIST.
-
Thanks for the help but for some reason my list is a lot larger and it does not return the selected items.
(setq agencynames '("01 Monday" "02 Tuesday" "03 Wednesday"
"04 Thursday" "05 Friday" "06 Saturday"
"07 Sunday" "xx This" "xx Does" "xx Not" "xx Work"
)
)
If you try this multiple times using different scenarios you will see that it is not reporting what was selected.
-
Wow, that was somewhat of a blooper! Sorry. I must have fallen asleep while writing that.
Did you try the MK_LIST in the help files instead?
-
The multiselect method you are instigating may not suit the functionality you are trying to develop. The list returned from the get_tile call will be sorted numerically, not in selection sequence as you may expect.
This code may be the simplest to return a list of values from the type of string returned by the multiple selection list_box.
(setq tmp "2 4 6 9")
(read (strcat "(" tmp ")")) ;; ==>> (2 4 6 9)
;;-----
The first listing attached will do what you ask for .. multiple and single selection are valid.
The second listing will do what I think you want.
The third listing is some library stuff , plus the DCL
;;; Multiple Selection
;;;
(defun c:test0718b (/ dcl_id index names
starter programpath returnlist objmtext
;;
*error* action-cancel do-something action-accept
)
;;-----
(defun *error* (msg) (kbsf:debug-simple-error msg))
(defun action-cancel (/) (princ))
(defun do-something (/)
(alert (strcat "You Selected: " returnlist))
(setq objmtext (vla-addmtext kbsg:modelspace
(vlax-3d-point '(0 0 0))
0.0
returnlist
)
)
)
(defun action-accept (/ tmp tmpstr)
(if (and (setq tmp (get_tile "selections"))
(setq tmpstr ""
returnlist (vl-string-right-trim
"\\P"
(foreach item (read (strcat "(" tmp ")"))
(setq tmpstr (strcat tmpstr (nth item names) "\\P"))
)
)
)
)
(done_dialog 101)
(done_dialog 0)
)
)
;;-----
;;-----
(setq programpath "z:\\_test\\List_box_Multiple_select\\"
names '("01 Monday" "02 Tuesday" "03 Wednesday"
"Thursday" "Friday" "Saturday"
"Sunday" "08 Day Off"
)
)
(if
(not
(new_dialog "dcl0718multiple"
(setq dcl_id (load_dialog (strcat programpath "dcl0718.dcl")))
)
)
(exit)
)
;; -- initialise
(start_list "selections")
(mapcar 'add_list names)
(end_list)
(action_tile "accept" "(action-accept)")
(setq starter (start_dialog))
;; --
(unload_dialog dcl_id)
(cond ((= starter 101) (do-something))
((<= starter 0) (action-cancel))
)
(princ)
)
;;;
;;;
;;; Selection in sequence
(defun c:test0718c (/ dcl_id names newstring
objmtext programpath starter
;;
*error* make-selection action-cancel
do-something action-accept
)
(defun *error* (msg) (kbsf:debug-simple-error msg))
(defun make-selection (val /)
(setq newstring (strcat newstring (nth (atoi val) names) "\\P"))
(set_tile "newstring" newstring )
)
(defun action-cancel (/) (princ))
(defun do-something (/)
(setq objmtext (vla-addmtext kbsg:modelspace
(vlax-3d-point '(0 0 0))
0.0
newstring
)
)
)
(defun action-accept (/ tmp tmpstr)
(if (and (/= "" newstring)
(setq newstring (vl-string-right-trim "\\P" newstring))
)
(done_dialog 101)
(done_dialog 0)
)
)
;;-----
;;-----
(setq programpath "z:\\_test\\List_box_Multiple_select\\"
names '("01 Monday" "02 Tuesday" "03 Wednesday"
"Thursday" "Friday" "Saturday"
"Sunday" "08 Day Off"
)
newstring ""
)
(if
(not
(new_dialog "dcl0718single"
(setq dcl_id (load_dialog (strcat programpath "dcl0718.dcl")))
)
)
(exit)
)
;; -- initialise
(start_list "selections")
(mapcar 'add_list names)
(end_list)
(action_tile "selections" "(make-selection $value )")
(action_tile "accept" "(action-accept)")
(setq starter (start_dialog))
;; --
(unload_dialog dcl_id)
(cond ((= starter 101) (do-something))
((<= starter 0) (action-cancel))
)
(princ)
)
LIBRARY STUFF
(vl-load-com)
(setq kbsg:debug_on t)
(or kbsg:acadapp (setq kbsg:acadapp (vlax-get-acad-object)))
(or kbsg:activedoc (setq kbsg:activedoc (vla-get-activedocument kbsg:acadapp)))
(or kbsg:modelspace (setq kbsg:modelspace (vla-get-modelspace kbsg:activedoc)))
;;;------------------------------------------------------------------
;;;------------------------------------------------------------------
;;;
(defun kbsf:debug-simple-error (msg / tmp)
;;----- Cancel any Active Commands -----------------------------
(while (< 0 (getvar "cmdactive")) (command))
(setvar "menuecho" 1)
(vla-endundomark kbsg:activedoc)
;;----- Display error message if applicable
(cond
((not msg))
((member (strcase msg t)
'("console break" "function cancelled" "quit / exit abort")
)
)
((princ (strcat "\nApplication Error: " (itoa (getvar "errno")) " :- " msg))
)
)
(setvar "errno" 0)
;;----- Display backtrace
(vl-bt)
;;----- Release Bound Activex Objects
;; --- removed
;;----- Reset System Variables from global list
;; --- removed
;;-----
(princ)
)
;;;------------------------------------------------------------------
;;;------------------------------------------------------------------
// dcl0718.dcl
dcl0718single
: dialog
{
label = "Test list_box" ;
: list_box
{
key = "selections" ;
multiple_select = false ;
}
: text
{
key = "newstring" ;
fixed_width = true ;
width = 70 ;
}
ok_cancel ;
}
dcl0718multiple
: dialog
{
label = "Test list_box" ;
: list_box
{
key = "selections" ;
multiple_select = true ;
}
ok_cancel ;
}
-
The multiselect method you are instigating may not suit the functionality you are trying to develop. The list returned from the get_tile call will be sorted numerically, not in selection sequence as you may expect.
This code may be the simplest to return a list of values from the type of string returned by the multiple selection list_box.
(setq tmp "2 4 6 9")
(read (strcat "(" tmp ")")) ;; ==>> (2 4 6 9)
;;-----
The first listing attached will do what you ask for .. multiple and single selection are valid.
The second listing will do what I think you want.
The third listing is some library stuff , plus the DCL
This is exactly what I want. Thanks for the hard work.
-
How do you make it so that it asks the use to 'pick a point' to place the Mtext in stead of it places it at 0,0??
-
Perhaps something like this :
(defun do-something (/ workpoint )
(initget 1)
(setq
workpoint (getpoint "\n Specify MText insertion point : ")
objmtext (vla-addmtext kbsg:modelspace
(vlax-3d-point workpoint)
0.0
newstring
)
)
)
-
Woops, not logged in :(
Just replace the do-something procedure with the one I posted should do the trick.
-
I get this when i run the routine.
Specify MText insertion point :
Application Error: 10 :- ActiveX Server returned an error: Parameter not
optional
Backtrace:
[0.77] (VL-BT)
[1.73] (KBSF:DEBUG-SIMPLE-ERROR "ActiveX Server returned an error: Parameter
not optional")
[2.68] (*ERROR* "ActiveX Server returned an error: Parameter not optional")
[3.63] (_call-err-hook #<SUBR @0cbb9f50 *ERROR*> "ActiveX Server returned an
error: Parameter not optional")
[4.57] (sys-error "ActiveX Server returned an error: Parameter not optional")
:ERROR-BREAK.52 nil
[5.49] (intelligent-invoke #<VLA-OBJECT IAcadModelSpace 0dc12c84> "AddMText" 1
#<variant 8197 ...> 0.0 nil)
[6.39] (#<SUBR @02674dd4 vlax-invoke-method> #<VLA-OBJECT IAcadModelSpace
0dc12c84> "AddMText" #<variant 8197 ...> 0.0 nil)
[7.31] (vla-AddMText #<VLA-OBJECT IAcadModelSpace 0dc12c84> #<variant 8197 ...>
0.0 nil)
[8.23] (DO-SOMETHING)
[9.19] (C:TESTB)
[10.15] (#<SUBR @0cbbe730 -rts_top->)
[11.12] (#<SUBR @026f2334 veval-str-body> "(C:TESTB)" T #<FILE internal>)
:CALLBACK-ENTRY.6 (:CALLBACK-ENTRY)
:ARQ-SUBR-CALLBACK.3 (nil 0)
[/list:u]
-
(setq tmp "2 4 6 9")
(read (strcat "(" tmp ")")) ;; ==>> (2 4 6 9)
That's a pearl! I'm gonna steal that, Kerry.
-
's ok, steal away Stig. Just glad I have to have something worth borrowing ..
dvarino :
[7.31] (vla-AddMText #<VLA-OBJECT IAcadModelSpace 0dc12c84> #<variant 8197 ...> 0.0 nil )
indicate to me that the string is nil.
Any chance you tried the procedure as a stand alone :D
... if so, set the newstring value as a glogal variable to the text you want to add.
-
Oh, i had another look at the error trace
[9.19] (C:TESTB)
.. means you called it from a routine.
You may have to repost the FULL routine for me to have a guess. .. seems the newstring variable is not being set , and that shouldnt happen, cause the action--accept procedure tests for its value before closing the dialog.
kwb
-
PS :
See how handy the (VL-BT) function is !!
I always use that style of error trap for testing .. it has got me out of the poo a few times now.
-
It seems to work with the single selection but the multiple selection is the one giving the error.
-
Cant fault it here .. weird
try this in the c:test0718c :
(defun do-something (/ workpoint )
(alert (strcat "Temporary Debug \n" "You Selected: " newstring)) ;; temporary Debug
(initget 1)
(setq
workpoint (getpoint "\n Specify MText insertion point : ")
objmtext (vla-addmtext kbsg:modelspace
(vlax-3d-point workpoint)
0.0
newstring
)
)
)
-
Now I get this....
Command: testb
Application Error: 10 :- bad argument type: stringp nil
Backtrace:
[0.58] (VL-BT)
[1.54] (KBSF:DEBUG-SIMPLE-ERROR "bad argument type: stringp nil")
[2.49] (*ERROR* "bad argument type: stringp nil")
[3.44] (_call-err-hook #<SUBR @0cbbc618 *ERROR*> "bad argument type: stringp
nil")
[4.38] (sys-error "bad argument type: stringp nil")
:ERROR-BREAK.33 nil
[5.30] (STRCAT "Temporary Debug \n" "You Selected: " nil)
[6.23] (DO-SOMETHING)
[7.19] (C:TESTB)
[8.15] (#<SUBR @0cbbcde8 -rts_top->)
[9.12] (#<SUBR @026f2334 veval-str-body> "(C:TESTB)" T #<FILE internal>)
:CALLBACK-ENTRY.6 (:CALLBACK-ENTRY)
:ARQ-SUBR-CALLBACK.3 (nil 0)
[/list:u]
-
ok, GOOD, it gets easier from here ..
The newstring variable is obviously the culpret. Can you post the c:TESTB function ??
-
Here you go..
(defun c:testb (/ dcl_id index names
starter programpath returnlist objmtext
;;
*error* action-cancel do-something action-accept
)
;;-----
(defun *error* (msg) (kbsf:debug-simple-error msg))
(defun action-cancel (/) (princ))
(defun do-something (/ workpoint )
(alert (strcat "Temporary Debug \n" "You Selected: " newstring)) ;; temporary Debug
(initget 1)
(setq
workpoint (getpoint "\n Specify MText insertion point : ")
objmtext (vla-addmtext kbsg:modelspace
(vlax-3d-point workpoint)
0.0
newstring
)
)
)
(defun action-accept (/ tmp tmpstr)
(if (and (setq tmp (get_tile "selections"))
(setq tmpstr ""
returnlist (vl-string-right-trim
"\\P"
(foreach item (read (strcat "(" tmp ")"))
(setq tmpstr (strcat tmpstr (nth item names) "\\P"))
)
)
)
)
(done_dialog 101)
(done_dialog 0)
)
)
;;-----
;;-----
(setq programpath "c:\\don\\download\\notes\\"
names '("01 Monday" "02 Tuesday" "03 Wednesday"
"Thursday" "Friday" "Saturday"
"Sunday" "08 Day Off"
)
)
(if
(not
(new_dialog "dcl0718multiple"
(setq dcl_id (load_dialog (strcat programpath "test5.dcl")))
)
)
(exit)
)
;; -- initialise
(start_list "selections")
(mapcar 'add_list names)
(end_list)
(action_tile "accept" "(action-accept)")
(setq starter (start_dialog))
;; --
(unload_dialog dcl_id)
(cond ((= starter 101) (do-something))
((<= starter 0) (action-cancel))
)
(princ)
)
-
In the do-something procedure for the c:testb function
replace newstring with returnlist , which is the concatenated string for that function.
regards.Kerry
-
I'm looking the the help files and I cannot find where in vlisp can you set the height of mtext items created in vlisp.
Is this possible?
-
Yes. Have a play with this.
(defun do-something (/ workpoint )
(alert (strcat "Temporary Debug \n" "You Selected: " newstring)) ;; temporary Debug
(initget 1)
(setq
workpoint (getpoint "\n Specify MText insertion point : ")
objmtext (vla-addmtext kbsg:modelspace
(vlax-3d-point workpoint)
0.0
newstring ;; or returnlist depending on module
)
)
(vla-put-Height objmtext 50.0)
)