CADsite forum

AutoCAD => Autolisp => Topic gestart door: Atwist op do 08 07 2010, 15:29:46

Titel: Getexcel ervaring (XL-get)
Bericht door: Atwist op do 08 07 2010, 15:29:46
Hallo forumleden,

Heeft iemand van jullie ervaring met het lisp tool GetExcel van Jeffery Sanders.
Ik wil deze graag gebruiken maar mijn Excel loopt telkens vast als ik GetExcel gebruik en de sheet kan ik niet meer openen.

Hoor graag jullie ervaringen en/of eventuele oplossingen.

Atwist
Titel: Re:Getexcel ervaring
Bericht door: HofCAD op vr 09 07 2010, 09:13:43
Beste Awist.

Ik heb er tot nu toe, nog nooit problemen er mee gehad.
Kun je aan de hand van een voorbeeld je probleem niet toelichten.
Kun je verder ook je AutoCAD en Excel versie opgeven.

Met vriendelijke groet, HofCAD CSI.
Titel: Re:Getexcel ervaring
Bericht door: Atwist op vr 09 07 2010, 14:40:53
Hallo HofCad,

Ik heb meerdere sheets met userforms om allerlei berekening te maken, het userform zet de berekening op een sheet bv cilinder berekening komt op sheet cilinder te staan.
Dit gaat allemaal goed, ik kan nu ook met GetExcel de sheet aanspreken en de tabel wordt ook gemaakt.
Maar als ik nu een nieuwe berekening wil maken ga ik excel en het bestand openen krijg ik de melding "dit bestand is in gebruik U kunt alleen lezen".
Nu moet ik mijn PC op nieuw opstarten of ben ik net achtergekomen via toepassings herstel van microsoft office.

Ik gebruik Excel 2003 PRO en AutoCad 2008 volledig

Atwist


Ik moet even wat recht zetten ik heb het telkens over GetExcel maar dit moet XL-Get zijn.
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: Joop op ma 12 07 2010, 09:08:12
Het grote probleem met Excel is dat het niet goed afsluit.
Zelfs als je Excel op de officiele manier afsluit blijft Windows denken dat er nog een sheet is geopend.

Open maar eens een sheet vanaf een datastick en sluit deze dan weer.
Probeer nu de datastick te verwijderen via het icoontje op je taakbalk (rechts onder).
Grote kans dat je de melding krijgt dat dit niet mogelijk is. Ook niet een tijd later.

