VBA Array Trier avec Fieldname en tant que paramètre

Voici l'affaire … En essayant de passer ma peur de Class Modules dans Excel VBA, j'ai décidé de créer une class qui est un tableau, puis d'append des fonctions (methods) pour append des éléments, sortinger une instance, etc. Ce sont des choses Je continue à réécrire dans les modules normaux en tant que fonctions / sous-stations, mais j'espère que l'utilisation des classs pourrait être un pas en avant.

Module de code

Public Type Thing Name As Ssortingng SomeNumber As Double End Type 

Module de class

 Private pSomething() As Thing 

Ceci est suivi de tous les LET publics et GET habituels, plus une fonction pour insert de nouvelles valeurs dans le tableau. Ensuite, j'arrive à la fonction / méthode de sorting. Il n'y a pas de problème avec le sorting par Nom ou SomeNumber, mais jusqu'à présent prend deux fonctions / methods. Je voudrais paramétrer dans une seule fonction / mehod puis utiliser un paramètre optionnel pour contrôler quel champ doit être utilisé. Les travaux suivants, mais il semble un peu clunky

 Function SortByField(Optional FieldName As Ssortingng, Optional SortOrder As vbaSortOrder) Dim strTemp As Thing If SortOrder = 0 Then SortOrder = soBottomToTop If Len(FieldName) = 0 Then FieldName = "Name" Dim i As Long Dim j As Long Dim lngMin As Long Dim lngMax As Long lngMin = LBound(pSomething) lngMax = UBound(pSomething) For i = lngMin To lngMax - 1 For j = i + 1 To lngMax If IIf(SortOrder = soBottomToTop, _ IIf(FieldName = "Name", pSomething(i).Name > pSomething(j).Name, _ pSomething(i).SomeNumber > pSomething(j).SomeNumber), _ IIf(FieldName = "Name", pSomething(i).Name < pSomething(j).Name, _ pSomething(i).SomeNumber < pSomething(j).SomeNumber)) _ Then strTemp = pSomething(i) pSomething(i) = pSomething(j) pSomething(j) = strTemp End If Next j Next i End Function 

