webForumDet fria alternativet

ByRef & ByVal för objekt

12 svar · 478 visningar · startad av Vide

VideMedlem sedan dec. 19998 577 inlägg
#1

Tjena,

Nu till nästa fråga, jag skickar in ett recordset till en funktion där jag på något sätt påverkar recordsettet, kör jag ByVal så kopieras väl objektet till funktionen och de ändringar som genomförs är helt knutna till det kopierade objektet.

Jag vill använda ByRef så att allt jag ändrar slår igenom till objektet utanför komponenten. Men kör jag ByRef får jag ett felmeddelande om "Type mismatch", definitionen av funktionen:

Public Function GetRsInHTML([b]ByRef[/b] rsObject As ADODB.Recordset) As String

Kan någon berätta för mig vad som egentligen händer med objekt när man kör dom via ByRef?

Mvh, Vide

nikoMedlem sedan juni 20022 599 inlägg
#2

Om man överförenklar så kan man säga att ByVal=ByRef. Dvs objekt skickas alltid ByRef och ändringar slår igenom till objektet utanför komponenten även om du skriver ByVal.

De skillnader som finns beskrivs här: http://vb.oreilly.com/ron/objects.html.

Varför du får "Type mismatch" vet jag inte. Kommer det inte nånstans inne i funktionen? Hur ser koden ut när du anropar "GetRsInHTML"?

VideMedlem sedan dec. 19998 577 inlägg
#3

Okej, så egentligen spelar det inge roll om du kör med objekt.

Type mismatch kommer när jag försöker att använda ByRef, kör jag ByVal så funkar allt prima...

Koden som anropas med ett recordset:

'Returns a HTML table representing the structure of a recordset.
Public Function GetRsInHTML(ByVal rsObject As ADODB.Recordset) As String

  Dim i As Integer
  Dim strHTMLTable As String

  If rsObject.EOF Then

    GetRsInHTML = "<b><font color='red'>The object is at EOF</font></b>"
    Exit Function

  End If

  rsObject.MoveFirst

  strHTMLTable = "<table border='1'><tr>"

  For i = 0 To rsObject.Fields.Count - 1
    strHTMLTable = strHTMLTable & "<td width='100' class='text'><b>" & rsObject.Fields(i).Name & "</b></td>"
  Next

  strHTMLTable = strHTMLTable & "</tr>"

  Do Until rsObject.EOF

    strHTMLTable = strHTMLTable & "<tr>"

    For i = 0 To rsObject.Fields.Count - 1
      strHTMLTable = strHTMLTable & "<td width='100' class='text'>&nbsp;" & rsObject.Fields(i).Value & "&nbsp;</td>"
    Next

    strHTMLTable = strHTMLTable & "</tr>"

    rsObject.MoveNext
  Loop

  strHTMLTable = strHTMLTable & "</table>"
  
  GetRsInHTML = strHTMLTable
  
  rsObject.MoveFirst

End Function
@ndersMedlem sedan juni 200032 969 inlägg
#4

Om du ska kasta in saker från en asp-sida till byref-parametrar måste den vara definierad som variant i interfacet. Du kan dock ha den definierad som variant och ändå skicka tillbaka ett recordset i den.

Mvh,

VideMedlem sedan dec. 19998 577 inlägg
#5

Har jag fattat det rätt om jag skall göra såhär istället?

Public Function GetRsInHTML(ByRef rsObject As Variant) As String
@ndersMedlem sedan juni 200032 969 inlägg
#6

Japp.

Sedan skapar du ditt recordset som vanligt inne i funktionen och sätter din rsObject = dittrecordsetsomduskapatifunktionen i funktionen.

Mvh,

VideMedlem sedan dec. 19998 577 inlägg
#7

Tack! :)

Men motsäger inte det lite av det som niko sa, att ByVal och ByRef nästan är samma sak när det gäller objekt?

@ndersMedlem sedan juni 200032 969 inlägg
#8

Nej, det tycker jag inte. Grejen är att ASP inte kan hantera annat än varianter i interface till COM-objekt, eftersom det i VBScript inte finns annat än varianter. Hade du istället kallat på denna metod från en annan klass eller komponent hade det varit helt andra bullar.

Mvh,

Erik JuhlinMedlem sedan maj 200010 687 inlägg
#9

För det första så fungerar väl recordsets annorlunda jämfört med andra objekt. Där kopieras väl hela objektet..?

Sen så är väl skillnaden när man kör ByRef och ByVal att när man kör ByRef så kan man byta ut hela objektet mot ett annat och inte bara göra ändringar i det. :)

VideMedlem sedan dec. 19998 577 inlägg
#10

Men om hela objektet kopieras så kommer väl det inte att bli en referens, eller speglar den tillbaks när funktionen är färdigkörd?

nikoMedlem sedan juni 20022 599 inlägg
#11

Erik Juhlin skrev:

För det första så fungerar väl recordsets annorlunda jämfört med andra objekt. Där kopieras väl hela objektet..?

Nej? Det faller ju delvis på sin egen orimlighet. Ett statiskt, client-side recordset skulle möjligtvis kunna kopieras byte för byte (även om det vore ineffektivt). Men hur skulle tex ett dynamiskt, server-side recordset kunna kopieras? Det finns ju inte i sin helhet på klienten. Får man en kopia av hela databasen då?

Oavsett om man skickar in ett recordset byval eller byref så kommer man att manipulera originalobjektet inne i funktionen.

Erik Juhlin skrev:

Sen så är väl skillnaden när man kör ByRef och ByVal att när man kör ByRef så kan man byta ut hela objektet mot ett annat och inte bara göra ändringar i det.

Den exakta skillnaden mellan byval och byref är att byval skickar in en kopia av referensen. Men en kopia av referensen och originalreferensen pekar fortfarande båda på originalobjektet.

Vad skillnaden innebär: http://vb.oreilly.com/ron/objects.html.

Om man sen tänker på MTS-objekt (som du kanske gör) så blir det lite överkurs, då tillkommer marshalling över process-boundaries och sånt.

Erik JuhlinMedlem sedan maj 200010 687 inlägg
#12

Jo, så är det. Det måste vara ett client-side recordset. :)

Jo, men om man skickar en kopia på referensen och sen byter ut den så kommer inte originalobjektet vara utbytt. :)
Flummigt. :)

nikoMedlem sedan juni 20022 599 inlägg
#13

Erik Juhlin skrev:

Jo, men om man skickar en kopia på referensen och sen byter ut den så kommer inte originalobjektet vara utbytt.

Exakt! Det är en av skillnaderna som tas upp i artikeln jag länkade till.

131 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
128 ms — hämta tråd, inlägg och bilagor (db)