2015-04-22 37 views
2

大家好,让我们开始通过给我的项目一些简要背景,然后我会跟进我的具体问题和代码。压缩很大程度上(不切实际)基于循环的VBA代码;嵌套对于...下一个循环

目前我正在构建一个程序来自动化填充模板的过程。这个模板经常超过60,000行数据,并且我通过插入新数据表并运行它来构建它的大部分工作来逐月运行。目前所有的工作都是基于一个数据表,我手动导入到excel中。此数据表不包含我需要的所有数据以填充模板,所以现在我开始引入其他数据来补充这一点。这里的问题在于数据关联。当我最初从一张数据表中拉出来时,我不必担心我为每行提取的数据是否与其他行一致,因为它们全部来自同一张表。现在我必须跨两张纸交叉检查数据,以确认它正在提取正确的信息。

现在为你所需要知道的。我试图填写一个将被称为理发的专栏,但在此之前,我需要确认我正在将相关的正确剪发号码与已在上一行中填充到模板中的Trade ID相关联码。

使用我在整个项目中使用的类似逻辑,这是我必须执行此任务的一段代码。

Dim anvil as Worksheet 
    Dim ALLCs as worksheet 
    Dim DS as worksheet 
    '''''''''''''''''''''''''''''code above this line is irrelevant to answer this question 
    ElseIf InStr(1, DS.Cells(x, 2), "Haircut") Then 
    Anvil.Select 
     For y = 1 To 80 
      If Anvil.Cells(1, y) = "Haircut" Then 
       For Z = 1 To 80 
        If Anvil.Cells(1, Z) = "Trade ID" Then 
         For t = 2 To 70000 
          For u = 16 To 70000 
           If Anvil.Cells(t, Z) = ALLCs.Cells(u, 34) Then 
           ALLCs.Cells(u, 27) = Anvil.Cells(t, y) 
           End If 
          Next 
         Next 
        End If 
       Next 
      End If 
     Next 

此代码加上我其他的代码我认为在理论上的工作将,但我只能想象,这将需要时间一个令人难以置信的金额(这项计划已经花费7分半钟运行)。有关如何使用更好的功能重写此代码的任何建议,请遵循此一般逻辑?

无论您是否完全修改代码,或者如果您提供关于如何减少循环的建议,都可以获得任何帮助。除了屏幕更新和计算建议之外,我还在寻找建议来加快一般代码的速度。

+0

我在代码方面给出了一个答案正在减少 - 但是要求关于加速代码的一般建议稍微超出了SO的范围。如果你有一个特定的例子,那么你可以把它作为一个单独的问题发布,或者甚至将你的代码提交给代码评论网站 - 希望帮助:) –

+1

WOW!可能会有31万亿次循环,我敢打赌一个过滤器可以做你所要求的,即使动态设置范围也可以帮助,正如其他人所说的那样,将我们链接到示例工作簿 – Davesexcel

+2

作为CR常规(以及顶级VBA评论员在CR),我同意@SOofWXLS,张贴*您的完整工作代码* over [codereview.se]将大大提高此代码的性能,可读性和可维护性。 –

回答

4

如果我理解正确的逻辑,那么你可以像这样用.Find()方法全部更换,但环中的一个:

'// Dimension range objects for use 
Dim hdHaricut As Excel.Range 
Dim hdTradeID As Excel.Range 
Dim foundRng As Excel.Range 

With Anvil 
    With .Range("A1:A80") '// Range containing headers 
     '// Find the cell within the above range that contains a certain string, if it exists set the Range variable to be that cell. 
     Set hdHaircut = .Find(What:="Haircut", LookAt:=xlWhole) 
     Set hdTradeID = .Find(What:="Trade ID", LookAt:=xlWhole) 
    End With 
    '// Only if BOTH of the above range objects were found, will the following block be executed. 
    If Not hdHaricut Is Nothing And Not hdTradeID Is Nothing Then 
     For t = 2 To 70000 
      '// Using the .Column property of the hdTradeID range, we can see if the value of Cells(t, hdTradeColumn) exists 
      '// in the other sheet by using another .Find() method. 
      Set foundRng = ALLCs.Range(ALLCs.Cells(16, 34), ALLCs.Cells(70000, 34)).Find(What:=.Cells(t, hdTradeID.Column).Value, LookAt:=xlWhole) 
      '// If it exists, then pass that value to another cell on the same row 
      If Not foundRng Is Nothing Then ALLCs.Cells(foundRng.Row, 27).Value = .Cells(t, hdHaircut.Column).Value 
      '// Clear the foundRng variable from memory to ensure it isn't mistaken for a match in the next iteration. 
      Set foundRng = Nothing 
     Next 
    End If 
End With 
+0

好的一点,我从来没有想过使用'.Find' –

+0

我从来没有用过 - 但是我的工作环境是报告格式永远改变以满足用户需求,所以'.Find()'很快成为我最好的朋友。使用标题! –

+0

我不熟悉.find函数,因此我不确定它是否能按预期工作。让我结合你的答案做一些研究,我会尽快回复你。这发现Rng变量看起来希腊我atm。 – dom176