Zelfs met onderstaande code (uit GetExcel) lukt het niet, maar je kunt dan wel doorwerken.
;;;;-------------------------------------------------------------------------------
;;;; CloseExcel - Closes Excel spreadsheet
;;;; Arguments: 1
;;;;   ExcelFile$ = Excel saveas filename or nil to close without saving
;;;; Syntax examples:
;;;; (CloseExcel "C:\\Temp\\Temp.xls") = Saveas C:\Temp\Temp.xls and close
;;;; (CloseExcel nil) = Close without saving
;;;;-------------------------------------------------------------------------------
(defun CloseExcel (ExcelFile$ / Saveas)
  (if ExcelFile$
    (if (= (strcase ExcelFile$) (strcase *ExcelFile$))
      (if (findfile ExcelFile$)
(vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook") "Save")
(setq Saveas t)
      ) ;_if
      (if (findfile ExcelFile$)
(progn
  (vl-file-delete (findfile ExcelFile$))
  (setq Saveas t)
) ;_progn
(setq Saveas t)
      ) ;_if
    ) ;_if
  ) ;_if
  (if Saveas
    (vlax-invoke-method
      (vlax-get-property *ExcelApp% "ActiveWorkbook")
      "SaveAs"
      ExcelFile$
      -4143
      ""
      ""
      :vlax-false
      :vlax-false
      nil
    ) ;_vlax-invoke-method
  ) ;_if
  (vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook") 'close :vlax-false)
  (vlax-invoke-method *ExcelApp% 'quit)
  (vlax-release-object *ExcelApp%)
  (gc)
  (setq *ExcelApp%  nil
*ExcelFile$ nil
  )
  (princ)
) ;_defun CloseExcel
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: Atwist op ma 12 07 2010, 09:53:18
Hallo Joop,

Dank voor je reactie.
Ik heb de code gekopieerd en er een lisp van gemaakt met de naam "Cexcel", heb ook een Excelsheet met de naam temp en deze ook in de map temp gezet.
Maar ik kreeg nu deze foutmelding:

Command: _appload Cexcel.lsp successfully loaded.
Cexcel.lsp successfully loaded.
Command:
Command:
Command:
Command: (CloseExcel "C:\\Temp\\Temp.xls")
; error: bad argument type: stringp nil


Weet je misschien ook wat  hiervan de oorzaak is?

Atwist
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: Joop op ma 12 07 2010, 10:29:37
Als je excel opent met onderstaande code werkt het wel.
;;;;--------------------------------------------------------------------------------------------------------------------;
;;;; OpenExcel - Opens an Excel spreadsheet ;
;;;; Arguments: 3 ;
;;;;   ExcelFile$ = Excel filename or nil for new spreadsheet ;
;;;;   SheetName$ = Sheet name or nil for not specified ;
;;;;   Visible = t for visible or nil for hidden ;
;;;; Syntax examples: ;
;;;; (OpenExcel "C:\\Temp\\Temp.xls" "Sheet2" t) = Opens C:\Temp\Temp.xls on Sheet2 as visible session ;
;;;; (OpenExcel "C:\\Temp\\Temp.xls" nil nil) = Opens C:\Temp\Temp.xls on current sheet as hidden session ;
;;;; (OpenExcel nil "Parts List" nil) =  Opens a new spreadsheet and creates a Part List sheet as hidden session ;
;;;;--------------------------------------------------------------------------------------------------------------------;
(defun OpenExcel (ExcelFile$ SheetName$ Visible / ;|Sheet$ Sheets@ Worksheet|;)
  (if (= (type ExcelFile$) 'STR)
    (if (findfile ExcelFile$)
      (setq *ExcelFile$ ExcelFile$)
      (progn
(alert (strcat "Excel file " ExcelFile$ " not found."))
(exit)
      ) ;_progn
    ) ;_if
    (setq *ExcelFile$ "")
  ) ;_if
  (gc)
  (if (setq *ExcelApp% (vlax-get-object "Excel.Application"))
    (progn
      (alert "Close all Excel spreadsheets to continue!")
      (vlax-release-object *ExcelApp%)
      (gc)
    ) ;_progn
  ) ;_if
  (setq *ExcelApp% (vlax-get-or-create-object "Excel.Application"))
  (if ExcelFile$
    (if (findfile ExcelFile$)
      (vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'open ExcelFile$)
      (vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Add)
    ) ;_if
    (vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Add)
  ) ;_if
  (if Visible
    (vla-put-visible *ExcelApp% :vlax-true)
  ) ;_if
  (if (= (type SheetName$) 'STR)
    (progn
      (vlax-for Sheet$ (vlax-get-property *ExcelApp% "Sheets")
(setq Sheets@ (append Sheets@ (list (vlax-get-property Sheet$ "Name"))))
      ) ;_vlax-for
      (if (member SheetName$ Sheets@)
(vlax-for Worksheet (vlax-get-property *ExcelApp% "Sheets")
  (if (= (vlax-get-property Worksheet "Name") SheetName$)
    (vlax-invoke-method Worksheet "Activate")
  ) ;_if
) ;_vlax-for
(vlax-put-property
  (vlax-invoke-method (vlax-get-property *ExcelApp% "Sheets") "Add")
  "Name"
  SheetName$
)
      ) ;_if
    ) ;_progn
  ) ;_if
  (princ)
) ;_defun OpenExcel
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: Atwist op ma 12 07 2010, 10:45:41
Joop

Hiermee kan ik inderdaad een excel sheet openen en met de vorige kan ik deze weer sluiten zonder fout meldingen.
Maar ik kan nog steeds niet mijn bestand gebruiken en dus ook geen nieuwe berekening maken, zodra ik mijn userform start dan zit de boel weer vast (normaal loopt deze userform als een trein).

Ik hoop dat je misschien nog een oplossing heb.

Atwist
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: Joop op ma 12 07 2010, 11:32:25
Kun je de Userform misschien uploaden?
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: Atwist op ma 12 07 2010, 12:20:55
Bij deze

Let wel hij is nog niet klaar maar werkt wel goed

Atwist
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: Joop op di 13 07 2010, 10:51:51
Ik denk  :vraagteken: dat ik eruit ben.
Je opent Excel met Visual Lisp vanuit AutoCAD.
Dit betekent dat lisp de "eigenaar" wordt van van het object Excel en het object worksheet.
Nu start je VBA op en die wil hetzelfde >>>> OORLOG. Waar twee honden vechten om hetzelfde been loopt het programma vast.

Ik denk  :vraagteken: dat het mogelijk is om een vba-routne cq userform in Excel op te starten vanuit Visual Lisp maar Ik heb hier geen ervaring mee.
Hieronder een uittreksel van AfraLisp in het engels over het laden en runnen van een vba routine via lisp.
CiteerLoading VBA Files
There are two AutoCAD functions that can you would use to Load and Run VBA Applications namely,
VBALOAD and VBARUN. In a menu file you would use them like this :

[Test]^C^C^C^P-vbaload test.dvb -vbarun Module1.MyTest

Or, in an AutoLisp routine, you would write something like this :

(command "vbaload" "test.dvb")
(command "-vbarun" "Module1.MyTest")

The VBALOAD function has one serious flaw though!
If a VBA application is already loaded, and you run VBALOAD again, you get an error message. Try it
out :

Command: -vbaload
Initializing VBA System...
Open VBA Project: test.dvb

Now try and load it again.

Command: -vbaload
Open VBA Project: test.dvb
You should get an error message :
"File already loaded d:/drawings/test.dvb"

This is where Visual Lisp come into play.
The function (VL-VBALOAD) behaves much like the command VBALOAD. You need to supply the file
name of a project or DVB file. The complete file name should be provided along with the path and DVB
extension. For example, if you want to load a project named MyProject.dvb in the C:\MyWork\ folder, the
(VL-VBALOAD) function call would appear as follows.

(VL-VBALOAD "C:/MyWork/MyProject.DVB")

You should note a couple of things right away. Visual LISP makes use of forward slashes when
separating folder or directory names. Also, the parentheses are required and the extension DVB is
needed for the project to be properly located.
Unlike the VBALOAD command, this function will not generate an error if the project has already been
loaded into the current drawing environment. Thus, programs can proceed smoothly by just calling the
load function and then calling the run function without concern about the project already being loaded.
Another interesting feature is that the Enable Macros/Virus Warning message does not appear when you
use the Visual LISP approach.
Therefore, your menu macro :

[Test]^C^C^C^P-vbaload test.dvb -vbarun MyTest

can be replaced with the following one:

[Test]^C^C^C^P(vl-vbaload "test.dvb")(vl-vbarun "MyTest")

And of course, your AutoLisp coding should be replaced with this :

(vl-vbaload "test.dvb")
(vl-vbarun "MyTest")
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: sschevers op di 13 07 2010, 11:19:07
Zoals Joop al aangeeft is dat wanneer je met vlisp het excel doc opent het bestand wordt gelocked. Zorg dus dat je wanneer je rouitne klaar is je je excel objecten ook weer netjes opruimt (vlax-release-object). Doe je dit niet dat blijft je document gelocked en kun je er niets mee. Alleen door het excel proces te killen kun je weer bij je document.

Let er op dat je ook in je error handling rekening houd met het opruimen van je objecten.

stephan
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: Atwist op di 13 07 2010, 12:07:06
Joop en Stephan,

Dank voor jullie reacties,

Met deze gegevens ga ik eens kijken of ik het voor elkaar kan krijgen.

Atwist
Titel: Re:Getexcel ervaring (XL-get)
Bericht door: HofCAD op di 13 07 2010, 13:51:25
Beste Atwist,

Ik ga er van uit dat je bestand Temp.xls heet en in de root van C: staat.
en in dit Excelbestand heb je een macro Knop1_Klikken.
Dan kun je de macro van Excel in Lisp als volgt opstarten:
(defun C:RM (/ abks aexc asht find x xbks xlpath xshts)
(vl-load-com)
;;;(if (not (findfile
;;;(setq xlpath (strcat (getvar "dwgprefix") "TestMacros" ".xls"))))
;;;<-- full path of your Excel file, change to suit
 (if (not (findfile
    (setq xlpath "c:/temp.xls")
  )
     ) ;;;<-- full path of your Excel file, change to suit
   (progn
     (alert "File does not exist")
     (exit)
     (princ)
   )
 )
 (alert "Close Excel File Save Changes")
 (setq aexc (vlax-get-or-create-object "Excel.Application")
xbks (vlax-get-property aexc "Workbooks")
 )
 (if (not (vl-file-systime xlpath))
   (progn (setq find nil)
  (setq abks (vlax-invoke-method xbks "Add"))
   )
   (progn (setq find T)
  (setq abks (vlax-invoke-method xbks "Open" xlpath))
   )
 )
 (setq xshts (vlax-get-property abks "Sheets")
asht  (vlax-get-property xshts "Item" 1)
 ) ;<-- sheet number - optional not used in this program
 (vla-put-visible aexc :vlax-true)
 (vlax-put-property aexc "ScreenUpdating" :vlax-true) ; to see changes
 (vlax-put-property aexc "DisplayAlerts" :vlax-true)
; to initialize user interaction
 (vlax-invoke-method asht "Activate") ;optional not used in this program
 (vlax-invoke-method
   aexc
   "Run"
   (strcat (vl-filename-base xlpath) ".xls!Knop1_Klikken")
 ) ;<-- macro name in the Excel file
 (vlax-invoke-method
   abks 'SaveAs xlpath -4143 nil nil :vlax-false :vlax-false 1 2)
 (mapcar
   (function (lambda (x)
(vl-catch-all-apply
 (function (lambda ()
     (progn
(if x
 (vlax-release-object x)
)
     )
   )
 )
)
     )
   )
   (list asht xshts abks xbks aexc)
 )
 (setq aexc nil)
 (gc)
 (gc)
 (princ)
)
(princ "\nType RM to run macros")
(princ)

Zie voor de bron: http://forums.augi.com/showthread.php?t=110899

Met vriendelijke groet, HofCAD CSI.