2009-03-27 5 views
15

Depuis plus de 10 ans que j'utilise VB6, de temps en temps, je reçois une erreur de type «erreur de type d'argument ByRef» dans laquelle je ne trouve tout simplement pas la différence. Après avoir lutté pendant un moment, j'ai toujours piqué en forçant le type d'une manière ou d'une autre, mais cette fois j'ai pensé que je demanderais. J'inclus tout le code que je pense pourrait avoir n'importe quoi faire avec ceci; mais vous pouvez l'ignorer maintenant et y faire référence après que j'ai démontré le problème:VB6 - Erreur d'incompatibilité de type d'argument ByRef - où est-ce?

Public Type PBufferType 
    Location(9) As Integer ' code location 
    ValueHi(9) As Integer ' Vhi code 
    ValueLo(9) As Integer ' Vlo code 
    Locked(9) As Integer ' State of pair 
    Gamma(9) As Single  ' Gamma between this segment and next 
End Type 

Public GammaBuffer(1) As PBufferType ' The main data type 

Public SelectedBank as Integer 

Function MeasureLuxAtCode(code As Integer) As Single 
    Call TestPatternForm.DrawTestWindow(3, code) 
    MeasureLuxAtCode = MeasureLux(1) 
End Function 

Le problème se produit ci-dessous. La ligne "LuxMinTarget = MeasureLuxAtCode (FirstLevel)" génère une erreur de type "ByRef argument mismatch", indiquant que FirstLevel n'est pas un entier.

 
Sub DetermineIdealLuxCurve() 
    Dim FirstLevel, FirstDACtoMeasure As Integer 
    FirstDACtoMeasure = 0 
    FirstLevel = GammaBuffer(SelectedBank).Location(FirstDACtoMeasure) 
    LuxMinTarget = MeasureLuxAtCode(FirstLevel) 
End Sub 

Mais il dang, FirstLevel est un entier, non? Il est dim'ed un int, sa valeur est définie par un UDT qui renvoie un int, alors où est-ce que je me trompe? Si je force à un int comme ceci:

 
    LuxMinTarget = MeasureLuxAtCode(Int(FirstLevel)) 

le compilateur/interpréteur est heureux. Mais je ne suis pas.

Alors, est-ce un bug dans le compilateur ou juste moi étant dense?

+0

Où sont définis SelectedBank et FirstDACtoMeasure? –

+0

J'ai édité la question pour ajouter ces deux variables. SelectedBank = entier global et FirstDACtoMeasure = entier local. –

+0

Vous ne pouvez l'obtenir que lorsque vous appelez un sous-système/une fonction dont les paramètres sont transmis par référence. Quelles sont les définitions de SelectedBank, FirstDACtoMeasure, DrawTestWindow() et MeasureLux()? –

Répondre

39

Le problème est ici:

Dim FirstLevel, FirstDACtoMeasure As Integer 

Ce fait FirstLevel déclare comme Variant et non comme un Integer comme on pouvait s'y attendre.

Ceci est un classique gotch VB6! (et vous n'êtes pas le premier à être mordu par elle).

Déclarant une variable par ligne évite le problème:

Dim FirstLevel As Integer 
Dim FirstDACtoMeasure As Integer 
+0

Bah. Je n'ai pas remarqué ça. Bon appel. –

+7

Wow, pour comprendre que, après une décennie, je n'ai pas compris la déclaration "Dim" ... J'ai besoin d'un verre! Merci! –

+0

VB6 est tous les gotchas: - | – TheCrazyProgrammer

1

Comme Mitch a souligné, VB6 déclare que la dernière variable dans une liste délimitée par des virgules comme explicitement du type défini. Les entrées précédentes sont déclarées, mais en tant que variantes.

Pour que les variables soient correctement déclarées, vous devez les gérer individuellement.

Dim FirstLevel As Integer 
Dim FirstDACtoMeasure As Integer 

C'était aussi le cas dans les versions précédentes de VB, IIRC, pas nouveau pour VB6.

4

John T, Vous pouvez actuellement déclarer explicitement des variables dans une liste.

Dim FirstLevel as Integer, FirstDACtoMeasure As Integer

+0

Merci. J'en étais conscient, et j'aurais probablement dû le signaler, même si j'utilise habituellement l'approche un par ligne pour plus de clarté. –

+1

Vous pouvez, mais vous ne devriez pas. Une déclaration de variable par ligne est une pratique courante. –

Questions connexes