2010-11-12 105 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); 
    } 

这是我的c#代码。我需要将其转换为vba。from c#to vba conversion(yes,kind of stupid)

我的主要问题是:

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 }; 

,我们会怎么做这在VBA?

+1

我不认为你可以在VBA中使用Linq到Objects。 – 2010-11-12 00:16:39

+2

我猜测答案会涉及循环。很多循环。 – 2010-11-12 00:18:15

回答

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 

不是最有效的..但试图按照原代码的流程..它会运行缓慢,因为它就像暴力破解循环(这里需要四分钟左右)。也许使用临时数据库/访问表通过ADO/DAO你可以使用SQL将会有所帮助。

+0

我一直用VBA的问题之一,我觉得我试图用一只手绑在背后跳绳。聪明......我希望你的建议可以通过某种临时数据存储来显着提高性能。 – IAbstract 2010-11-12 02:31:37

+0

尽管我不确定这是否是一个Office项目,但我对于为什么MS没有尝试用某种轻/动态.NET语言逐步淘汰VBA(或只是添加额外的语言)感到困惑与“现代语言”功能..我们已经在Office 2010,仍然使用VBA。虽然我明白这是为了遗留目的(他们只是在2011年的Mac OS X版本中重新实现),并且它被现有的Excel/Access解决方案大量使用。他们并没有将VB6(VB Classic)很好,他们呢?毕竟,对象模型已经存在并且可以在.NET中使用! – 2010-11-12 02:47:42

+1

“他们没有很好地对待VB6(VB Classic),是吗?” < - 恰恰相反:VB 6.0迁移到VB 7.0,这是.NET,如你所说应该完成。事实是,VBA和.NET共享相同的(COM)对象模型。而且我们也可以很容易地创建VB.NET或C#插件,因此我没有看到.NET和VBA的限制。 – 2010-11-12 23:25:29

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:在技术上你的循环应该从0到199,1到199等重新创建'跳过'部分......并且你的if语句应该总结n0(i0)+ n0(i1)+ n0(i2) + n0(i3)。如果你正在循环,那么你只需要原始数组。 – jtolle 2010-11-12 01:00:15

+0

当然,你是对的 - 编辑。 – Stu 2010-11-12 16:04:50