Newsgroup: it.comp.appl.access
Titolo: Passaggio recordset  a una form tramite Property con errore di runtime

Un salutone a tutti.
 
Cercherò di semplificare al massimo il problema.
 
Abbiamo 2 Form: 
 
- "Form1"  - commandbuton: ”cmdApriForm”
- "Form2" associata a una tablella qualsiasi con n record
 
DETTAGLIO:
----------- Form1 -----------------------------
Private pRsInProperty As DAO.Recordset
 
Private Sub cmdApriForm_Click()
   DoCmd.OpenForm "Form2", , , , , acDialog
   Debug.Print Me.Name & " ->" & Me.RsInProperty.RecordCount
End Sub
 
Public Property Get RsInProperty() As DAO.Recordset
   Set RsInProperty = pRsInProperty
End Property
 
Public Property Let RsInProperty(ByVal newValue As DAO.Recordset)
   Set pRsInProperty = newValue
End Property
 
----------- Form2 -----------------------------
 
Private Sub Form_Load()
   Dim frm As Form_Form1
 
   Set frm = Forms("form1")
   frm.RsInProperty = Me.Recordset
 
   Debug.Print Me.Name & “->" & frm.RsInProperty.RecordCount
End Sub
 
----- ESECUZIONE ----
 
- Lancio la form 1
 
- Clicco sul commandbutton che apre la Form2
 
- Il Debug.Print  evidenzia correttamente il recordcount tramite 
  la RsInProperty
 
- Chiudo la form2
 
- La riga con il Debug.Print della Form1 genera l’errore di runtime
  ‘3000’ (errore riservato - 1104)
 
Domanda: come mai la property  funziona correttamente nella Form2 e, invece, nella Form1 mi genera un errore di runtime tutt'altro che chiaro?
 
TIA per l'aiuto,
Stolcius
 
-- Per aspera ad (dis)astra

 - "Form2" associata a una tablella qualsiasi con n record
 
[cut].........
Perche' definisci una property Let per un oggetto? Che tra l'altro passi 
(vorresti passare) byVal?
Gli oggetti usano "set" e vengono passati per reference.
 
-- 
 
ac (x=y-1)
 
 

 Perchè definisci una property Let per un oggetto? 
 
Ciao e grazie, Alessandro.
 
Imho l'inguacchio non dovrebbe risiedere nel let, in quanto, nella form2, l'oggetto restituisce correttamente il recordcount.
 
Ad ogni bon conto avevo già tentato tutte le combinazioni possibili: let, set, byval, byref, ali di pipistrello e olio di serpente. :-))
 
Al culmine della disperazione ho osato anche l'oscura via del late binding con "as object" al posto di "as dao.recordset"
 
L'ultima combinazione è quella del post con let e byval.
 
L'errore è stato sempre lo stesso: runtime error 3000(-1104).
 
Prova tu stesso.
 
Che dici? E' possibile che si tratti di un bug?
 
Per la cronaca il test è stato effettuato con Access 2007 - Sp2.
 
Ritornando al let e set,probabilmente mi sbaglio, ma mi sembra che la differenza sia puramente sintattica.
 
Con Property Let debbo referenziare l'oggetto in questo modo:
 
frm.RsInProperty = Me.Recordset
 
Con Property  Set:
 
Set frm.RsInProperty = Me.Recordset
 
 
Un salutone,
Stolcius
 


 
 
-- 
 
ac (x=y-1)
 
 

"Let" : property=var, nell'altro caso con "Set": set property=var 
 
D'accordo, ma rimane il fatto che nella form2 l'oggetto recordset viene assegnato(1) e utilizzato(2) senza problemi, mentre nella form1 -ceteris paribus - il tutto va in vacca.
 
1) Set frm.RsInProperty = Me.Recordset
2) Debug.Print Me.Name & " ->" & frm.RsInProperty.RecordCount
 
 
Per il resto conto di risponderti non appena avrò fatto alcuni test.
 
Un salutone e grazie ancora  per la risposta,
Stolcius

Stolcius Von Stolcenberg presented the following explanation :

Sembra un programma fatto da MS...
Fa' ancora qualche sforzo e la MS ti assume come consulente.
 
Su Form1:
Private Sub Command3_Click()
    'DoCmd.OpenForm "Form2", , , , , acHidden
    Set Recordset = Forms("Form2").Recordset
    'DoCmd.Close acForm, "Form2"
End Sub
 
I controlli (campi della tabella origine di Form2) debbono esistere in 
Form1.
 
Bruno
 
PS
RsInProperty nell'Help di Access 10/64 non esiste.
E io non l'ho mai sentito nominare.
Da dove viene?
 
 

Da dove viene? 
 
Le ho create io:
Public Property Get RsInProperty() As Recordset
       Set RsInProperty = pRsInProperty
End Property
 
Public Property Set RsInProperty(ByVal newValue As Recordset)
      Set pRsInProperty = newValue
