Search code examples
csvautocadautolisp

AutoLISP program giving inconsistent results


Software: AutoCAD 2012 (Japanese language)

System: MS Windows 7 (Japanese language)


The Situation

I have made a .LSP file which defines a new function "C:MAKEATABLE".

It asks the user to select a .CSV file and then it imports its data to the drawing file opened in AutoCAD. The .CSV file has two columns:

  1. Serial number (integer)
  2. Data (real number)

The last line of the .CSV file is "EOF".

The data imported should be such that each text entity is independent of the other, except for the fact that they are arranged in a tabular manner from the insertion point specified by the user.

Now, my problem is that whenever I load that .LSP file and call my function, the result is not always the same. Sometimes the values appear perfectly in the desired manner; but many times the values appear jumbled up. There are three types of ways in which the values appear jumbled up.

  • I tried restarting the application as well as the PC, but to no avail.
  • I have declared all the variables to be local, so that they are not interfered with.

Here is the complete code: Pastebin link also available

(defun c:makeatable ( / filename csvfile startpt data rdline digits lineno currentpt datapt datarelpt baserelpt indexbasept temp2 temp3 temp4 temp5 wide1 wide2 rowheight txtheight tempvar tmps)

    (setq filename (getfiled "Data File" "C:/Temp/drawings/" "csv" 128))    ;prompt user to open the file containing the data
    (setq csvfile (open filename "r"))                          ;open the file to read its contents
    (setq startpt (getpoint "\n Table insertion point: "))      ;prompt user to choose the insertion point

;------------;prompt user to input the parameters; if nil, default value is set;--------------------------;
;
;** This code is useful when default values are needed, so that the user doesn't have to enter them.    **;
;** If the values appear jumbled, kindly run the program again with appropriate values.         **;
;**                                                 **;


    (initget (+ 2 4))
    (if (not(setq txtheight (getreal "\n Enter Text height: ")))        
        (setq txtheight 4.0)
    )
    (princ)

    (initget (+ 2 4))
    (if (not(setq wide1 (getreal "\n Enter first column width: ")))     
        (setq wide1 15.0)
    )
    (princ)

    (initget (+ 2 4))
    (if (not(setq wide2 (getreal "\n Enter second column width: ")))        
        (setq wide2 30.0)
    )
    (princ)

    (initget (+ 2 4))
    (if (not(setq rowheight (getreal "\n Enter Row height: ")))     
        (setq rowheight 7.0)
    )
    (princ)
;----------------------------------------------------------------------------------------------------------;    

    (setq lineno 1) ;this var stores the line at which the program is currently at
    (setq digits 0) ;this var stores the (number of digits - 1) of the index

    (setq currentpt startpt)    ;initialize currentpt


;-------*------temporary variables for the arrangement of the data------*-------;

    (setq temp2  (/ (+ rowheight txtheight) 2)) 
    (setq temp3 (+ wide1 (* txtheight 2)))
    (setq temp4 (+ wide1 (/ wide2 5)))      
    (setq temp5 (- wide1 (/ wide1 20)))
    (setq tempvar (list 0 (* -1 rowheight) 0))

;-------------------------------------------------------------------------------;

    (setq datarelpt (list temp4 temp2 0))   ;these are relative points;
    (setq baserelpt (list temp5 temp2 0))

;------------------------------;while loop;-------------------------------------;

    (while (/= rdline "EOF")
        (cond   ((> lineno 9)       ;check the number of    ;
             (setq digits 1)        ;digits in the index    ;
            )
            ((> lineno 99)
              (setq digits 2)
            )
        );end cond



        (setq datapt (mapcar '+         ;these lines        ;
                currentpt       ;set the coordinates    ;
                datarelpt       ;for the data       ;
                )       ;           ;
        )

        (setq indexbasept (mapcar '+    ;these lines        ;
            currentpt       ;set the coordinates    ;
                baserelpt       ;for the index      ;
                )       ;           ;
        )

        (setq rdline (read-line csvfile))   ;read a line from the CSV file      
        (setq data (substr rdline (+ 3 digits)));extract the data from the read line    

        (setq tmp (command "STYLE" "MONO" "MONOTXT" "" "" "" "" "" ""))     ;makes the text monospace

    ;-----------------------------printing the values-----------------------;

        (command "text" datapt txtheight 0 data)    ;write the data

        (command "text" "_j" "_r" indexbasept txtheight 0 lineno)   ;write the index number
    ;-------------------------------------------------------------------;

        (setq lineno (1+ lineno))           ;increment line number

        (setq currentpt (mapcar '+      ;increment the      ;
                currentpt       ;current point      ;
                tempvar     ;coordinates        ;
                )       ;           ;
        )
    )  
;------------------------------;while loop ends;------------------------------------;

    (entdel (entlast))  ;to remove the extra index number printed at the end
    (close csvfile)     ;close the opened file
    (princ)         ;clean exit
)

I even checked the points at which the text are being inserted [using (princ datapt) and (princ indexbasept)], and found them to be alright. However, when AutoCAD creates these text objects on the screen, they occupy the same position and get jumbled up.

Kindly tell me where i might be going wrong and what should I do now.


Solution

  • My first thought is that you need to turn off osnaps before running your command.

    (setq orig-osm (getvar "osmode"))
    (command "osmode" 0)
    ... the rest of your command ...
    (command "osmode" orig-osm)
    

    Depending on your constraints I think you could also generate the table columns as mtext (multi-line text) and explode them each after creation to create separate text objects. You can use (ssget "L") to operate on the last element added to the database.