MarcoW Posted August 19, 2010 Posted August 19, 2010 Hellow partners in crime, I read about writing variable-values to an external document (Afralisp). That I can understand, a bit... But I am wondering if this is possible, an example: ; in a lisp file this code is used (setq variable1 100 variable2 200 variable3 300) Writing them to an external file is possible, but what if the variables are to be modified: ; in a lisp file this code is used (setq variable1 (getreal "How many?") variable2 (getreal "How many?") variable3 (getreal "How many?")) So the external file should be opened, the variable "variable1" should be looked up, and its value should be set to the new value. Kinda replacement. While typing this I know it is possible, of course, but I have no clue. Any help is much appreciated, as always. Quote
MSasu Posted August 19, 2010 Posted August 19, 2010 Please keep in mind that by opening a text file in "w" (write) mode, his previous content will be lost at CLOSE statement call. I suggest you to open the file, read his content into a list of dotted pairs, update required entries (by SUBST and ASSOC) and record all back to the file. Regards, Quote
Tharwat Posted August 19, 2010 Posted August 19, 2010 I read about writing variable-values to an external document (Afralisp). That I can understand, a bit... But I am wondering if this is possible, an example: ; in a lisp file this code is used (setq variable1 100 variable2 200 variable3 300) Writing them to an external file is possible, but what if the variables are to be modified: ; in a lisp file this code is used (setq variable1 (getreal "How many?") variable2 (getreal "How many?") variable3 (getreal "How many?")) So the external file should be opened, the variable "variable1" should be looked up, and its value should be set to the new value. Kinda replacement. If I got you well, You need to see the values that you entered first to be shown in the second example. It yes, the following example could help you as best as you want. (or Values (setq Values 1000.0)) (if (setq Input (getdist (strcat "\nHow Many ["(rtos Values 2 2)"] : " ))) (setq Values Input)) Regards, Tharwat Quote
MarcoW Posted August 19, 2010 Author Posted August 19, 2010 Please keep in mind that by opening a text file in "w" (write) mode, his previous content will be lost at CLOSE statement call.I suggest you to open the file, read his content into a list of dotted pairs, update required entries (by SUBST and ASSOC) and record all back to the file. Regards, If I got you well, You need to see the values that you entered first to be shown in the second example. It yes, the following example could help you as best as you want. (or Values (setq Values 1000.0)) (if (setq Input (getdist (strcat "\nHow Many ["(rtos Values 2 2)"] : " ))) (setq Values Input)) Regards, Tharwat Thanks guys, for the replies. But I seem to be unclear, sorry for that. I will do my best to explain better, I will give an example so do not worry about it being useless. It is for learning process only. Example: I want to make a lisp that saves a few names. So at some point AutoCAD prompts me for the first name. No need to show the name wich is stored. So I enter "Marco". In the external file should be this: Name1 = Marco or maybe (Name1 . "Marco") At another point it promps me to give the second name. So I enter "John". My external file should look like this: (Name1 . "Marco") (Name2 . "John") Now.... at some point I decide to have a new name for John. So AutoCAD prompts me for the second name. I enter "Charles". My external file should look like this: (Name1 . "Marco") (Name2 . "Charles") In the end my external file will carry several values. I will have to be able to look up the very variable and replace the value. Sorry for my bad explain. Quote
jammie Posted August 19, 2010 Posted August 19, 2010 Hi MacroW You may may have to consider a method for parsing each line by storing the info in a textfile as (Name1 . "Marco") (Name2 . "Charles") Is it feasible to simplify your text file for this example? Maybe Name1 Marco Name2 John Using read-line, when the required index found, eg. Name2 the next line that is read will be its corresponding value ie John Quote
Tharwat Posted August 19, 2010 Posted August 19, 2010 The following codes work good ..... This would write data to file (defun c:try (/ fname) (setq fname (open "c:/try.txt" "w")) (write-line "Marco" fname) (write-line "Name2" fname) (close fname) (princ) ) And this insert data through text. (defun c:txts (/ fname aa bb) (setq fname (open "c:/try.txt" "r")) (setq aa (read-line fname)) (setq bb (read-line fname)) (command "_.text" pause "" "" aa "") (command "_.text" pause "" "" bb "") (close fnamea) (princ) ) Regards, Tharwat Quote
David Bethel Posted August 19, 2010 Posted August 19, 2010 I'd suggest that format your external file as an Autolisp list call: Name1.txt (setq marcodat '( ("Name1" . "Marco") ("Name2" . "John") )) Then you easily load the file and extract the data: [b][color=BLACK]([/color][/b]load [color=#2f4f4f]"name1.txt"[/color][b][color=BLACK])[/color][/b] Now you have a list of dotted string pairs that can be easily manipulated and then be overwritten to the external file. If you need to have access to a variable . string , you can: [b][color=BLACK]([/color][/b]load [color=#2f4f4f]"name1.txt"[/color][b][color=BLACK])[/color][/b] [b][color=BLACK]([/color][/b]foreach n marcodat [b][color=FUCHSIA]([/color][/b]set [b][color=NAVY]([/color][/b]read [b][color=MAROON]([/color][/b]car n[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]cdr n[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][b][color=BLACK])[/color][/b] -David Quote
Se7en Posted August 19, 2010 Posted August 19, 2010 One question: Who will be accessing this file. If its you or other lisp developers then i suggest the dotted pair style but if your users will be in this file i recommend a more user friendly style like: var1=value var2=value ... parsing, stripping, reformatting a string can be done with a few lines of code if need be; dont let that be a deciding factor. Quote
JohnM Posted August 19, 2010 Posted August 19, 2010 When working with text files to save data you really need to think ahead and determine how you will use the saved data later in your program. This will tell you how you should format the data being written to the file. Formatting your data into a list or even a list of list is better in my opinion Also create 2 subroutines that you can call and pass data to and retrieve data 1 sub to write to a file passing 3 arguments (filename write_append data) Example call: (mywritefile c:/myfile.txt “w” ‘(data data data)) to write data Change the “w” to an “a” to append data to a file 1 sub to read a file passing 1 argument (filename) Example call: (setq returndata (myreadfile c:/myfile.txt)) Side note: create a lisp file for all your typical subroutines so you don’t have to write them over and over and just include it with your project. Make all your subroutines where they receive arguments so you can call them and pass data to them. Quote
Se7en Posted August 19, 2010 Posted August 19, 2010 When working with text files to save data you really need to think ahead and determine how you will use the saved data later in your program. This will tell you how you should format the data being written to the file. I agree with the thinking ahead part but how the string will be used in a program should be a very small concern over whom will be using the data. For example consider this piece of information: !Sghr! hr sgd `mrvdq sn xntq ptdrshnm. Can you use that (My application can use it quite easily)? Quote
MarcoW Posted August 20, 2010 Author Posted August 20, 2010 Thanks all for the replies, they are good for learning! I'd suggest that format your external file as an Autolisp list call: Name1.txt (setq marcodat '( ("Name1" . "Marco") ("Name2" . "John") )) Then you easily load the file and extract the data: [b][color=black]([/color][/b]load [color=#2f4f4f]"name1.txt"[/color][b][color=black])[/color][/b] Now you have a list of dotted string pairs that can be easily manipulated and then be overwritten to the external file. If you need to have access to a variable . string , you can: [b][color=black]([/color][/b]load [color=#2f4f4f]"name1.txt"[/color][b][color=black])[/color][/b] [b][color=black]([/color][/b]foreach n marcodat [b][color=fuchsia]([/color][/b]set [b][color=navy]([/color][/b]read [b][color=maroon]([/color][/b]car n[b][color=maroon])[/color][/b][b][color=navy])[/color][/b] [b][color=navy]([/color][/b]cdr n[b][color=navy])[/color][/b][b][color=fuchsia])[/color][/b][b][color=black])[/color][/b] -David David, thanks, this is the way I want to go. The external file is not to be seen by other users. It is just a file to store variables (user dependent settings) that can be changed by the user. Not in the *.txt file itself but by prompt & answer. The MyFile.txt will always be there. In case not, the function "openfile" will create one if I am right but that aside. The forech idea is great, in combination with the load function. I never did that. Here is my example code as far as I came: (defun c:test (/ ExternalFile) (if (setq ExternalFile (findfile "c:/MyFile.txt")) (progn (load ExternalFile) (foreach n marcodat (set (read (car n)) (cdr n)) ) ) ;end progn (progn (setq Name1 "Undefined_01" Name2 "Undefined_02" Name3 "Undefined_03" Name4 "Undefined_04" ) ; end setq ) ;end progn ) ; end if (alert (strcat "Variable Name1 is set:" Name1)) (alert (strcat "Variable Name2 is set:" Name2)) (alert (strcat "Variable Name3 is set:" Name3)) (alert (strcat "Variable Name4 is set:" Name4)) (princ) ) ; end defun (princ) (defun c:modify ( / ) (setq Name1 (getstring "What name to attach to variable Name1 ? :") ;Name2 (getstring "What name to attach to variable Name2 ? :") ;Name3 (getstring "What name to attach to variable Name3 ? :") ;Name4 (getstring "What name to attach to variable Name4 ? :") ) ;| here comes the code to put the new names in the file MyFile.txt. so if Name1 would be answered with "James_01" my external file looks like this: (setq marcodat '( ("Name1" . "James_01") ("Name2" . "John_02") ("Name3" . "Paul_03") ("Name4" . "Ringo_04") )) |; ;|«Visual LISP© Format Options» (120 2 2 2 nil "Ende von " 100 9 0 0 0 T T nil T) ;*** DO NOT add text below the comment! ***|; Any further help is very welcome. Quote
JohnM Posted August 20, 2010 Posted August 20, 2010 Just curious, what are you trying to achieve in your program? If you have a list of names that you want to display and edit and save the best way is to use a dialog box with a list box a text box and some buttons for adding, deleting, moving up & down in the list and saving. This way everything is on the screen at one time instead of trying to use the command line. If you just need to save some variable settings so the next time you use the program they are used as defaults then use the read from file and write to file methods Quote
MarcoW Posted August 20, 2010 Author Posted August 20, 2010 Just curious, what are you trying to achieve in your program?If you have a list of names that you want to display and edit and save the best way is to use a dialog box with a list box a text box and some buttons for adding, deleting, moving up & down in the list and saving. This way everything is on the screen at one time instead of trying to use the command line. If you just need to save some variable settings so the next time you use the program they are used as defaults then use the read from file and write to file methods If you just need to save some variable settings so the next time you use the program they are used as defaults then use the read from file and write to file methods Yes this is my goal. In the end a user doesn't have to do anything, if there are made changes to a specific variable it will be automatically written into the external file. SO what about my code, have any help? Quote
David Bethel Posted August 20, 2010 Posted August 20, 2010 A cheat that I use from time to time, is to create a temporary block and insert with attributes that contains the data ( tagname = variable_name ) and then call DDATTE as the dialog box. Then read the attribute values back in. I also have programs that create dcl boxes on the fly. In both cases, they leave a footprint ( either a block that has to be purged or a dcl file on the hard drive ) Good Luck -David Quote
JohnM Posted August 20, 2010 Posted August 20, 2010 MarcoW are you saying that you want to use a dialog box? If so do you know DCL? I looked at the code you posted and it didn’t work for me, maybe I missed something But I would do it different Quote
MarcoW Posted August 20, 2010 Author Posted August 20, 2010 No I do not want to use DCL. Also there is nu user input involved. I am sorry to say but my explain / request is not very clear I notice. I have been thinking of how to explain further... I want to be able to pass a value (of a variable) into an external document. Or, reverse, get it out of there and read it into the current session. Like I said before in my lisp, like a list of names... I am only interested in the way how to read, write and replace a value. Because it is for learning I do not need DCL now. The code I posted does not work, obviously, because there is a part missing. Quote
JohnM Posted August 20, 2010 Posted August 20, 2010 Lets start with something simple just to get an idea on one-way it could be done The example below does the following Looks for a file If the file is found read the data and set variables If the file is not found set some defaults Ask questions If the user hits enter set the variable to the last used input Make a list of the variables Turn the list into a string to write it to a file Write the data string file Now next time the program is used the new data will be displayed at the end of the questions (defun c:test (/ ff opfl rl strval relval intval str rel int lst savelst) (setq ff (findfile "c:/MyFile.txt"));_look for file (if ff ;;_if file is found found (progn (setq opfl (open ff "r"));_open to read ;_read line and use the read function to ger rid of the quotes from whenb it is saved (setq rl (read(read-line opfl))) (close opfl);_close file ;;;_retrive data using nth (setq strval (nth 0 rl)) (setq relval (nth 1 rl)) (setq intval (nth 2 rl)) );_progn ;;;_if file is not found set some defaults (progn (setq strval "HELLO") (setq relval 3.14) (setq intval 99) );_progn );_if ;_get some info and show the user the last setting so if they just hit ente that is what it will be (setq str (getstring (strcat"\nEnter Something: " "<" strval ">"))) (if (= str "")(setq str strval));_if user hits enter transfer last used to variable (setq rel (getreal (strcat"\nEnter A Real Number: " "<" (rtos relval) ">")));_use rtos function to convert real to string (if (not rel)(setq rel relval));_if user hits enter transfer last used to variable (setq int (getint (strcat"\nEnter A interger: " "<" (itoa intval) ">")));_use itoa to convert interger to string (if (not int)(setq int intval));_if user hits enter transfer last used to variable (setq lst (list str rel int));_make a list of data (setq savelst (vl-prin1-to-string lst));_now convert list to a string to be saved (setq opfl (open "c:/MyFile.txt" "w"));_open file for writting (write-line savelst opfl);_write data string (close opfl);_close file );_defun Quote
MarcoW Posted August 21, 2010 Author Posted August 21, 2010 JohnM, I really appreciate your efforts to help me but we are going in the wrong direction. There is so much information in this threat already that I am concerned being overloaded: I need to read, test and understand all of it. I have other options as well to experiment with. Maybe an odd reply from me, but if you don't mind, let's call it a day for now. Thank you again for the help as provided. 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.