Author Topic: Write from vlisp to excel file  (Read 14967 times)

0 Members and 1 Guest are viewing this topic.

Amsterdammed

  • Guest
Write from vlisp to excel file
« on: October 31, 2005, 11:37:17 AM »
Hello Hotshots,

I need for an application in Vlisp to write to an excel file. Till now I make a text file as exchange medium, so I write the data out vlisp into the txt file and let Vba read from this file and write it to Excel.

Now I wonder if there is a more elegant way to do so, till now I only read from an excel file into vlisp straight away, but can I also write to excel straight out of vlisp?

Thanks in Advance,

Bernd 

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Write from vlisp to excel file
« Reply #1 on: October 31, 2005, 12:16:26 PM »
I just write a .csv (comma delimited ) file of the data, excel will open it no problems. Granted my data is usually not very sophisticated.
TheSwamp.org  (serving the CAD community since 2003)

TR

  • Guest
Re: Write from vlisp to excel file
« Reply #2 on: October 31, 2005, 04:05:04 PM »
Check out typelib.lsp in C:\Program Files\Autodesk\Acadm 2005\Sample\VisualLISP. It's set up for Word but you might be able to apply the concepts to Excel.

Amsterdammed

  • Guest
Re: Write from vlisp to excel file
« Reply #3 on: October 31, 2005, 04:28:50 PM »
Tim, i work with R2002

Mark, how do you get the delimilter work, i tried what you said and get it all in one cell

Bernd

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Write from vlisp to excel file
« Reply #4 on: October 31, 2005, 04:45:26 PM »
You could use a simple type library import to have all of the VBA available in VLisp ... although you would need to have Excel loaded on the computer you want to run the program on.

Code: [Select]
(vlax-import-type-library
    :tlb-filename "c:/Program Files/Microsoft Office/Office/EXCEL9.olb"
    :methods-prefix "xlm-"
    :properties-prefix "xlp-"
    :constants-prefix "xlc-"
  )

Just change the path to your installation of Excel and make sure you have the correct version of the file listed (EXCEL9.olb is for Excel 2000).
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

TR

  • Guest
Re: Write from vlisp to excel file
« Reply #5 on: October 31, 2005, 05:02:41 PM »
Bernd:

That lisp file should still be in the samples/visualisp directory of your installation. It explains the typelib import that Keith suggested.

~Tim

Amsterdammed

  • Guest
Re: Write from vlisp to excel file
« Reply #6 on: October 31, 2005, 07:45:22 PM »
Keith,

I got the sample for word running, I got the lib for excel imported.

I got a lot of functions in the Apropos Window. But unfortunately they ring no bell at all. I’m not very familiar with VBA.

Is there any simple function to select a range in an excel file and write a string to this cell?

Thanks in Advance,

Bernd

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Write from vlisp to excel file
« Reply #7 on: October 31, 2005, 10:32:14 PM »
Ok, you will have to change the paths, you will also need to create an empty xls file (Test.xls) with at least a single sheet called "Sheet1"

Quick and dirty ... actually very dirty ... it needs some real cleanup to make it into a production piece ... let this serve as an example only

