[VB6] ByVal ByRef Gaat allemaal mis.

Pagina: 1
Acties:

  • Nexopheus
  • Registratie: Juni 2001
  • Laatst online: 28-01 13:50
Goed, het volgende is het geval.
Ik heb een collectieklasse, deze bevat meerdere klassen (DUH) en de klasse bevat ook nog een andere klasse.....

Schema:
dataPointCollection
dataPoint
measurement

Nu gaat er iets mis bij het laden van de code. het Measurement object wordt constant overgeschreven, zodat ik aan het eind bij elke dataPoint hetzelfde measurement object heb. [ nog duidelijk :X ?]

Datapoint.cls
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Option Explicit
Private meas As New Measurement
Private dblPower As Double
Private dblRPM As Double
Private strComment As String
Public Property Set Measure(m As Measurement)
    Set meas = m
End Property
Public Property Get Measure() As Measurement
    Set Measure = meas
End Property
Public Property Let powerInst(dblP As Double)
    dblPower = dblP
End Property
Public Property Get powerInst() As Double
    powerInst = dblPower
End Property
Public Property Get rpmInst() As Double
    rpmInst = dblRPM
End Property
Public Property Let rpmInst(ByVal vNewValue As Double)
    dblRPM = vNewValue
End Property

Public Property Get comment() As String
    comment = strComment
End Property

Public Property Let comment(ByVal vNewValue As String)
    strComment = vNewValue
End Property

Measurement
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Option Explicit
Private mdblrpm As Double
Private mdblTorque As Double
Private mIntTemp As Integer
Private mIntTempPCB As Integer
Public Property Get rpm() As Double
    rpm = mdblrpm
End Property
Public Property Let rpm(ByVal vNewValue As Double)
    mdblrpm = vNewValue
End Property
Public Property Get torque() As Double
    torque = mdblTorque
End Property
Public Property Let torque(ByVal vNewValue As Double)
    mdblTorque = vNewValue
End Property
Public Property Get temperature() As Integer
    temperature = mIntTemp
End Property
Public Property Let temperature(ByVal vNewValue As Integer)
    mIntTemp = vNewValue
End Property
Public Property Get temperaturePCB() As Integer
    temperaturePCB = mIntTempPCB
End Property
Public Property Let temperaturePCB(ByVal vNewValue As Integer)
    mIntTempPCB = vNewValue
End Property
Public Property Get power() As Double
    power = mdblTorque * 2 * PI * (mdblrpm / 60)
End Property
Public Property Let power(ByVal vNewValue As Double)
    mdblTorque = vNewValue / (2 * PI * (mdblrpm / 60))
End Property


DataPointCollection
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Option Explicit

Private mColDataPoint As New Collection

Public Function add(ByVal rpm_In As Double, _
    ByVal power_In As Double, ByVal comment As String, _
    ByVal m As Measurement) As DataPoint
    Static intCt As Integer
    intCt = intCt + 1
    Dim NewDataPoint As New DataPoint
    With NewDataPoint
        .rpmInst = rpm_In
        .powerInst = power_In
        .comment = comment
        Set .Measure = m
        mColDataPoint.add NewDataPoint, CStr(intCt)
    End With
      Set add = NewDataPoint
End Function

Public Function Count() As Long
    Count = mColDataPoint.Count
End Function

Public Sub Delete(ByVal Index As Variant)
    mColDataPoint.Remove (Index)
End Sub

Public Function Item(ByVal Index As Variant) As DataPoint
    Set Item = mColDataPoint.Item(Index)
End Function
Public Function NewEnum() As IUnknown
    Set NewEnum = mColDataPoint.[_NewEnum]
End Function

Public Sub loadData(strPath As String)
Dim fso As New FileSystemObject, fil As File, ts As TextStream
Dim txtArr, ergArr, pwrArr As Variant, txt As String, txtTemp As String
Dim i%, j%
Dim rpm_instel, power_instel As Double
Dim meas As New Measurement

    Set fil = fso.GetFile(strPath)
    Set ts = fil.OpenAsTextStream(ForReading)
    txt = ts.ReadAll
    txtArr = Split(txt, vbCrLf)
    For i% = LBound(txtArr) To UBound(txtArr)
        ergArr = Split(txtArr(i%), "|")
        pwrArr = Split(ergArr(1), ",")
        rpm_instel = Val(ergArr(0))
        For j% = LBound(pwrArr) To UBound(pwrArr)
            add rpm_instel, Val(pwrArr(j%)), " ", meas
        Next
    Next
End Sub


