Je concevons un tampon dynamique pour les messages sortants. La structure de données prend la forme d'une file d'attente de nœuds disposant d'un tampon de réseau d'octets en tant que membre. Malheureusement, dans la VBA, les tableaux ne peuvent être membres d'une classe.
Par exemple, il s'agit d'un non-non et de ne pas compiler: p> Vous obtiendrez ce qui suit Erreur: "Constantes, chaînes de longueur fixe, tableaux, types définis par l'utilisateur et déclarations déclarations non autorisées en tant que membres du public de modules d'objets" p> Eh bien, ça va, je vais juste en faire un membre privé avec Accessoires de propriété publique ... p> ... et quelques tests dans un module pour vous assurer qu'il fonctionne: p> test n ° 1 fonctionne bien, test n ° 2 fonctionne maintenant! GSERG souligne que pour appeler la propriété Test n ° 3 échoue - La valeur d'origine de 3 est imprimée sur la fenêtre immédiate. Gserg a souligné dans son commentaire selon lequel la propriété publique (Je devrais clarifier que la question générale est "VBA ne permet pas aux tableaux d'être membres du public de classes . Comment puis-je contourner cela pour avoir un membre de la matrice d'une classe qui se comporte comme si c'était à toutes fins pratiques, notamment: # 1 attribuer à la matrice, n ° 2 Obtenir des valeurs de la matrice, n ° 3 Attribuant des valeurs dans le tableau et # 4 Utilisation du tableau directement dans un appel à mais test # 2 pauses, tampon code> est mis en surbrillance et le message d'erreur est "Nombre erroné d'arguments ou assignation de propriété non valide" del> p> Obtenir la mémoire tampon () code> correctement et également faire référence à un index spécifique dans la mémoire tampon, deux ensembles de parenthèses forts> sont nécessaires: Obuffer.buffer () (2) Code> P> Obtenir la mémoire tampon () code> ne renvoie qu'une copie et non le tableau des membres de la classe actuelle, de sorte que les modifications sont perdues. P> CopyMemory code> (# 3 et # 4 sont presque équivalents)?) " Em> p> p> P> P>
3 Réponses :
Pas la solution la plus élégante, mais la modélisation du code que vous avez fourni ...
dans Crstest: p> et dans mdlmain: p> Sub test()
Dim buf() As Byte
Dim bufnew() As Byte
Dim oBuffer As New clsTest
ReDim buf(0 To 4)
buf(0) = 1
buf(1) = 2
buf(2) = 3
buf(3) = 4
oBuffer.AssignArray vInput:=buf
Debug.Print oBuffer.GetArrayValue(lItemNum:=2)
oBuffer.AssignArray vInput:=27, lItemNum:=2
Debug.Print oBuffer.GetArrayValue(lItemNum:=2)
bufnew() = oBuffer.GetWholeArray
Debug.Print bufnew(0)
Debug.Print bufnew(1)
Debug.Print bufnew(2)
Debug.Print bufnew(3)
End Sub
Désolé je suis allé si longtemps sans répondre! Le problème avec cette méthode est que bufnew () = obuffer.getwholarray () code> crée une copie de l'ensemble de la matrice. Cela pourrait ne pas sembler un gros problème, mais supposons que nous parlions d'un tableau de 2 Go ... cela serait sucer :(
@blackhawk,
Je sais que c'est un ancien post, mais je pensais que je l'affaiterais de toute façon. p>
ci-dessous est un code que j'ai utilisé pour ajouter un tableau de points à une classe, je Utilisé une sous-classe pour définir les points individuels, il semble que votre défi est similaire: p>
MAINCLASS TCURVE strong> P> Option Explicit
Private pSlope As Double
Private pCurvature As Double
Private pY As Variant
Private pdY As Double
Private pRadius As Double
Private pArcLen As Double
Private pChordLen As Double
Public Property Let Slope(Value As Double)
pSlope = Value
End Property
Public Property Get Slope() As Double
Slope = pSlope
End Property
Public Property Let Curvature(Value As Double)
pCurvature = Value
End Property
Public Property Get Curvature() As Double
Curvature = pCurvature
End Property
Public Property Let valY(Value As Double)
pY = Value
End Property
Public Property Get valY() As Double
valY = pY
End Property
Public Property Let Radius(Value As Double)
pRadius = Value
End Property
Public Property Get Radius() As Double
Radius = pRadius
End Property
Public Property Let ArcLen(Value As Double)
pArcLen = Value
End Property
Public Property Get ArcLen() As Double
ArcLen = pArcLen
End Property
Public Property Let ChordLen(Value As Double)
pChordLen = Value
End Property
Public Property Get ChordLen() As Double
ChordLen = pChordLen
End Property
Public Property Let dY(Value As Double)
pdY = Value
End Property
Public Property Get dY() As Double
dY = pdY
End Property
Merci pour cela! Les fonctions accessoires que vous avez pour obtenir et définir des valeurs de remplissage définitivement les exigences n ° 2 et n ° 3, mais malheureusement, cela ne satisfait pas aux exigences n ° 1 (pouvoir définir le tampon entier directement d'un existant) et # 4 (être capable de Obtenez une référence directe au tampon afin que je puisse copymemory ()))
Il s'avère donc que j'avais besoin d'un peu d'aide d'Oleaut32.dll, spécifiquement le 'varianteCopy' fonction. Cette fonction rend fidèlement une copie exacte d'une variante à une autre, y compris quand elle est BYREF! Em> avec cette nouvelle définition, tous les tests passent! P > 'mdlMain
Public Sub Main()
Dim buf() As Byte
ReDim buf(0 To 4)
buf(0) = 1
buf(1) = 2
buf(2) = 3
buf(3) = 4
Dim oBuffer As clsTest
Set oBuffer = New clsTest
'Test #1, the assignment
oBuffer.Buffer = buf 'Success!
'Test #2, get the value of an index in the array
Debug.Print oBuffer.Buffer()(2) 'Success! This is from GSerg's comment on the question
'Test #3, change the value of an index in the array and verify that it is actually modified
oBuffer.Buffer()(2) = 27
Debug.Print oBuffer.Buffer()(2) 'Success! Diplays "27" in the immediate window
End Sub
J'ai rencontré ce problème lors de la création d'une structure de données pour faire tamponner les messages sortants pour certains code de réseautage. J'étais finalement capable de le résoudre, mais puisque je n'ai pas trouvé la question à ce sujet, je pensais que je l'ajouterais. Si quelqu'un connaît la réponse, n'hésitez pas à l'ajouter! Si quelqu'un d'autre l'obtient avant de pouvoir poster la réponse, je vais accepter.
Si vous vouliez réellement copier la matrice à chaque fois, vous avez oublié par parenthèses ,
obuffer.buffer () ( 2) code>. Sinon, vous voudrez peut-être avoir un look. ici .@Gserg c'est la solution que j'ai réalisée - je pourrais faire quelque chose comme changer l'accessoir vers
Propriété publique Obtenir la mémoire tampon (index aussi longtemps) que l'octet code> Si tout ce que je voulais faire était d'accéder à des articles individuels dans le tableau, mais Dans mon cas, je dois utiliser le tampon dans une déclaration code> CopyMemory code>, de sorte que cela ne fonctionnerait pas.@Gserg je joue en fait avec la création de ma propre classe
clsbytearray code> en utilisantheaphoc code> etheapfree code> pour contourner le fait que vba copie réseaux pour missions au lieu de le faire par référence. Savez-vous s'il existe une façon d'utiliser des variantes pour transmettre une référence du même tableau en mémoire? (leheaphoc code> etheapfree code> la méthode fuite si l'utilisateur clique sur le bouton d'arrêt du débogueur: '(Ce n'est donc pas mon premier choix pour une solution)Vous pouvez Construire un descripteur de tableau sur les données existantes (d'autres arraches). Ou vous pouvez conserver le modèle accessoir, ajoutez simplement une autre propriété qui retournerait le pointeur (VARPTR) au premier membre du tableau, que vous pouvez ensuite passer à
CopyMemory code>.@Gserg drôle chose - je suis allé à upvote la réponse et j'ai réalisé que j'avais déjà fait déjà déjà fait à un moment donné dans le passé ... J'ai déjà un type de safearray que j'avais utilisé pour une fonction code> getdims code>. Je vais jouer avec ça. J'aime la suggestion d'utiliser une propriété pour simplement obtenir l'adresse de la matrice d'octet en mémoire, et je pense que je pourrais l'utiliser plutôt car il y aurait moins de risque de faire référence à la mémoire traitée. J'apprécie toute l'entrée! Si vous voulez copier / coller vos commentaires en une réponse, je peux accepter.
Que diriez-vous d'utiliser une méthode pour définir les valeurs
SETValue (valeur BYVAL sous forme d'octet, index byval comme entier) code>@ ja72 pire qu'un propriété que nous avons mentionnée ci-dessus.