Jump to content

write and read text files


saim

Recommended Posts

I'd like to make a lisp that allows cad to communicate with excell. I do know there is a way to write and read .csv files and I'll look into that later, but I really like the versatility of text files.

So I'd like to know how it works I already found this thread in which an example code is written (I'll post it here, below). What I would really like you guys to help me is:

- To point out in the help file where I can find info about the "open" command, because I could not find it by myself

found it!!! Is there a way to remove this thread? I'll repost if my answers are not found, but it seems that I can go on by myself, for now...

- Teach me, if possible, how to allow the user to choose the directory in which the file will be saved (hopefully, it'll be in the help file)

Here's the code (but keep reading, I'll ask for some more stuff, too)

;ronjonp, sorry for kidnaping your code and thanks for writing it
(defun c:pts2file (/ pts e file openf)
 (vl-load-com)
 (if (and (setq e (car (entsel)))
      (= (cdr (assoc 0 (entget e))) "LWPOLYLINE")
      (setq pts (mapcar 'cdr
                (vl-remove-if-not
                  (function (lambda (pt) (= (car pt) 10)))
                  (entget e)
                )
            )
      )
      (setq file (strcat (getvar 'dwgprefix)
                 (getvar 'dwgname)
                 "__points.txt"
             )
      )
      (setq openf (open file "w"))
     )
   (progn
     (foreach pt pts
   (write-line (vl-prin1-to-string pt) openf)
     )
     (close openf)
   )
 )
 (princ file)
 (princ)
)

 

Ok. That should get the project info to excell, where the user is going to change some of it and export to another text file (actually, user is going to put a completely different set of information into that file).

Then, of course, I'll need to get the info from that other text file and convert to drawing. How should I get that done?

I mean, how should I tell AutoCad that this info is the coordinate of the point, that info is the layer in which I want the line to be drawn with, etc

 

In the final form of the program, I hope to completely get rid of excell, but I need to take small steps in order to understand what I'm doing...

Link to comment
Share on other sites

  • 4 months later...

I've returned to this issue and can't seem to make sense of the errors I'm getting. What I want, at this point, is to read the first line of the text file.

(Later, I'll want to read each line, then separate the values in a line the draw a polyline based on such values and, finally, draw a whole drawing based on the output of an excell calculation. But that's much later)

 

I think the problem may be with opening the file. Addressing the file this way worked when I tried to WRITE one.

But when I ask AutoCad for the value of the file, it gives me a "nil" value. Let me show the codes so far:

 

(defun c:fstattempt()
(setq dflt (strcat (getvar 'dwgprefix) (substr (getvar 'dwgname) 1 (- (strlen (getvar 'dwgname)) 4)) )) ; give the file a default name
(setq flname (getfiled "esse é o título da cx de diálogo" dflt "txt" ) ; use function getfileid to allow user to search for the file
(setq arq (open flname r)) ; open file for reading and stores it in a variable
(read-line arq) ; read a line from the open file
(close arq) ; close file
)
(defun c:scnattempt()
(setq dflt (strcat (getvar 'dwgprefix) "valores vindos do excell.txt")) ; thats the file name, it does exist in the drawing folder
(princ dflt) ; show onscreen the file name, for debugging
(setq arq (open dflt r)) ; open file for reading and stores it in a variable
(setq lineread (read-line arq)) ; read a line from the open file, store it in a variable
(close arq) ; close file
)

 

I've tried to put the single line that opens the file on the prompt (after running those attempts a few times, so the file names would be on the designed variables) and I kept receiving the "bad argument type" error, so I think that's where the problem is.

Command: (setq arq (open dflt r))

; error: bad argument type: stringp nil

 

But I can't make sense out of it. It SHOULD be opened that way, right?

Help!

 

By the way...

The variable returned by th "getfileid" function is just the name of the file, with extension (in the case, "valores vindos do excell.txt" - which would translate as "values from excell.txt"). It doesn't have the full path name. Souldn't it have the full path name? Can autocad still open such file without the full path? If the path is not the same as the drawing path, how can I get the user to tell it to autocad?

Link to comment
Share on other sites

Maybe try :

 

 (if    (setq flname (getfiled ... blablabla))     (setq arg (open flname "r"))   )  

 

note the "r"

 

also :

 

 (setq input (read-line arg)) 

Link to comment
Share on other sites

Second rlx

 

Open file to read "R"

Open file to write "W"

 

Have a look at Lee-mac's read csv file in conjunction with read a file.

 

; example of reading multiple lines
; thanks to Lee-mac for this defun
; www.lee-mac.com
(defun _csv->lst ( str / pos )
(if (setq pos (vl-string-position 44 str))
   (cons (substr str 1 pos) (_csv->lst (substr str (+ pos 2))))
   (list str)
   )
)

(setq fname (open "P:\\Autodesk\\lisp\\civilcad6layercodes.txt" "r"))
(while (setq layercode (read-line fname)) ; it will stop after last line is read
(setq lst (_csv->lst layercode)) ; list of all the csv values
.......... your code
)

Link to comment
Share on other sites

note the "r"
Awesome! I did use quotation marks on the lisp that writes info, but it has been so long that I forgot about it - and didn't notice, when reading it for reference into writing the "read" lisp.

Using it made the line get readed, so thank you a lot! :)

I still don't know how to go for the next line but I haven't searched for it yet. I'll let you know when I get stucked again (there is a long path ahead, it'll happen, no doubt).

 

Have a look at Lee-mac's read csv file in conjunction with read a file.
I didn't realise there was a standard character (the comma) to separate list values. I'm using the semicolon because here in Brazil, Excell (and everithing else except autoCad) uses the comma as a decimal separator. I hadn't realised the problem I'll sure have when trying to move those values from one program to the other.

Sure, I'll take a little time to change those values by code but maybe you guys can show me some standard method for doing so.

Btw, is it always a comma separator on such files or can the semicolon be used as well?

Link to comment
Share on other sites

Our document control system also uses | for separator. CSV stands for comma separated value so for us (Europeans) using a . makes more sense in our numbers than a comma , period! haha

 

 

gr. Rlx

Link to comment
Share on other sites

Have a look at this tiny bit of code

(ascii (getstring))

copy to command line and enter ,

 

You will see 44 appear

Do again and type ; and 59 appears

change the 44 in Lees's code to 59 and ; will work.

 

This is the Ascii code for any key presed see (chr x) also for inverse

Link to comment
Share on other sites

Thanks, guys.

The problem is that half of the programs involved (cad) uses the "." as a decimal separator and the other half (excell) uses ",".

There is no escape, I will have to handle that. The research is about when should it be handled - while in VBA or in LISP.

Bigal, that piece of info allowed me the choice. Before that, I'd just have to use VBA. Now, I can find the easier path (I think it is still VBA, excell does have a few useful transformations, I just have to look for them).

I'll manage it (I hope), don't worry.

 

Bigal, I'm still chewing Lee-mac's code (recursive codes are a pain to me) but I just can't find the part the code says "go to the next line". Does it do it when I reach the end of the line? If so, using "read-line" -n- times will return -n- lines? (I prefer the loop, just trying to understand)

Link to comment
Share on other sites

In lisp you can't read a certain line number directly so you have read them all or until you find (through a test) the one you need. You find a certain string for example. Else you just read until the end is reached. So you open the file by creating a file-pointer 'setq fp open filename for reading' and after that you can read every line until you reached the last line. Every 'read-line' gives you a result , a string. But if your appie has read all the lines read-line returns nil and so you know you have reached the end of the file.

 

 

 
 (if (and (findfile filename) (setq fp (open filename "R")))
   (while (setq data (read-line fp))
      (do-your-stuff)
   )
   (princ "Unable to read from file")
 )

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...