Ce que j'aimerais faire, c'est replace le suivant (et c'est pair dans la deuxième partie de cette IF (IIF …) incroyable

 IIf(FieldName = "Name", pSomething(i).Name > pSomething(j).Name, pSomething(i).SomeNumber > pSomething(j).SomeNumber) 

… avec quelque chose comme ça

 "pSomething(i)." & FieldName > "pSomething(j)." & FieldName 

Question directe: Comment puis-je get la string à évaluer / convertir en code?

Question indirecte: Existe-t-il une autre technique pour passer un nom de terrain et l'avoir traité comme autre chose qu'une string?

Merci d'avance pour toute aide, assistance, orientation, direction, references, conseils, ceci est une erreur de fou, ou des commentaires dérisoires :).

BiggerDon, j'essayais de suivre votre code et vous avez raison, l'IIF nested est génial. Puis-je vous suggérer de réécrire le code avec les instructions SELECT CASE. Cela pourrait aider un peu. En outre, quel est le gros objective que vous essayez d'atteindre? Cela ressemble presque à une overkill pour un tableau à une seule dimension.

Il pourrait y avoir d'autres Excel VBA construit dans des methods sur lesquelles vous pouvez exploiter.

Je viens de faire une search rapide sur Internet pour sortinger les Arrays et j'ai rencontré le site Web de Pearson http://www.cpearson.com/excel/SortingArrays.aspx

Vous pourriez vérifier quoi que ce soit.

@BiggerDon, Que diriez-vous d'une class de type personnalisé avec une propriété pour chacun de vos champs. Faites une boucle dans les loggings et ajoutez-les à une collection de la class personnalisée. Lorsque vous faites cela, vous déterminez quel champ sera utilisé comme key pour la collecte. Ensuite, utilisez quelque chose comme présenté ici. Comment sortinger une collection?

Considérez une approche basée sur des classs personnalisées au lieu de types, et en utilisant la méthode Eval() de VBScript pour évaluer la valeur du champ de l'élément.

Placez le code ci-dessous dans le module VBA :

 Sub TestStorage() Dim Room As New Storage Dim i As Long Dim Elem As Object Dim Item As Variant Dim Result As Ssortingng For i = 1 To 10 Set Elem = New OrdinalType Elem.Name = GetRandomFruit Elem.Index = i Room.Push Elem Next For i = 11 To 20 Set Elem = New ExtendedType Elem.Name = GetRandomFruit Elem.Index = i Elem.Additional = "Extended" Room.Push Elem Next Set Elem = Nothing ShowList Room.GetContent Room.SortByField "Name", True ShowList Room.GetContent Room.SortByField "Index", False ShowList Room.GetContent End Sub Sub ShowList(Arr) Result = "" For Each Item In Arr Result = Result & Item.Name & " (" & Item.Index & ")" If TypeName(Item) = "ExtendedType" Then Result = Result & " " & Item.Additional End If Result = Result & vbCrLf Next MsgBox Result End Sub Function GetRandomFruit() Dim Fruits Randomize Fruits = Array("Apple", "Apricot", "Banana", "Bilberry", "Blackberry", "Blackcurrant", "Blueberry", "Coconut", "Currant", "Cherry", "Cherimoya", "Clementine", "Date", "Damson", "Durian", "Elderberry", "Fig", "Feijoa", "Gooseberry", "Grape", "Grapefruit", "Huckleberry", "Jackfruit", "Jambul", "Jujube", "Kiwifruit", "Kumquat", "Lemon", "Lime", "Loquat", "Lychee", "Mango", "Mangostine", "Melon", "Cantaloupe", "Honeydew", "Watermelon", "Rock melon", "Nectarine", "Orange", "Passionfruit", "Peach", "Pear", "Plum", "Prune", "Pineapple", "Pomegranate", "Pomelo", "Raisin", "Raspberry", "Rambutan", "Redcurrant", "Satsuma", "Strawberry", "Tangerine", "Ugli Fruit") GetRandomFruit = Fruits(LBound(Fruits) + Round(Rnd * (UBound(Fruits) - LBound(Fruits)))) End Function 

Ajouter une reference à Microsoft Script Control ActiveX (Menu – devises – Références).
Placez le code ci-dessous dans VBA Class Module , Name Storage :

 Private Content As Variant Private SC As MSScriptControl.ScriptControl Private Sub Class_Initialize() Set SC = New MSScriptControl.ScriptControl SC.Language = "VBScript" SC.ExecuteStatement "Function EvalProp(Item, Name): EvalProp = Eval(""Item."" & Name): End Function" Content = Array() End Sub Private Function GetValue(ObjectInstance, PropertyName) GetValue = SC.Run("EvalProp", ObjectInstance, PropertyName) End Function Public Sub Push(Item) ReDim Preserve Content(UBound(Content) + 1) Set Content(UBound(Content)) = Item End Sub Public Function Pop() Set Pop = Content(UBound(Content)) ReDim Preserve Content(UBound(Content) - 1) End Function Public Sub SortByField(Optional PropName As Ssortingng = "Name", Optional SortAsc As Boolean = True) Dim i As Long Dim j As Long Dim l As Long Dim u As Long Dim a As Variant Dim b As Variant Dim tmp As Object l = LBound(Content) u = UBound(Content) For i = l To u - 1 For j = i + 1 To u a = GetValue(Content(i), PropName) b = GetValue(Content(j), PropName) If (a > b And SortAsc) Or (a < b And Not SortAsc) Then Set tmp = Content(j) Set Content(j) = Content(i) Set Content(i) = tmp End If Next j Next i End Sub Public Function GetContent() GetContent = Content End Function Public Function GetSize() GetSize = UBound(Content) - LBound(Content) + 1 End Function 

Placez le code ci-dessous dans VBA Class Module , Nom OrdinalType :

 Public Name As Ssortingng Public Index As Double 

Placez le code ci-dessous dans VBA Class Module , Name ExtendedType :

 Public Name As Ssortingng Public Index As Double Public Additional As Ssortingng 

Cet exemple montre comment créer et stocker les instances de différents types dans l'object de stockage qui est capable de traiter ces types, dans ce cas particulier – pour les sortinger en prenant une string comme un nom de champ de sorting. Notez qu'une telle injection de VBS est anormale et, en général, elle n'est pas une bonne pratique. En ce qui concerne la vitesse de traitement – Function GetValue() appel Function GetValue() prend environ 15 mksecs sur mon N7110.