Inlezen van de data uit de database en invoeren in de datastructuur
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Public Function getCalibrations() As CalibrationCollection
Dim strSQL As String
Dim rsCalib As ADODB.Recordset
Dim nwCalCol As New CalibrationCollection
Dim nwCalib As Calibration
    strSQL = "SELECT * FROM Calibration"
    Set rsCalib = cnnLode.Execute(strSQL)
    Do While Not rsCalib.EOF
        Set nwCalib = nwCalCol.add(Ergometers.Item(rsCalib.Fields(2)), _
        getEngineer(rsCalib.Fields(1)), _
        getCustomer(rsCalib.Fields(3)), _
        rsCalib.Fields(4), _
        getCalibMatrix(rsCalib.Fields(0)), _
        rsCalib.Fields(0))
        rsCalib.MoveNext
    Loop
    Set getCalibrations = nwCalCol
End Function
Public Function getCalibMatrix(key As Integer) As DataPointCollection
Dim strSQL As String
Dim rsCalibMatrix As ADODB.Recordset
Dim nwDataP As New DataPoint
Dim nwMeas As New Measurement

Dim nwCalibMatrix As New DataPointCollection
    strSQL = "SELECT * FROM Metingen WHERE Metingen.CalibID=" & key
    Set rsCalibMatrix = cnnLode.Execute(strSQL)
    Do While Not rsCalibMatrix.EOF
        nwMeas.rpm = Val(rsCalibMatrix.Fields(3))
        nwMeas.power = Val(rsCalibMatrix.Fields(4))
        Set nwDataP = nwCalibMatrix.add(rsCalibMatrix.Fields(1), _
        rsCalibMatrix.Fields(2), "", nwMeas)
        rsCalibMatrix.MoveNext
    Loop
    Set getCalibMatrix = nwCalibMatrix
End Function


Nog een keer het probleem.
Het measurement object geeft na een get bij elke datapoint uit de datapointcollectie dezelfde waarde.
Iemand een oplossing of een idee?

Wat niet kan is nog nooit gebeurd


Verwijderd

klopt .. .
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Public Function add(ByVal rpm_In As Double, _
    ByVal power_In As Double, ByVal comment As String, _
    ByVal m As Measurement) As DataPoint
    Static intCt As Integer
    intCt = intCt + 1
    Dim NewDataPoint As New DataPoint
    With NewDataPoint
        .rpmInst = rpm_In
        .powerInst = power_In
        .comment = comment
        Set .Measure = m 
        mColDataPoint.add NewDataPoint, CStr(intCt)
    End With
      Set add = NewDataPoint
End Function


Set .Measure = m

hier "Set" je het adres van een byval value... oftewel .. onder water wordt de pointer opgeslagen . . .volgens mij is dit de pointer naar de lokale stack van de functie. . . die is volgens mij iedere keer hetzelfde. . ..

m moet byref om een pointer van de globale heap te kunnen krijgen
voordat je m meegeeft vannuit die andere functie moet je hem ook IEDERE keer new-en (in jou voorbeeld new je hem maar 1x . .voordat je de i% loop begint in de loaddata functie)

  • Nexopheus
  • Registratie: Juni 2001
  • Laatst online: 28-01 13:50
Ok, zal dat eens proberen, dacht dat byref juist de pointer meegaf.....

Wat niet kan is nog nooit gebeurd


Verwijderd

dat klopt. . en dat moet ook . . het moet namelijk die pointer van die genewde class zijn ('meas' in de loaddata). .. die moet je in de j% van de loaddata iedere keer newen voordat je hem meegeeft

code:
1
2
3
4
5
6
7
8
    For i% = LBound(txtArr) To UBound(txtArr)
        ergArr = Split(txtArr(i%), "|")
        pwrArr = Split(ergArr(1), ",")
        rpm_instel = Val(ergArr(0))
        For j% = LBound(pwrArr) To UBound(pwrArr)
SET MEAS IS NEW MEASUREMENT
            add rpm_instel, Val(pwrArr(j%)), " ", meas
        Next

  • Nexopheus
  • Registratie: Juni 2001
  • Laatst online: 28-01 13:50
Oh, sorry die LoadData is niet het probleem. die leest alleen maar de instellingen in, laat Meas gewoon op nothing staan. Het probleem doet zicht voor bij de functie add van DataPointCollection. De meas waarde die wordt meegegeven klopt allemaal.

Op het moment dat ik de get functie aanroep van DataPoint gaat het fout.

edit.
Ik ben er nu vrij zeker van dat de fout in de DataPoint klasse staat.
Visual Basic:
1
2
3
4
5
6
Public Property Set Measure(m As Measurement)
    Set meas = m
End Property
Public Property Get Measure() As Measurement
    Set Measure = meas
End Property

Wanneer ik hier een watch op gooi staat de m goed, maar na de set staat meas niet goed.

Ik snap er echt helemaal niets meer van.

Nog een edit.
De DataPointCollection heeft meerdere DataPoints, dit gaat goed, alle data staat hier goed. MAAAAR op 1 of andere manier heeft elke dataPoint in de datapoint collectie dezelfde Measurement. Blijf het raar vinden. ByVal, ByRef , newen maakt allemaal niets uit.

