Behöver man stänga ett objekt man använder i en for each loop? Typ:
Dim rs As ADODB.Recordset, f As ADODB.Field
Set rs = ...
For Each f In rs.Fields
MsgBox f.Name
Next f
Set rs = Nothing
Behöver man där lägga till Set f = Nothing på slutet?
6 svar · 251 visningar · startad av Erik Juhlin
Behöver man stänga ett objekt man använder i en for each loop? Typ:
Dim rs As ADODB.Recordset, f As ADODB.Field
Set rs = ...
For Each f In rs.Fields
MsgBox f.Name
Next f
Set rs = Nothing
Behöver man där lägga till Set f = Nothing på slutet?
Nej, det har jag aldrig hört talas om att man ska göra.
Kan alltid vara bra att göra för att bruka mindre minne.
Behövs det eller stängs objektet automagiskt i.o.m. att loopen är klar? :)
Behövs det eller stängs objektet automagiskt i.o.m. att loopen är klar?
Frågan är egentligen ganska förvirrande. f refererar till ett ADODB.Field inne i ett ADODB.Recordset (rs) och minnet det upptar kan inte avallokeras innan Recordsetet avallokeras. Det avallokeras istället samtidigt som recordsetet avallokeras
set f=nothing
blir alltså helt verkningslöst (men inte fel).
Förutom det, så är f som referens i vilket fall som helst ogiltig efter loopen.
Experiment:
Dim rs As ADODB.Recordset, f As ADODB.Field
Set rs = ...
For Each f In rs.Fields
MsgBox f.Name
Next f
[blue]msgbox f is nothing[/blue]
Set rs = Nothing
Referensen nollas alltså av loopen själv.
Jo, provade det själv och fick också att f var Nothing efter loopen. Känns ganska logiskt också att f objektet endast finns inne i loopen.
Var min chef som helt plötsligt fått för sig att man behöver stänga såna objekt. :)
Var min chef som helt plötsligt fått för sig att man behöver stänga såna objekt.
Nej, enumeratorfunktionen i fields-collectionen fixar det själv. Men i andra fall har nog din chef en poäng som inte riktigt framgår av mitt svammel ovan.
Dim rs As ADODB.Recordset, f As ADODB.Field
Set rs = ...
set f = rs.fields(0) 'Vi skapar en kopia av [i]referensen[/i] till första fältet i rs.
debug.print ObjPtr(f) = ObjPtr(rs.fields(0)) 'Ger true eftersom det är samma objekt och inte en klonad kopia.
Set rs = Nothing 'Vi nollar den enda referensen till recordsetet.
Debug.print f.Name 'Fungerar bra.
Debug.print rs.fields(0).Name 'Ger run-time error eftersom rs inte är en giltig referens.
set f = Nothing 'Vi nollar referensen till fältet.
Frågan som uppstår är alltså när recordsetet egentligen avallokeras i det här fallet? Utan att ha kollat närmare så är jag ganska säker på att det inte sker förrän f har nollats.