Read the comments for a better understanding
Code: [Select]
(defun c:test()
  ;Load the com object
  (vl-load-com)
  ;get the Excel object ... it should be running already
  (setq xlapp (vlax-get-object "Excel.Application"))
  ;import the object type library
  (vlax-import-type-library
    :tlb-filename "D:/Program Files/Microsoft Office/Office/EXCEL9.olb"
    :methods-prefix "xlm-"
    :properties-prefix "xlp-"
    :constants-prefix "xlc-"
  )
  ;ensure excel is visible
  (xlp-put-visible xlapp acTrue)
  ;open the template file
  (vlax-invoke-method (vlax-get-property xlapp 'Workbooks) 'Open "Test1")
  ;get the workbooks collection
  (setq xlworkbooks (vlax-get xlapp "Workbooks"))
  ;get the workbook corresponding to our template
  (setq xlworkbook (vla-open xlworkbooks "Test1"))
  ;get the sheets from our workbook
  (setq xlsheets (vlax-get xlworkbook "Sheets"))
  ;grab Sheet1 from the sheets collection
  (setq xlsheet (vlax-get-property xlsheets 'Item "Sheet1"))
  ;activate Sheet1
  (vlax-invoke-method xlsheet 'Activate)
  ;select the cell to use
  (setq xlcell (xlp-get-Range xlsheet "D5"))
  ;put the text in the cell
  (xlp-put-FormulaR1C1 xlcell "This is a test")
  ;release the excel application
  (vlax-release-object xlapp)
)
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

Amsterdammed

  • Guest
Re: Write from vlisp to excel file
« Reply #8 on: November 01, 2005, 07:05:18 AM »
Keith

Your are the bomb.

Thanks a lot. That is exactly what I needed to start from. Great.   :-)
Made my day.

Thanks, Bernd

Amsterdammed

  • Guest
Re: Write from vlisp to excel file
« Reply #9 on: November 01, 2005, 07:14:12 AM »
Koz,
That is the error MSG i get when i try to run your example code.

Quote
no function definition: VLXLS-APP-NEW

Bernd

kozmos

  • Newt
  • Posts: 114
Re: Write from vlisp to excel file
« Reply #10 on: November 01, 2005, 09:03:42 AM »
you can find source code for VLXLS-APP-NEW in VLXLS.LSP
KozMos Inc.

whdjr

  • Guest
Re: Write from vlisp to excel file
« Reply #11 on: November 01, 2005, 10:00:18 AM »
Here is a lisp file I got from David Stein's website when it was up.

This will be your guide to understanding the process of linking with excel.

Excel examples:
Code: [Select]
(vl-load-com)
;;;*************************************************************************
;;; MODULE: DSX-TypeLib-Excel                                               
;;; DESCRIPTION: Determines which Version of Excel you have                 
;;;*************************************************************************
(defun DSX-TypeLib-Excel ( / sysdrv tlb)
  (setq sysdrv (getenv "systemdrive"))
  (cond
    ( (setq tlb (findfile (strcat sysdrv "\\Program Files\\Microsoft Office\\Office\\Excel8.olb")))
      tlb
    )
    ( (setq tlb (findfile (strcat sysdrv "\\Program Files\\Microsoft Office\\Office\\Excel9.olb")))
      tlb
    )
    ( (setq tlb (findfile (strcat sysdrv "\\Program Files\\Microsoft Office\\Office\\Excel10.olb")))
      tlb
    )
    ( (setq tlb (findfile (strcat sysdrv "\\Program Files\\Microsoft Office\\Office\\Excel.exe")))
      tlb
    )
    ( (setq tlb (findfile (strcat sysdrv "\\Program Files\\Microsoft Office\\Office10\\Excel.exe")))
      tlb
    )
  )
)
;;;*************************************************************************
;;; MODULE: DSX-Load-TypeLib-Excel                                         
;;; DESCRIPTION: Loads the Type Library for Excel                           
;;;*************************************************************************
(defun DSX-Load-TypeLib-Excel ( / tlbfile tlbver out)
  (cond
    ( (null msxl-xl24HourClock)
      (if (setq tlbfile (DSX-TypeLib-Excel))
        (progn
          (setq tlbver (substr (vl-filename-base tlbfile) 6))
          (cond
            ( (= tlbver "9")
              (princ "\nInitializing Microsoft Excel 2000...") )
            ( (= tlbver "8")
              (princ "\nInitializing Microsoft Excel 97...") )
            ( (= (vl-filename-base tlbfile) "Excel.exe")
              (princ "\nInitializing Microsoft Excel XP...")
            )
          )
          (vlax-import-type-library
            :tlb-filename tlbfile
            :methods-prefix "msxl-"
            :properties-prefix "msxl-"
            :constants-prefix "msxl-"
          )
          (if msxl-xl24HourClock (setq out T))
        )
      )
    )
    ( T (setq out T) )
  )
  out
)
;;; Note: <dmode> is either "SHOW" or "HIDE" depending upon whether
;;; you want the Excel session to be accessible to the user directly.
(defun DSX-Open-Excel-New (dmode / appsession)
  (princ "\nCreating new Excel Spreadsheet file...")
  (cond
    ( (setq appsession (vlax-create-object "Excel.Application"))
      (vlax-invoke-method (vlax-get-property appsession 'WorkBooks) 'Add)
      (if (= (strcase dmode) "SHOW")
        (vla-put-visible appsession 1)
        (vla-put-visible appsession 0)
      )
    )
  )
  appsession
)
;;; Note: <xfile> is the fully-qualified filename to be opened,
;;; <dmode> is either "SHOW" or "HIDE" depending upon whether
;;; you want the Excel session to be accessible to the user directly.
(defun DSX-Open-Excel-Exist (xfile dmode / appsession)
  (princ "\nOpening Excel Spreadsheet file...")
  (cond
    ( (setq fn (findfile xfile))
      (cond
        ( (setq appsession (vlax-get-or-create-object "Excel.Application"))
          (vlax-invoke-method
            (vlax-get-property appsession 'WorkBooks)
            'Open fn
          )
          (if (= (strcase dmode) "SHOW")
            (vla-put-visible appsession 1)
            (vla-put-visible appsession 0)
          )
        )
      )
    )
    ( T (alert (strcat "\nCannot locate source file: " xfile)) )
  )
  appsession
)
 



;;; Get cell object relative to range using <relrow> and <relcol>

(defun DSX-Excel-Get-Cell (rng relrow relcol)
  (vlax-variant-value
    (msxl-get-item (msxl-get-cells rng)
      (vlax-make-variant relrow)
      (vlax-make-variant relcol)
    )
  )
)

;;; Return value of contents in cell (row, col)

(defun DSX-Excel-Get-CellValue (row col)
  (vlax-variant-value
    (msxl-get-value
      (DSX-Excel-Get-Cell
        (msxl-get-ActiveSheet xlapp)
        row col
      )
    )
  )
)
 


;;;*************************************************************************
;;; MODULE: DSX-Excel-Get-RowValues
;;; DESCRIPTION: Returns a list of cell values within a given row
;;; ARGS: row-number(int), startcol, num-cells
;;; EXAMPLE: (DSX-Excel-Get-RowValues 3 1 20) get first 20 values in row 3
;;;*************************************************************************

(defun DSX-Excel-Get-RowValues (row startcol numcells / next out)
  (setq next startcol)
  (repeat numcells
    (setq out
      (if out
        (append out (list (DSX-Excel-Get-CellValue row next))); row x col
        (list (DSX-Excel-Get-CellValue row next)); row x col
      )
      next (1+ next)
    )
  ); repeat
  out
)

;;;*************************************************************************
;;; MODULE: DSX-Excel-Get-ColumnValues
;;; DESCRIPTION: Returns a list of cell values within a given column
;;; ARGS: column-number(int), startrow, num-cells
;;; EXAMPLE: (DSX-Excel-Get-ColumnValues 2 1 20) get top-20 entries in column 2 ("B")
;;;*************************************************************************
(defun DSX-Excel-Get-ColumnValues (col startrow numcells / next out)
  (setq next startrow)
  (repeat numcells
    (setq out
      (if out
        (append out (list (DSX-Excel-Get-CellValue next col)))
        (list (DSX-Excel-Get-CellValue next col))
      )
      next (1+ next)
    )
  ); repeat
  out
)

;;;*************************************************************************
;;; MODULE: DSX-Excel-GetRangeValues-ByRows
;;; DESCRIPTION: Get range values in row order and return as nested lists
;;; ARGS: startrow, startcol, num-rows, num-cols
;;; EXAMPLE: (DSX-Excel-GetRangeValues-ByRows 1 1 5 10) get range values from 1A to 5J where each sublist is one row
;;;*************************************************************************

(defun DSX-Excel-GetRangeValues-ByRows (startrow startcol numrows numcols / nextrow rowlst outlst)
  (setq nextrow startrow)
  (repeat numrows
    (setq rowlst (DSX-Excel-Get-RowValues nextrow startcol numcols)
          outlst (if outlst (append outlst (list rowlst)) (list rowlst))
         nextrow (1+ nextrow)
    )
  )
  outlst
)

;;;*************************************************************************
;;; MODULE: DSX-Excel-GetRangeValues-ByCols
;;; DESCRIPTION: Get range values in column order and return as nested lists
;;; ARGS: startrow, startcol, num-rows, num-cols
;;; EXAMPLE: (DSX-Excel-GetRangeValues-ByCols 1 1 5 10) get range values from 1A to 5J where each sublist is one column
;;;*************************************************************************

(defun DSX-Excel-GetRangeValues-ByCols (startrow startcol numrows numcols / nextrow nextcol collst outlst)
  (setq nextcol startcol)
  (repeat numcols
    (setq collst (DSX-Excel-Get-ColumnValues nextcol startrow numrows)
          outlst (if outlst (append outlst (list collst)) (list collst))
         nextcol (1+ nextcol)
    )
  )
  outlst
)



;;;*************************************************************************
;;; MODULE: DSX-Excel-Put-ColumnList
;;; DESCRIPTION: Write each list member to a column (startcol) starting at row (startrow)
;;; ARGS: list, startrow, startcol
;;; EXAMPLE: (DSX-Excel-Put-ColumnList '("A" "B" "C") 1 2) puts members into cells (1,B) (2,B) (3,B) respectively
;;;*************************************************************************

(defun DSX-Excel-Put-ColumnList (lst startrow startcol)
  (foreach itm lst
    (msxl-put-value
      (DSX-Excel-Get-Cell range startrow startcol)
      itm
    )
    (setq startrow (1+ startrow))
  ); repeat
)

;;;*************************************************************************
;;; MODULE: DSX-Excel-Put-RowList
;;; DESCRIPTION: Write each list member to row (startrow) starting at column (startcol)
;;; ARGS: list, startrow, startcol
;;; EXAMPLE: (DSX-Excel-Put-RowList '("A" "B" "C") 2 1) puts members into cells (1,B) (1,C) (1,D) respectively
;;;*************************************************************************

(defun DSX-Excel-Put-RowList (lst startrow startcol)
  (foreach itm lst
    (msxl-put-value
      (DSX-Excel-Get-Cell range startrow startcol)
      itm
    )
    (setq startcol (1+ startcol))
  ); repeat



;;;*************************************************************************
;;; MODULE: DSX-Excel-Put-CellColor
;;; DESCRIPTION: Applies fill-color to specified cell
;;; ARGS: row, column, color (integer)
;;; EXAMPLE: (DSX-Excel-Put-CellColor 1 1 14) apply color #14 to cell (1,A)
;;;*************************************************************************

(defun DSX-Excel-Put-CellColor (row col intcol / rng)
  (setq rng (DSX-Excel-Get-Cell (msxl-get-ActiveSheet xlapp) row col))
  (msxl-put-colorindex (msxl-get-interior rng) intcol)
)


;;;*************************************************************************
;;; MODULE: DSX-Excel-Put-RowCellsColor
;;; DESCRIPTION: Applies fill-color to a row of cells
;;; ARGS: startrow, startcol, num-cols, color (integer)
;;; EXAMPLE: (DSX-Excel-Put-RowCellsColor 1 1 5 14) Start at row=1 col=1 repeat for 5 columns using color #14
;;;*************************************************************************

(defun DSX-Excel-Put-RowCellsColor (startrow startcol cols intcol / next)
  (setq next startcol)
  (repeat cols
    (DSX-Excel-Put-CellColor startrow next intcol)
    (setq next (1+ next))
  )
)

;;;*************************************************************************
;;; MODULE: DSX-Excel-Put-ColumnCellsColor
;;; DESCRIPTION: Change fill color in a column of cells
;;; ARGS: startrow, startcol, num-rows, color (integer)
;;; EXAMPLE: (DSX-Excel-Put-ColumnCellsColor 1 1 5 14) Start at row=1 col=1 repeat for 5 rows using color #14
;;;*************************************************************************

(defun DSX-Excel-Put-ColumnCellsColor (startrow startcol rows intcol / next)
  (setq next startrow)
  (repeat rows
    (DSX-Excel-Put-CellColor next startcol intcol)
    (setq next (1+ next))
  )
)
;;;*************************************************************************
;;; MODULE: DSX-Excel-RangeAutoFit
;;; DESCRIPTION: Applies Auto-Fit to columns within active range
;;; ARGS: active-sheet (object)
;;; EXAMPLE: (DSX-Excel-RangeAutoFit myxlws)
;;;*************************************************************************

(defun DSX-Excel-RangeAutoFit (active-sheet)
  (vlax-invoke-method
    (vlax-get-property
      (vlax-get-property
        (vlax-get-property active-sheet 'UsedRange)
        'Cells
      )
      'Columns
    )
    'AutoFit
  )
)
;;;
;;;
;;;
(defun w-Excel-Get-Current-Column (activesheet / widths cnt num activerange)
  (setq activerange
(vlax-get-property
   (vlax-get-property
     (vlax-get-property activesheet 'UsedRange)
     'Cells
   )
   'Columns
)
  )
  (setq widths '(22 16 14 35))
  (setq cnt (msxl-get-count activerange))
  (setq num 0)
  (repeat cnt
    (w-Excel-Put-ColumnWidth activerange (nth num widths) num)
    (w-Excel-Put-Borders (msxl-get-Borders activerange) 1)
    (setq activerange (msxl-get-next activerange))
    (setq num (1+ num))
  )
)
;;;;
;;;;
;;;;
(defun w-Excel-Put-ColumnWidth (currentcolumn val num / ind)
  (msxl-put-columnwidth
    currentcolumn
    (vlax-make-variant val vlax-vbDouble)
  )
  (setq ind (cond ((= num 0) 2)
  ((= num 1) 3)
  ((= num 2) 3)
  ((= num 3) 2)
    )
  )
  (msxl-put-horizontalalignment
    (msxl-get-EntireColumn currentcolumn)
    (vlax-make-variant ind vlax-vbLong)
  )
)
;;;*************************************************************************
;;; MODULE: DSX-Excel-Put-ColumnCellsColor
;;; DESCRIPTION: Change fill color in a column of cells
;;; ARGS: startrow, startcol, num-rows, color (integer)
;;; EXAMPLE: (DSX-Excel-Put-ColumnCellsColor 1 1 5 14) Start at row=1 col=1 repeat for 5 rows using color #14
;;;*************************************************************************

(defun w-Excel-Put-Borders (borders num / newLineStyle newValue)
  (setq newLineStyle
(msxl-put-LineStyle
   borders
   (vlax-make-variant num vlax-vbLong)
)
  )
)
;;;*************************************************************************
;;; MODULE: C:GETXLREGION                                                   
;;; DESCRIPTION: THIS IS THE MAIN PROGRAM                                   
;;;*************************************************************************
(defun C:GETXLREGION
  ( / xlapp xlfile ready tlbfile ash range xlist)
  (cond
    ( (DSX-Load-TypeLib-Excel)
      (cond
        ( (setq xlfile
            (getfiled "Excel Spreadsheet File"
              (if G$XFILE G$XFILE "") "XLS" 8
          ))
          (setq G$XFILE xlfile)
          (cond
            ( (setq xlapp (DSX-Open-Excel-Exist xlfile "HIDE"))
              (setq ash   (msxl-Get-ActiveSheet xlapp))
              (setq range (msxl-Get-ActiveCell  xlapp))

              ;;; fetch data starting at row=2 column=1 and get
              ;;; the next 68 rows, 6 columns each

              (setq xlist (DSX-Excel-GetRangeValues-ByRows 2 1 68 6))

              ;;; Print out each sublist to see what you got...
              (foreach mbr xlist (princ mbr) (terpri))
              (setq xlist nil)
              (DSX-Excel-Quit xlapp)
              (gc); forced garbage collection after closing Excel!
            )
            ( T (princ "\nFailed to start application session.") )
          )
        )
      )
    )
    ( T (alert "Failed to initialize type library for Excel 97...") )
  )
  (princ)
)
--------------------------------------------------------------------------------

;;;*************************************************************************
;;; MODULE: DSX-Excel-Quit
;;; DESCRIPTION: Quit and close Excel session (app)
;;; ARGS: app (session object)
;;; EXAMPLE: (DSX-Excel-Quit xlapp)
;;;*************************************************************************

(defun DSX-Excel-Quit (appsession)
  (cond
    ( (not (vlax-object-released-p appsession))
      (vlax-invoke-method appsession 'QUIT)
      (vlax-release-object appsession)
    )
  )
)


;;;*************************************************************************
;;; MODULE: DSX-Excel-Kill
;;; DESCRIPTION: Forces any open Excel sessions to be closed
;;; ARGS: none
;;; EXAMPLE: (DSX-Excel-Kill)
;;;*************************************************************************

(defun DSX-Excel-Kill ( / eo)
  (while (setq eo (vlax-get-object "Excel.Application"))
    (DSX-Excel-Quit eo)
    (vlax-release-object eo)
    (setq eo nil)
    (gc)(gc);; even this doesn't always kill the damn thing!
  )
)

Amsterdammed

  • Guest
Re: Write from vlisp to excel file
« Reply #12 on: November 01, 2005, 10:48:31 AM »
Thanks Will,

That is a great code to have!!!
 Bernd:lol:

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: Write from vlisp to excel file
« Reply #13 on: November 01, 2005, 11:50:04 AM »
Mark, how do you get the delimilter work, i tried what you said and get it all in one cell

Bernd

Maybe something like this.
Code: [Select]
(defun ListToCSV (fo lst header)
  ;;; takes a list [lst], open file handle [fo] and header [header]
  ;;; (optional) a string and writes the list to the file in comma
  ;;; delimited format.

  ;;; example
  ;;; (setq fo (open "c:/cd_file.csv" "w"))
  ;;; (setq pt_list (list "23" 100.25 200.2))
  ;;; (ListToCSV fo pt_list "Point,Northing,Easting")
  ;;; (close fo)

  (defun Item2Str (lst)
    ;;; convert INT or REAL to string
    (mapcar
      '(lambda (item)
(cond
   ((= (type item) 'INT)
    (itoa item))
   ((= (type item) 'REAL)
    (rtos item 2 4)); you will probably want to change this
   (T item)
   )
)
      lst
      )
    )

  (if header
    (write-line header fo)
    )

  ;; make sure we have nothing but strings in the list
  (setq lst (Item2Str lst))

  ;; write it!!
  (write-line
    (apply 'strcat
   (mapcar
     '(lambda (item)
(if (/= (last lst) item)
  (strcat item ",")
  (strcat item)
  )
)
     lst
     )
   )
    fo
    )
  (princ)
  )

TheSwamp.org  (serving the CAD community since 2003)

Fatty

  • Guest
Re: Write from vlisp to excel file
« Reply #14 on: November 01, 2005, 12:57:25 PM »
Hi Bernd

I don't know how it will work for you
Anyway you can try it

Thank you

Fatty


Code: [Select]
;written by Eduard (edited by Fatty)
;(last listing on the page):
;http://www.autocad.ru/cgi-bin/f1/board.cgi?t=9958Dp
;; ;;
(defun write-exc (coor_list / fd fname)
  (setq fname (getfiled "Enter file name to write coordinates" "" "xls" 1))
  (setq fd (open fname "w"))
  (foreach i coor_list
    (princ (strcat (rtos (car i) 2 1) "\t"
   (rtos (cadr i) 2 1)"\t"
   (rtos (caddr i) 2 1) "\n")
   fd)
)

  (close fd)
    (princ)
  )
;CaLL: (write-exc coor_list)

;; ;;

(defun read-exc (/ coors fn fname ln)
(if (setq fname
(getfiled "Select a .XLS File" (getvar "dwgprefix") "xls" 8))
(progn
(setq fn (open (findfile fname) "r"))
(while (setq ln (read-line fn))
(setq coors (cons (read (strcat "(" ln ")")) coors)))
(close fn)))
(reverse coors)
)
;CaLL:(read-exc)

;TesT:
(setq coor_list (vl-remove-if (function not)
      (mapcar (function (lambda (x)
(if (eq 10 (car x))(trans (cdr x) 0 1))))
    (entget (car (entsel "\nSelect object :\n"))))))
(write-exc coor_list)
(read-exc)