Wat niet kan is nog nooit gebeurd


  • Nexopheus
  • Registratie: Juni 2001
  • Laatst online: 28-01 13:50
OPGELOST!!!!!!!!YEAH
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Public Function getCalibMatrix(key As Integer) As DataPointCollection
Dim strSQL As String
Dim rsCalibMatrix As ADODB.Recordset
Dim nwDataP As New DataPoint
[b]Dim nwMeas As Measurement[/b]
Dim nwCalibMatrix As New DataPointCollection

    strSQL = "SELECT * FROM Metingen WHERE Metingen.CalibID=" & key
    Set rsCalibMatrix = cnnLode.Execute(strSQL)
    Do While Not rsCalibMatrix.EOF
       [b] Set nwMeas = new Measurement[/b]
        nwMeas.rpm = Val(rsCalibMatrix.Fields(3))
        nwMeas.power = Val(rsCalibMatrix.Fields(4))
        Set nwDataP = nwCalibMatrix.add(rsCalibMatrix.Fields(1), _
        rsCalibMatrix.Fields(2), "", nwMeas)
        rsCalibMatrix.MoveNext
    Loop
    Set getCalibMatrix = nwCalibMatrix
End Function


De vet gemaakte regels zijn de regels die veranderd zijn. En het werkt nu.,....
edit:

mmmm de bold tags werken niet binnen de code tags, helaas.

Wat niet kan is nog nooit gebeurd


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 15:03

johnwoo

3S-GTE

Nog een kleine opmerking. Sommigen zullen dit misschien niet netjes vinden, maar ik zie dat je in je Datapoint en Measurement classes voor iedere property zowel een Get als een Let/Set hebt; je gebruikt hem dus puur als container, er zit verder geen functionaliteit in. Ik zou dan die property gewoon public maken, daar wordt je class een stuk korter = overzichtelijker van. En de code die de class aanspreekt kan onveranderd blijven.

code:
1
2
3
4
5
6
Option Explicit

Public Measure As Measurement
Public PowerInst As Double
Public RpmInst As Double
Public Comment As String


... is imho netter; je ziet zo meteen welke properties public zijn en hoeft niet voor iedere (private) property op te gaan zoeken of er een Get/Let voor is, en hoe die dan heet.

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
Als een declaratie als
Visual Basic:
1
Dim Blah as New BlahClass


gebruikt moet je, om een nieuw object te forceren, het ding ook een keer naar Nothing zetten. Dit om een nieuwe instantie te forceren. Als je dit niet doet, wordt telkens hetzelfde object gebruikt. ( Veranderingen in dat object, zijn dus ook veranderingen in alle objecten in je collectie )

Bijvoorbeeld:

Visual Basic:
1
2
3
4
5
6
7
8
9
Dim Blah as New BlahClass
Dim ColBlah as New BlahCollection

While DoAddToCollection
    ' Do something with Blah. Add it to a collection or so ..
    Call Blah.SetBlahProperty( "Blah ") 
    Call ColBlah.Add( Blah )
    Set Blah = Nothing
Wend


[edit]
Ik ben het dus niet echt eens met de reactie van johnwoo hierboven. Als je kortere code wilt, zou je een property Let/Get kunnen gebruiken. Ben je daarna nog vrij om extra instructies toe te voegen mocht dat nodig zijn.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 15:03

johnwoo

3S-GTE

[...]

[edit]
Ik ben het dus niet echt eens met de reactie van johnwoo hierboven. Als je kortere code wilt, zou je een property Let/Get kunnen gebruiken. Ben je daarna nog vrij om extra instructies toe te voegen mocht dat nodig zijn.
Hehe, dacht ik al :P
Die property get/lets heeft hij nu al; ik zou daar dus public properties voor gebruiken, dat is efficienter. (De class biedt direct de children aan, ipv een hele rits methods)
Maarja, als er geen objecten in gebruikt zouden worden, zou ik hier zelfs een UDT voor gebruiken, dus wie ben ik :P Het enige nadeel van een UDT tov zo'n container class (waar dus geen functionaliteit inzit) is dat ze lastiger te gebruiken zijn met collections. En daarom gebruik ik dan weer arrays ipv collections :P

(trage krengen zijn het, die collections -- maar wel makkelijk ;) )

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • Nexopheus
  • Registratie: Juni 2001
  • Laatst online: 28-01 13:50
Public member variabelen zijn natuurlijk niet echt netjes mbt OO, maar aangezien VB6 allesbehalve netjes OO is, lijkt het me niet zo'n groot probleem. Raak ik ook wat meer overhead kwijt.

Wat niet kan is nog nooit gebeurd


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
Nexopheus schreef op 08 oktober 2002 @ 11:08:
Public member variabelen zijn natuurlijk niet echt netjes mbt OO, maar aangezien VB6 allesbehalve netjes OO is, lijkt het me niet zo'n groot probleem. Raak ik ook wat meer overhead kwijt.
Dat is ook weer waar. :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1