Author Topic: write-line, wrong-line  (Read 7527 times)

0 Members and 1 Guest are viewing this topic.

daron

  • Guest
write-line, wrong-line
« on: September 22, 2004, 11:36:06 PM »
Hopefully, I've given enough here so as to not have to dish out the entire code to help everybody understand the problem I'm having and maybe receive an answer as to what to do.

Given the code below with the parameters set, why will the commented portion work just fine, yet the foreach option executes, but doesn't actually set anything in the file? I've even tried opening as "w".
Code: [Select]
(setq cvsopen (open filepath "a"))
     (foreach item filelist
 (write-line item cvsopen)
     )
     ;(write-line "P.CODE, ITEM, DESCRIPTION, F.CODE, FINISH" cvsopen)
     (close csvopen)

filelist = the list below
filepath = "C:\\My Documents\\Draw\\DESIGN\\SpecBook.csv" <-I've even tried .txt here.
Code: [Select]

list
("P.CODE, ITEM, DESCRIPTION, F.CODE, FINISH" "B, DESIGN ELEMENT B:, SPEC 1:, ,
WAY TOO MANY THINGS TO LIST" ", , SPEC 2:, , FINISH" ", , SPEC 4:, , FINISH" ",
, SPEC 5:, , FINISH" "C, ITEM, SPEC 6:, , FINISH" ", , , , " "P.CODE, ITEM,
DESCRIPTION, F.CODE, FINISH" "B, DESIGN ELEMENT B:, SPEC 1:, , WAY TOO MANY
THINGS TO LIST" ", , SPEC 2:, , FINISH" ", , SPEC 3:, , FINISH" ", , SPEC 4:, ,
FINISH" ", , SPEC 5:, , FINISH" "C, ITEM, SPEC 6:, , FINISH")

[0]"P.CODE, ITEM, DESCRIPTION, F.CODE, FINISH"
[1]"B, DESIGN ELEMENT B:, SPEC 1:, , WAY TOO MANY THINGS TO LIST"
[2]", , SPEC 2:, , FINISH"
[3]", , SPEC 3:, , FINISH"
[4]", , SPEC 4:, , FINISH"
[5]", , SPEC 5:, , FINISH"
[6]"C, ITEM, SPEC 6:, , FINISH"
[7]", , , , "

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
write-line, wrong-line
« Reply #1 on: September 22, 2004, 11:40:22 PM »
Daron I think the culprit is the fact that you are writing to a non existent file handle...

In your code you set the file handle to "newcvs" but in your write-line command you are writing to "cvsopen"
Fix that and let us know if you still are having problems...
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

daron

  • Guest
write-line, wrong-line
« Reply #2 on: September 22, 2004, 11:51:31 PM »
Fixed the above portion. GRR. I have it in two places as I'm working this out. One in the main function and the other is in a reusable function. It got a little confused. I retested as you said, and still nothing. From what is currently there, can you test it and see if you get it to work, either as a csv or txt file? I appreciate it. Keith, do you ever sleep? It's almost midnight there, isn't it?

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
write-line, wrong-line
« Reply #3 on: September 22, 2004, 11:59:40 PM »
Coded blind, but ...
Code: [Select]
(cond
    (   (null fileList)
        (princ "fileList is null.\n")
    )    
    (   (/= 'str (type filePath))
        (princ "filePath is not a string.\n")
    )    
    (   (setq handle (open filePath "a"))
        (foreach item fileList
            (write-line item handle)
        )
        (write-line "P.CODE, ITEM, DESCRIPTION, F.CODE, FINISH" handle)
        (close handle)
        (startapp "notepad.exe" filePath)
    )
    (   (princ
            (strcat
                "Could not open <"
                filePath
                "> for output."
            )
        )
    )    
)

... what happens if you run this?
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
write-line, wrong-line
« Reply #4 on: September 23, 2004, 12:06:46 AM »
Just after midnight ....

Damn you need to get some sleep...
You still have the file handles wrong ....

In one you refer to CVSOPEN as you ropen file handle and then you attempt to close CSVOPEN

Correct that and try again....
Also make sure your list of elements is properly defined. If they are defined too long within the code it will not set the var.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

daron

  • Guest
write-line, wrong-line
« Reply #5 on: September 23, 2004, 12:16:40 AM »
I thought I changed it. Oh well. It should be changed now.

What do you mean by properly defined and too long? Would it work better if I did something like:
Code: [Select]

     (foreach item filelist
(setq cvsopen (open filepath "a"))
     (write-line item cvsopen)
     (close csvopen)
     )

I'll have to try that out later.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
write-line, wrong-line
« Reply #6 on: September 23, 2004, 12:22:17 AM »
Your code is still trying to close a non-existent file handle ....

As far as the list of elements referenced by 'filelist' ... there is a strict line limit for code in a lisp file. Once that length is exceeded the string is truncated and the program will fail...
I wasmerely pointing this out so that if your list grew too long, youmight try to build the list dynamically ....i.e.
Code: [Select]

(list item-a item-b item-c)
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

daron

  • Guest
write-line, wrong-line
« Reply #7 on: September 23, 2004, 08:57:08 AM »
Okay, thanks Keith. I took what you said about the length and decided to open and close the file for each single string of text  within the while loop. I think the problem I was really having was that my function that creates the list was creating  lists containing strings within one full list and when the foreach drew out each piece it was drawing out a list and not a string. I've since removed the foreach and put it in a while loop.

Now that that's fixed, I found another problem. In selecting text objects for this file, I find that some of my text strings have commas in them. These commas need to maintain their integrity for what they are and not serve as comma delimiters. Is there a way to get the processor to differentiate true commas with delimiters or is there a file I can create similar to a csv that uses a different symbol for delimitation?

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
write-line, wrong-line
« Reply #8 on: September 23, 2004, 10:47:56 AM »
You can use the pipe symbol "|" as a delimiter, save the file as any name, open it in excel and specify the delimiter for that file ...
Or make sure you don't use spaces in your strings and save as a SDF ...

There are many options, like using a colon ":" or semicolon ";" .... it is up to you to determine which one is less likely to be used in the strings being entered.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

daron

  • Guest
write-line, wrong-line
« Reply #9 on: September 23, 2004, 12:30:40 PM »
Thanks, I used a semicolon.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
write-line, wrong-line
« Reply #10 on: September 23, 2004, 02:23:24 PM »
Oddly enough I wrote a Q&D utility for a colleague just yesterday that exports CSV data (see below). You might want to look at function (_Insert->CSV ename) which converts embedded commas (",") to Cedillas ("¸") which look comma like but don't make parsers chuck a wobbly.

Lift what might be useable for your program; HTH.

Code: [Select]
(defun c:BomOut

    ;;-----------------------------------------------------------------------
    ;;
    ;;  c:BomOut
    ;;
    ;;  Copyright © 2004 Michael Puckett. All Rights Reserved.
    ;;
    ;;-----------------------------------------------------------------------
    ;;
    ;;  Written Quick and Dirty for Greg Xxxxxxxxx
    ;;
    ;;  2004/09/22 : Original code : Michael Puckett
    ;;
    ;;-----------------------------------------------------------------------
    ;;
    ;;  If the drawing contains BOM data (attributed blocks named BOM)
    ;;  export the data to a CSV file (same name as drawing w/a ".BOM.CSV"
    ;;  extension). Data is sorted by the y cordinate of the insert.
    ;;
    ;;-----------------------------------------------------------------------

    (   /
        _SortPickSetByYCord
        _MakeExportName
        _GetTagString
        _GetChildren
        _Insert->CSV
        _Replace
        _Trim
        exportName
        handle
        ss
        i
    )

    ;;-----------------------------------------------------------------------
    ;;
    ;;  local defun (_Replace pattern newString string)
    ;;
    ;;-----------------------------------------------------------------------
    ;;
    ;;  Assumes caller is smart enough to use properly, i.e. will likely
    ;;  bomb (endless loop) if pattern and newString are the same etc. Coded
    ;;  to be fast not smart.
    ;;
    ;;-----------------------------------------------------------------------

    (defun _Replace ( pattern newString string / i )

        (while

            ;;  pattern found

            (setq i
                (vl-string-search
                    pattern
                    string
                )
            )

            ;;  replace it

            (setq string
                (vl-string-subst
                    newString
                    pattern
                    string
                    i
                )
            )

        )

        string

    )

    ;;-----------------------------------------------------------------------
    ;;
    ;;  local defun (_Trim string)
    ;;
    ;;-----------------------------------------------------------------------
    ;;
    ;;  Trim leading / trailing white space.
    ;;
    ;;-----------------------------------------------------------------------

    (defun _Trim ( string )
        (vl-string-trim
            " \t\n\r"
            string
        )
    )

    ;;-----------------------------------------------------------------------
    ;;
    ;;  local defun (_GetChildren ename)
    ;;
    ;;-----------------------------------------------------------------------
    ;;
    ;;  Find all the child entities of the entity. Typically this would be
    ;;  attribute entities that are are children of a parent block insert,
    ;;  though polyline vertices would also be returned (not used in that
    ;;  context in this program).
    ;;
    ;;-----------------------------------------------------------------------

    (defun _GetChildren ( ename / result )
        (if (assoc 66 (entget ename))
            (reverse
                (while
                    (/= "SEQEND"
                        (cdr
                            (assoc 0
                                (entget
                                    (setq ename
                                        (entnext ename)
                                    )
                                )
                            )
                        )
                    )
                    (setq result
                        (cons
                            ename
                            result
                        )
                    )
                )
            )
        )
    )

    ;;-----------------------------------------------------------------------
    ;;
    ;;  local defun (_SortPickSetByYCord ss)
    ;;
    ;;-----------------------------------------------------------------------
    ;;
    ;;  Sort a selection set by the y cordinate of the entity data.
    ;;
    ;;-----------------------------------------------------------------------

    (defun _SortPickSetByYCord ( ss / i ename lst result )

        (cond

            (   (eq 'pickset (type ss))

                (repeat (setq i (sslength ss))
                    (setq lst
                        (cons
                            (cons
                                (setq ename (ssname ss (setq i (1- i))))
                                (caddr (assoc 10 (entget ename)))
                            )
                            lst
                        )
                    )
                )

                (setq lst
                    (mapcar 'car
                        (vl-sort
                            lst
                            (function (lambda (a b)(> (cdr a) (cdr b))))
                        )
                    )
                )

                (setq result (ssadd))

                (foreach ename lst
                    (ssadd ename result)
                )
            )
        )

        result

    )

    ;;-----------------------------------------------------------------------
    ;;
    ;;  local defun (_MakeExportName)
    ;;
    ;;-----------------------------------------------------------------------
    ;;
    ;;  Using the current drawings path and name construct a suitable
    ;;  file name for exporting the BOM (CSV) data.
    ;;
    ;;-----------------------------------------------------------------------

    (defun _MakeExportName ()
        (strcat
            (getvar "dwgprefix")
            (vl-filename-base (getvar "dwgname"))
            ".BOM.CSV"
        )
    )

    ;;-----------------------------------------------------------------------
    ;;
    ;;  local defun (_GetTagString ename)
    ;;
    ;;-----------------------------------------------------------------------
    ;;
    ;;  Get an attribute entity's tag string.
    ;;
    ;;  Assumes caller will provide valid ename for an attribute entity.
    ;;
    ;;-----------------------------------------------------------------------

    (defun _GetTagString ( ename )
        (cdr
            (assoc 1
                (entget ename)
            )
        )
    )

    ;;-----------------------------------------------------------------------
    ;;
    ;;  local defun (_Insert->CSV ename)
    ;;
    ;;-----------------------------------------------------------------------
    ;;
    ;;  Convert a block's attribute data to a single CSV stream. Ensures
    ;;  raw data contains no embedded commas (converts them to Cedillas
    ;;  which look like a commas ("¸") but won't confuse parsers) as well
    ;;  as removing leading / trailing white space.
    ;;
    ;;  Assumes caller will provide valid ename for a block entity.
    ;;
    ;;-----------------------------------------------------------------------

    (defun _Insert->CSV ( ename / tagStrings )
        (if
            (setq tagStrings
                (mapcar
                    (function
                        (lambda (tagString)
                            (_Trim
                                (_Replace "," (chr 184)
                                    tagString
                                )
                            )
                        )
                    )
                    (mapcar '_GetTagString
                        (_GetChildren ename)
                    )
                )
            )
            (apply 'strcat
                (cons
                    (car tagStrings)
                    (mapcar
                        (function
                            (lambda (tagString)
                                (strcat "," tagString)
                            )
                        )
                        (cdr tagStrings)
                    )
                )
            )
            ""
        )
    )

    ;;-----------------------------------------------------------------------
    ;;
    ;;  'Main'
    ;;
    ;;-----------------------------------------------------------------------

    (cond

        ;;  we have data and succesfully opened the export file

        (   (and

                (setq ss
                    (_SortPickSetByYCord
                        (ssget "x"
                           '(   (00 . "insert")
                                (02 . "bom")
                                (66 . 1)
                            )
                        )
                    )
                )

                (setq handle
                    (open
                        (setq exportName (_MakeExportName))
                        "w"
                    )
                )

            )

            ;;  walk the selection set and export formatted data

            (setq i -1)

            (repeat (sslength ss)
                (princ
                    (strcat
                        (_Insert->CSV (ssname ss (setq i (1+ i))))
                        "\n"
                    )
                    handle
                )
            )

            (close handle)

            ;;  we're done

            (princ
                (strcat
                    "Data written to <"
                    exportName
                    ">.\n"
                )
            )
        )

        ;;  no data to process

        (   (null ss)

            (princ "Drawing has no BOM data.\n")

        )

        ;;  error opening the export file

        (   (and (null handle) exportName)

            (princ
                (strcat
                    "Could not open <"
                    exportName
                    "> for output.\n"
                )
            )
        )
    )

    (princ)

)


Cheers,

MP.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

sinc

  • Guest
write-line, wrong-line
« Reply #11 on: September 23, 2004, 03:02:07 PM »
Quote
You might want to look at function (_Insert->CSV ename) which converts embedded commas (",") to Cedillas ("¸") which look comma like but don't make parsers chuck a wobbly.

What exactly do you mean?

If something knows how to parse a CSV file, changing the comman to a cedilla will break it.  That comma is pretty important.  If you want to include a comma in data, it should be enclosed in quotes.  For example, the following line has three fields:

bubba,"1,000",5

The format you describe, using cedillas instead of commas, will cause something that expects a CSV (like Excel) to "chuck a wobbly"...

Some applications/languages let you specify this character, called a record separator or field separator, so you can change it from a comma to whatever you like (i.e., Perl).  In that case, what you're describing works great.  But it depends on how you want to use the data.  (Actually, Excel will let you import data like this, but it expects files with .csv extentions to use commas, and only commas, as the field seperator.)

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
write-line, wrong-line
« Reply #12 on: September 23, 2004, 03:39:42 PM »
Quote from: sinc
Quote
You might want to look at function (_Insert->CSV ename) which converts embedded commas (",") to Cedillas ("¸") which look comma like but don't make parsers chuck a wobbly.

What exactly do you mean?

If something knows how to parse a CSV file, changing the comman to a cedilla will break it.  That comma is pretty important.  If you want to include a comma in data, it should be enclosed in quotes.  For example, the following line has three fields:

bubba,"1,000",5

The format you describe, using cedillas instead of commas, will cause something that expects a CSV (like Excel) to "chuck a wobbly"...

Some applications/languages let you specify this character, called a record separator or field separator, so you can change it from a comma to whatever you like (i.e., Perl).  In that case, what you're describing works great.  But it depends on how you want to use the data.  (Actually, Excel will let you import data like this, but it expects files with .csv extentions to use commas, and only commas, as the field seperator.)

You're misrepresenting what my code does, and what it does not do. It ensures individual field values do not contain comma(s); it does not break the CSV format. In fact it was written so that the CSV format would be useable for attribute resident data (which might contain commas).

For example, if there were 3 attribute values for a single block instance like:
"Some data"
"Some more data"
"And yet, more data"

It would be exported to the CSV file as
Some data,Some more data,And yet[Cedilla] more data

But I thank you for making me clarify and I apologise if my post was nebulous.

Cheers.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

daron

  • Guest
write-line, wrong-line
« Reply #13 on: September 24, 2004, 10:41:20 AM »
Thanks MP, that is some clean code. I originally wrote mine where the user has to select each object individually, just so I can get something working. I was then going to go back and try to figure out how to use ssget to read each value based off of the x,y coordinates of the text or mtext. I cannot use attributes in this case, so yes, from the start it's more complicated. What would be cool is if someone or I could write something in c++ or VB to make mtext attributes based off a fixed width that reacts to the height of mattributes above to maintain integrity and be able to be used with LT and full autocad. At any rate, I think there is a lot I can use of your code. The cedilla is definately one of them and your sortpicksetbycoord should come in handy. Thanks

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
write-line, wrong-line
« Reply #14 on: September 24, 2004, 11:27:16 AM »
Thank you Daron; nice of you to say and hope it helps.

In hindsight I guess I could have written it all activex flavour instead of using dxf coding, which would mean it could be used in objectdbx contexts. Let me know if that's something you could use and I'll rewrite it.

The mtext thing is a significant challenge and you're not the first to have want for a mtext based attribute (if I understood you correctly). I'm surprised the desk hasn't anted up yet. A reactor based simple attribute fake could be produced, though I'm not a fan of reactor based apps -- there are so many these days that they tend to make an AutoCAD session a little fragile (esp. when used in concert with 3rd party apps like AutoPlant etc.).

Anyway, offer stands on the rewrite; just let me know.

Cheers.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst