Author Topic: write-line, wrong-line  (Read 7523 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

daron

  • Guest
write-line, wrong-line
« Reply #15 on: September 24, 2004, 11:42:29 AM »
Isn't Autocad already full of reactors: i.e. most double click properties? I know I'm not the first to think about mtatts, but it is something I might have more of a need for now than ever. We are restructuring our spec book, which gets rewritten for each job. The designer that is developing the new spec book wants to take it out of excel, which it's currently in (she's cool), and put it in autocad. Attributes won't work because the info is too dynamic, so she's considering mtext. Our project managers are in the habit of copying what's in the excel spec book and creating a shiplist with it. If they don't have the excel version, they have to type out the entire thing. I know how frustrating that can be, so I wanted to make a program that would export the specs itno excel for the PM's.

If you want to covert it to activex, I wouldn't mind, but I've noticed that if objects don't get released, my computer at work slows down to a snails pace. It's probably best to stay away from ActiveX at least on my end.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
write-line, wrong-line
« Reply #16 on: September 24, 2004, 12:30:20 PM »
Quote from: Daron
Isn't Autocad already full of reactors?

Yup, that's my point :)

Quote from: Daron
I know I'm not the first to think about mtatts, but it is something I might have more of a need for now than ever. We are restructuring our spec book, which gets rewritten for each job. The designer that is developing the new spec book wants to take it out of excel, which it's currently in (she's cool), and put it in autocad. Attributes won't work because the info is too dynamic, so she's considering mtext. Our project managers are in the habit of copying what's in the excel spec book and creating a shiplist with it. If they don't have the excel version, they have to type out the entire thing. I know how frustrating that can be, so I wanted to make a program that would export the specs itno excel for the PM's.

As much fun as it is designing and coding systems like this have you considered any pre-canned third party apps, like
    http://www.dotsoft.com/word2cad.htm,
    http://www.dotsoft.com/autocell.htm,
    http://www.dotsoft.com/xl2cad.htm
    [/list:u]?
    Quote from: Daron
    If you want to covert it to activex, I wouldn't mind, but I've noticed that if objects don't get released, my computer at work slows down to a snails pace. It's probably best to stay away from ActiveX at least on my end.

    That kind of slowdown is typical of the improper release of objects created with vlax-create-object. I see no need for the use of said function, unless you're going ObjectDBX. But having said that, any ObjectDBX code would be ancillary [external] to my little function -- as I see it you'd just pass the document object to my function, it would scan for the intelligence and then be done with it. The caller would be responsible for creating, passing and releasing the document object. How's that for side stepping responsibility? :)
    Engineering Technologist • CAD Automation Practitioner
    Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
    cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

    MP

    • Seagull
    • Posts: 17750
    • Have thousands of dwgs to process? Contact me.
    write-line, wrong-line
    « Reply #17 on: September 24, 2004, 02:04:42 PM »
    Converted program to activex variant, please see this.
    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 #18 on: September 25, 2004, 03:46:25 PM »
    Thanks MP.

    MP

    • Seagull
    • Posts: 17750
    • Have thousands of dwgs to process? Contact me.
    write-line, wrong-line
    « Reply #19 on: September 25, 2004, 04:23:35 PM »
    You're welcome Daron. :)
    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 #20 on: September 27, 2004, 09:17:14 PM »
    Quote from: MP

    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

    Ah, OK.  But still, whatever reads your pseudo-csv file needs to replace cedillas with commas.

    Anything that can parse a CSV file will be able to read your file if you instead export it as:
    Code: [Select]
    Some data,Some more data,"And yet, more data"
    If you want to include data that includes double-quotes, you need to enclose the entire field in double-quotes, and then put two quotes back-to-back where you want a single double quote to appear.  For example, the following includes two data items,
    'Storm Drain' and '36" RCP':
    Code: [Select]
    Storm Drain,"36"" RCP"
    This is the definition of the CSV format.  Anything that can parse a CSV file can parse data formatted in this manner without any issues.