2010-11-12 10 views
0
double [] numbers = new numbers[200]; 
    numbers[0] = 123; 
    numbers[1] = 456; 

    // 
    // and so on. 
    // 

    var n0 = numbers; 
    var n1 = numbers.Skip(1); 
    var n2 = numbers.Skip(2); 
    var n3 = numbers.Skip(3); 

    var x = from a in n0 
      from b in n1 
      from c in n2 
      from d in n3 
      where a + b + c + d == 2341.42 
      select new { a1 = a, b1 = b, c1 = c, d1 = d }; 

    foreach (var aa in x) 
    { 
    Console.WriteLine("{0}, {1}, {2}, {3}", aa.a1, aa.b1, aa.c1, aa.d1); 
    } 

il y a mon code C#. j'ai besoin de le transposer en vba.de conversion de C# en vba (oui, sorte de stupide)

mon principal problème est la suivante:

var x = from a in n0 
      from b in n1 
      from c in n2 
      from d in n3 
      where a + b + c + d == 2341.42 
      select new { a1 = a, b1 = b, c1 = c, d1 = d }; 

comment pourrions-nous faire en vba?

+1

Je ne pense pas que vous pouvez utiliser Linq to Objects dans VBA. –

+2

Je suppose que la réponse impliquera des boucles. Beaucoup de boucles. –

Répondre

3
Type NumberSet 
    A As Double 
    B As Double 
    C As Double 
    D As Double 
End Type 

Public Sub TheSub() 
    Dim numbers(0 To 199) As Double 

    numbers(0) = 123 
    numbers(1) = 456 

    ' 
    ' and so on. 
    ' 

    'iterators 
    Dim ai As Integer 
    Dim bi As Integer 
    Dim ci As Integer 
    Dim di As Integer 

    'data set  
    Dim x() As NumberSet 

    'temp record holder 
    Dim ns As NumberSet 

    Dim count As Integer 

    count = 0 

    'simulate the select query 
    For ai = LBound(numbers) To UBound(numbers) 
     For bi = LBound(numbers) + 1 To UBound(numbers) 
      For ci = LBound(numbers) + 2 To UBound(numbers) 
       For di = LBound(numbers) + 3 To UBound(numbers) 
        'fill the record 
        With ns 
         .A = numbers(ai) 
         .B = numbers(bi) 
         .C = numbers(ci) 
         .D = numbers(di) 
         'test record 
         If .A + .B + .C + .D = 2341.42 Then 
          'append to the data set 
          ReDim Preserve x(0 To count) 
          x(count) = ns 
          count = count + 1 
         End If 
        End With 
       Next di 
      Next ci 
     Next bi 
    Next ai 

    'iterate through data set and print results 
    For i = LBound(x) To UBound(x) 
     ns = x(i) 
     With ns 
      Debug.Print .A & ", " & .B & ", " & .C & ", " & .D 
     End With 
    Next i 
End Sub 

pas le plus efficace .. mais a essayé de suivre le flux du code d'origine .. il fonctionnera lentement car il est comme bruteforce en boucle (prend environ quatre minutes ici) .. peut-être à l'aide temporaire base de données/table d'accès via ADO/DAO où vous pourriez utiliser SQL aiderait.

+0

Un des problèmes que j'ai toujours eu avec VBA, j'avais l'impression d'essayer de sauter avec une main attachée dans le dos. Intelligent ... Je m'attends à ce que les performances augmentent de manière significative avec une sorte de stockage de données temporaire comme vous le suggérez. – IAbstract

+0

Bien que je ne sois pas sûr que ce soit spécifiquement un projet Office, mais je suis étonné de voir pourquoi MS n'a pas essayé d'éliminer VBA (ou juste d'ajouter une langue supplémentaire) avec un langage léger/dynamique .NET avec des fonctionnalités "langage moderne" .. nous sommes déjà à Office 2010 et toujours en utilisant VBA. Bien que je comprenne qu'il est là pour un but d'héritage (et ils ont juste ré-implémenté dans la version Mac OS X 2011), et il est fortement utilisé par les solutions Excel/Access existantes .. ils n'ont pas traité VB6 (VB Classic) aussi bien, ont-ils? Après tout, le modèle d'objet est déjà là et utilisable dans .NET! –

+1

"Ils n'ont pas traité VB6 (VB Classic) aussi bien, n'est-ce pas?" <- Tout le contraire: VB 6.0 a migré vers VB 7.0, qui est .NET, comme vous l'avez suggéré devrait être fait. La vérité est que VBA et .NET partagent le même modèle d'objet (COM). Et on peut faire des compléments VB.NET ou C# sans trop de problèmes non plus, donc il n'y a pas de limitation avec .NET ou avec VBA, comme je le vois. –

2
Dim N(200) 

For I0 = 0 To 199 
    For I1 = 1 To 199 
    For I2 = 2 To 199 
     For I3 = 3 To 199 
     If N(I0)+N(I1)+N(I2)+N(I3) = 2341.42 Then 
      Debug.Print N(I0) & "," & N(I1) & "," & N(I2) & "," & N(I3) 
     End If 
     Next 
    Next 
    Next 
Next 
+0

Nitpick: techniquement, vos boucles devraient aller de 0 à 199, de 1 à 199, etc. pour recréer la partie 'Sauter' ... et votre instruction if devrait juste résumer n0 (i0) + n0 (i1) + n0 (i2) + n0 (i3). Si vous bouclez alors vous auriez juste besoin du tableau original. – jtolle

+0

Vous avez raison, bien sûr - édité. – Stu