Zobrazit plnou verzi příspěvku: ADO Automation Error

Vratislav
26.04.2005, 15:23
V AutoLispu (Map 3D 2005) cyklicky vytvarim a oteviram adodb.recordset (Microsoft.Jet.OLEDB.4.0). Po urcitem poctu iteraci (cca 180) program vzdy spadne a nahlasi: Automation Error. Nelze otevrit zadnou dalsi tabulku.
Recordset delam jednoduse takto: 
  (setq rs nil)  (setq rs (vlax-create-object "ADODB.Recordset"))
  (vlax-invoke-method    rs    "OPEN"    sql    cn    adok-adOpenStatic    adok-adLockReadOnly    adok-adCmdUnknown  )
Podobne cykly pouzivam casto uz radu let a nikdy jsem se s touto chybou nesetkal. Nevite nekdo co to znamena? V Mapu 5 (2002) mi to urcite nedelalo.
Diky za kazdou radu.

Vladimír Michl
26.04.2005, 15:50
nevím, jestli by nebylo efektivnější opakovaně používat stejný objekt rs, ale hlavně by bylo dobré odchytávat případné chyby ADO (a dozvědět se tak bližší příčiny chyby) - viz vl-catch-all-apply

Vratislav
26.04.2005, 17:24
Pane Michle, chyby ado samozřejmě odchytávám:
Viz např:
(setq errobj (vl-catch-all-apply   'vlax-invoke-method   (list rsSloje         "Open"         sql         cnEUZ         adok-adOpenStatic         adok-adLockReadOnly         adok-adCmdUnknown   )        )  )
  (if (vl-catch-all-error-p errobj)    (alert (vl-catch-all-error-message errobj))  )
Není mi to ale nic platné, protože v tom alertu se nedovím nic nového: prostě Automation Error: Nelze otevřít žádnou další tabulku.
Otázku efektivnosti vytváření recordsetu při každém volání funkce ponechám stranou. To bych nakonec mohl mít v celé aplikaci jeden globální recordset a ten bych jen otevíral a zavíral.
Problém asi souvisí s tím, jak AutoLisp 2005 object recordset vytváří a ruší. Je opravdu (setq rs nil) to samé jako ve VB set rs = nothing? Vypadá to totiž, jako by v určitý okamžik byl vyčerpán nějaký potřebný paměťový prostor, protože AutoLisp po sobě objekty recordset neruší.
 

Vratislav
26.04.2005, 18:20
Pane Michle, je to opravdu tak. že AutoLisp vytváří stále nové a nové objekty recordset. Prozatím mi pomohlo to, že jsem cyklicky otevírané recordsety opravdu nechal globální a objekt recordset vytvářím jen jednou.
(if (null rs)   ;;Pokud ano - vytvorim novy   (setq rs (vlax-create-object "ADODB.Recordset"))   ;;Pokud ne a je otevren - zavru ho   (if (= (vlax-get-property rs "State") 1)     (vlax-invoke-method rsProfil "Close")   ) )
Program tedy už jede, ale znamená to, že se vlastně neumím objektu vytvořeného pomocí funkce vlax-create-object zbavit. Co s tím? Navíc bych se skoro vsadil, že se tak Map 2002 nechoval.
 
 

Vladimír Michl
26.04.2005, 18:24
(setq rs nil) zruší ukazatel na objekt, ale nikoliv objekt samotný (jeho paměť); pro rušení objektu slouží (a vždy sloužila) VLisp funkce vlax-release-object
popis chyby závisí na tom co vrátí daný objekt, měl by být dostupný přes catch-all-error-message

Vratislav
26.04.2005, 18:25
Omlouvám se za chybu, ale fragment k kódu v předešlé odpovědi má být pochopitelně takto:
(if (null rs)   ;;Pokud ano - vytvorim novy   (setq rs (vlax-create-object "ADODB.Recordset"))   ;;Pokud ne a je otevren - zavru ho   (if (= (vlax-get-property rs "State") 1)     (vlax-invoke-method rs "Close")   ) )