MR_Zeroeffect Posted June 15, 2009 Posted June 15, 2009 Hello, I have been struggeling with this problem for two days now so any help would be very, very much apreciated. Unfourtunatly Im a beginner in both Lisp and Autocad but not in VBA. I have written a function in VBA that let the user select a LWPOLYLINE and then the function will convert the LWPOLYLINE to a "polyline" (Changing all the arcs to several straight lines). Since I want to confirm to the standard behaviour of Autocad commands, I have written some Lisp code where the user first selects the polyline, and then can choose how many lines every arc will convert to. My problem is how to get the selected polyline and the settings over to vba. I have really tried, and probably is my problem a result of my bad knowledge of autocad and lisp. To get the users variables over to vba I read about using the USER1-5 variable, but It didn't work (When using ThisDrawing.GetVariable("USERS1") the return was empty). So now Im writing the settings to a file, and then reads the file into vba. It looks a bit awkyard to me, but it works. But how can I get the selected polyline to VBA? Please help me. And please be as clear as possible if you know the answer. This is the code in VBA that I want to change to something that gets the polyline that the user selected within the lisp code: ThisDrawing.Utility.GetEntity oEnt, vPick, vbCr & vbCr & "Select object:" Sorry for writing so much... But I really really need to get this working, and Im so close. Thanks for taking your time! This is my Lisp-code for letting the user select an object: (defun C:conv () ;Clears vars (setq mmtCalcMethod nil) (setq mmtSectorAngle -1) (setq mmtNrOfSectors -1) (princ "\nconv: Version 1.2") (setq again nil) (setq p-ent nil) (while (not p-ent) (setq p-ent (car (entsel "\nSelect a polyline:"))) (if (not p-ent) (prompt "\nNo object selected. ") ;_ end of prompt (progn ;(if (and (/= (dxf 0 p-ent) "POLYLINE") (/= (dxf 0 p-ent) "LWPOLYLINE") ) ;_ end of and (if (/= (dxf 0 p-ent) "LWPOLYLINE") (progn (prompt "\nNot a LWPOLYLINE, select again:" ) ;_ end of prompt (setq p-ent nil) ) ; progn ) ;_ end of if ) ;_ end of progn ) ;_ end of if ) ;_ end of while And this is the rest of the code where the user select which calculation method to use... ;Number of vectors or degrees ;Read users last setting! (setq mmtCalcMethod (getcfg "AppData/MY_Stuff/mmtCalcMethod")) (if ( = mmtCalcMethod nil ) (setq mmtCalcMethod "A") ) ;The user can use S or A ;0 = NIL is ok to return (initget 0 "S A") (setq Tmp (getkword (STRCAT "\nCalculate number of points for each arc using [Angle/Sector] <" (princ mmtCalcMethod) ">: "))) ;The users selection was stored in Tmp and now we assign Tmp to mmtCalcMethod (if Tmp (setq mmtCalcMethod Tmp) ) ;Save the setting in the "Autocad" register (setcfg "AppData/MY_Stuff/mmtCalcMethod" mmtCalcMethod) ;Depending on the users previous selection... (if (= mmtCalcMethod "S") ( progn ;Read settings from the "Autocadregistret" (setq mmtSectorAngle (getcfg "AppData/MY_Stuff/mmtSectorAngle")) ; ; (if (and ( /= mmtSectorAngle nil ) ( /= mmtSectorAngle "" )) (setq mmtSectorAngle (ATOI mmtSectorAngle)) (setq mmtSectorAngle 5)) ; (setq Tmp (getint (STRCAT "\nEnter sector angle <" (ITOA mmtSectorAngle) ">: "))) ; (if Tmp (setq mmtSectorAngle Tmp) ) ; (setcfg "AppData/MY_Stuff/mmtSectorAngle" (ITOA mmtSectorAngle)) ) ( progn ; (setq mmtNrOfSectors (getcfg "AppData/MY_Stuff/mmtNrOfSectors")) ; ; (if (and ( /= mmtNrOfSectors nil ) ( /= mmtNrOfSectors "" )) (setq mmtNrOfSectors (ATOI mmtNrOfSectors)) (setq mmtNrOfSectors 10)) ; (setq Tmp (getint (STRCAT "\nEnter number of segments for each arc <" (ITOA mmtNrOfSectors) ">: "))) ; (if Tmp (setq mmtNrOfSectors Tmp) ) ; (setcfg "AppData/MY_Stuff/mmtNrOfSectors" (ITOA mmtNrOfSectors)) ) ) And this is the final code where the settings are written to a file ******************************************************************* ; Code to get the data to VBA ******************************************************************* ; The "USER1" code below never worked. ; The variables were always empty inside VBA ; (VBA CODE) ; Dim var1, var2 As Variant ; var1 = ThisDrawing.GetVariable("USERS1") ; var2 = ThisDrawing.GetVariable("USERS2") ; (/VBA CODE) ;(setq USERS1 mmtCalcMethod) ;(setq USERS2 (ITOA mmtSectorAngle)) ;(setq USERS2 (ITOA mmtNrOfSectors)) ;(setq USERS4 p-ent) ; Instead we are now saving the settings to a textfile (setq tempfile (open "C:\\Program Files\\AutoCAD Map 3D 2009\\temp.txt" "w")) (write-line (STRCAT "mmtCalcMethod: " (princ mmtCalcMethod)) tempfile) (write-line (STRCAT "mmtSectorAngle: " (princ (ITOA mmtSectorAngle))) tempfile) (write-line (STRCAT "mmtNrOfSectors: " (princ (ITOA mmtNrOfSectors))) tempfile) ;THIS IS MY MAJOR PROBLEM RIGHT NOW!!!! ;WHAT SHOULD I DO? PLEASE HELP!!! ;HOW CAN I GET THE SELECTED POLYLINE INTO VBA?? ;(write-line (STRCAT "p-ent: " p-ent) tempfile) (close tempfile) (setq current_osnap_mode (getvar "osmode")) (setvar "osmode" 0) (RunVbaMacro "C:/Program Files/AutoCAD Map 3D 2009/code.dvb" "module_mmtconv.mmtconv") (setvar "osmode" current_osnap_mode) (princ) ;Exit quietly! );defun ; ******************************************************************* ; DXF ******************************************************************* (defun dxf (code ename) (cdr (assoc code (entget ename))) ) ;_ end of dxf Quote
SEANT Posted June 15, 2009 Posted June 15, 2009 I don’t think the task necessarily requires two APIs. As a matter of fact, a good case could be made that what you already have was the trickiest part of a VBA only solution. Some creative use of ThisDrawing.Utility.InitializeUserInput, ThisDrawing.Utility.GetInteger, and maybe ThisDrawing. ActiveSelectionSet could have done the rest. However, given that you already have much of the necessary code, both AutoLisp and VBA can retrieve entities by the entity’s handle. It should be possible to transfer info via “User” variables (perhaps not the most efficient method). Check the spelling, especially the type identifier USERS1, USERI1, etc. Quote
MR_Zeroeffect Posted June 16, 2009 Author Posted June 16, 2009 I don’t think the task necessarily requires two APIs. As a matter of fact, a good case could be made that what you already have was the trickiest part of a VBA only solution. Some creative use of ThisDrawing.Utility.InitializeUserInput, ThisDrawing.Utility.GetInteger, and maybe ThisDrawing. ActiveSelectionSet could have done the rest. However, given that you already have much of the necessary code, both AutoLisp and VBA can retrieve entities by the entity’s handle. It should be possible to transfer info via “User” variables (perhaps not the most efficient method). Check the spelling, especially the type identifier USERS1, USERI1, etc. Thank you very much for your answer. I deleted the Lisp code and rewrote it using ThisDrawing.Utility.InitializeUserInput, ThisDrawing.Utility.GetInteger and so on. Finally it works! But I still have a question. It doesn't look exactly like the Autocad-functions Im used to.... Every time I ask for the users input (using for example ThisDrawing.Utility.GetInteger) the word "Command:" is echoed to the screen after the user has enterd a value. Pretty annoying... For example: Select LWPolyline to convert: Command: Calculate number of points for each arc using [Angle/Sector] S Command: Enter number of segments for each arc 3 Command: Delete original polyline [Yes/No] Command: Regenerating model. My code looks like this: kwordList = "A S" ThisDrawing.Utility.InitializeUserInput 0, kwordList 'Reads from the register vCalcMethod = GetSetting("MyAcad", "mmtconv", "vCalcMethod", "A") 'Ask user how to convert the polyline returnString = ThisDrawing.Utility.GetKeyword(vbCrLf & "Calculate number of points for each arc using [Angle/Sector] <" & vCalcMethod & "> ") 'ESC aborts If Err <> 0 Then Err.Clear Exit Sub End If 'If not <ENTER> use users value... If (returnString <> "") Then vCalcMethod = returnString End If 'Saves the settings in the register SaveSetting "MyAcad", "mmtconv", "vCalcMethod", vCalcMethod I retried using the USERS1 variables, but still couldn't get it to work. I use blockletters and USERS1 for String? When debuggin in Visual Lisp I can se that USERS1 contains data, but I can't get the data into VBA... Strange... And just for curiosity, I would very much like to know how to write a objects handle to a file from LISP, and then read it back in using VBA. And ofcourse how to select the object when having this handle as a string! If anyone know the answer, please let me know! I was trying to write the handle to a file from LISP using the following code, but with no luck... (setq p-ent (car (entsel "\nSelect a polyline:"))) (write-line (STRCAT "p-ent: " p-ent) tempfile) Any help, tips or suggestions is as usually highly appreciated! Best regards, Marcus Quote
VVA Posted June 16, 2009 Posted June 16, 2009 Look This Vlax.cls for VBA and AutoLISP apps. VBA code with AutoLISP Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.