End Property
 
Beninteso, avrai mille altre occasioni per tirarmi le orecchie.
D'altronde il mio moto è "per aspera ad (dis)astra" :-))
 
Un salutone,
Stolcius

 Stolcius
 
Se ti piace andar per aspera mi taccio... come Farinata.
 
Bruno
 
 

devi fare set x = oggetto (Come scrivi a seguire)
 
Giusto, ma ciò è valido per gli oggetti predefiniti.
 
Tramite le property siamo noi che decidiamo come dovrà essere la sintassi.
 
Non si tratta di un’assunzione gratuita: dimostrerò(almeno lo spero) questa tesi tramite la seguente  PoC.
 
****** Modulo di Classe: “clsClassePoc” ******
Option Compare Database
Option Explicit
 
Private pOggettoQualsiasi As Object
 
Public Property Get OggettoQualsiasi() As Object
    Set OggettoQualsiasi = pOggettoQualsiasi
End Property
 
Public Property Set OggettoQualsiasi(ByRef newValue As Object)
    Set pOggettoQualsiasi = newValue
End Property
 
******* Modulo: “Modulo1” **********
Private Sub TestPoc()
 
  Dim ClassePoc As clsClassePoc
  Dim CollPoc As Collection
 
  Set ClassePoc = New clsClassePoc
  Set CollPoc = New Collection
 
 
  Debug.Print "****** START *******"
  ' inserisco un elemento qualsiasi  nella collezione
 
  CollPoc.Add "PippoItem", "Pippokey"
 
  Set ClassePoc.OggettoQualsiasi = CollPoc
 
    ' inserisco un secondo elemento  nella collezione tramite la classe
  Debug.Print "1) "; ClassePoc.OggettoQualsiasi.Item("Pippokey")
 
  ClassePoc.OggettoQualsiasi.Add "PlutoItem", "Plutokey"
  Debug.Print "2) " & ClassePoc.OggettoQualsiasi.Item("Plutokey")
 
 Set ClassePoc = Nothing
 Set CollPoc = Nothing
 
End Sub
*********************************************
In poche parole abbiamo una Property “Set”.
Il riferimento viene quindi attribiuto con un Set.
------------------------------------------------------------
    Set ClassePoc.OggettoQualsiasi = CollPoc
------------------------------------------------------------
Lancio TestPoc -> output:
----------------------
****** START *******
1) PippoItem
2) PlutoItem
-----------------------
Ok, il tutto funzica alla grande.
 
Modifichiamo la property da Set A Let.
-------------------------
Public Property Let OggettoQualsiasi(ByRef newValue As Object)
    Set pOggettoQualsiasi = newValue ‘l’importante è che qui non
                                     ' venga espunto il set
End Property
----------------
 
A questo punto il riferimento deve essere attribiuto senza Set.
------------------------------------------------------------
    ClassePoc.OggettoQualsiasi = CollPoc
-------------------------------------------------------------
Lancio TestPoc -> output:
-------------------------
****** START *******
1) PippoItem
2) PlutoItem
-------------------------
Quindi CVD il meccanismo - mutatis mutandis -funziona anche con il Let.
 
Spero di non aver scritto castronerie.
 
Un salutone,
Stolcius

Lo immaginavo. Manca il sangue di drago!
 
Ma lo sai che avevi ragione?
 
[Sangue di Drago]="Sale in zucca di Stolcius" :-))
 
Ho capito le ragioni del problema, che adesso mi sembra di un'ovvietà disarmante.
 
Be', è naturale che chiudendo la "form2" il richiamo al recordcount generi un errore: l'oggetto me.recordset, con la chiusura, "Kaputt!" Va a ingrassare i cavoli.
 
Pertanto, la property si ritrova un riferimento che pesca nel nulla che nulleggia!
 
Ci sarei dovuto arrivare subito, ma vi è stato un alquanto arcano precedente che mi ha sviato.
 
Infatti, avevo già provato a usare una variabile globale "as recordset.dao" con piena soddisfazione(a chiusura della form2, la variabile globale manteneva il riferimento).
 
Ciò, molto probabilente - e correggimi se dovessi sbagliarmi -, è dovuto al Garbage Collector, che, in qualche modo, tiene in vita l'oggetto cui la variabile si riferisce per qualche attimino in più.
 
A riprova di questa congettura, inseredo un  DoEvents prima del richiamo della variabile si genera nuovamente l'abominevole errore 3000.
 
Private Sub cmdApriForm_Click()
   DoCmd.OpenForm "Form2", , , , , acDialog
 
   DoEvents 'Senza questa riga il recordcount restituisce il n. dei record.
 
   Debug.Print Me.Name & Now & " global ->" & rsGlobale.RecordCount
 
End Sub
 
Meglio tardi(in tutte le neurologiche accezioni) che mai...
 
Stolcius