让它更快?

我目前有点两难。 在Macro / vba项目上工作了几个月后,事情变得非常庞大(大约4K行代码),并且由于它必须多次遍历许多列表,所以有时甚至需要半小时才能完成,有时甚至停止自己没有任何明显的原因(或错误信息)。

我发现,即使closures屏幕更新,但更快,它仍然会节省我约5/10分钟的处理。

所以我的问题是这样的:

如果程序没有使用“variables=单元格(1,x)”,而是使用“variables=工作表单”(“Sheet1”),单元格(1,x)“会有多大的速度差异?

因为它在整个事物中只在标签之间切换两次,是否值得开始重写呢?

请考虑我所有的VBA知识都是通过反复试验自我教导的,所以尽可能使用小字。

编辑:

我得到了3张大量的数据(我不创build这些数据,也不能更改信息的显示方式)。

表A列出了我公司的客户名单以及每个客户的负责人。

B表包含了过去两年内客户买卖给我公司的信息(包括成本,收益,规模,产品等信息)。

工作表C包含了我们已经设法做出新“承诺”的新产品(因此,如果我们的工人之一设法让公司1声称他们将从现在开始向我们购买产品X,那么'承诺'将出现这里列出)。

我被要求做的(和我的项目)首先填写表A中每个客户的详细信息和表B的信息(所以对于客户A,我们现在将看到他们在2014年买了X€),那么它将创build一个新的表格,显示表B中所有'承诺',都已经在表B中完成(我们详细说明的原因是因为提供的价格(单位)对于承诺的客户较低“买一定数量,问题是许多客户利用这一点,并承诺超过他们实际购买,所以我们有必要做到这一点,看看谁保持他们的话)。

在这一点上,我创build了一个“Main.xlsm”,并将信息转储到那里,从那里我必须为我们的每个员工做出优秀的细节,只详细说明他们的客户(约56名员工,你可以为什么我拼命地把它变成一个程序,而不是每当他们要求这个“报告”(至less每个月两次)手工完成。

我在不使用可怕的“.select”选项时遇到的主要问题是,我被要求给报告的某些部分提供特定的格式,这些部分高度依赖于多个variables。 这与许多检查,以确保数据没有错误某种程度上使得在我的程序中的代码行“批量”,因为他们是很多的东西,如“如果去年他们有X%更多的交付,但他们比以前支付的Y%less,那么你必须得到blablablabla,如果是Z%,那么你必须……“或者”如果客户去年购买了产品,但不是这个产品,你必须从表A(包括格式)复制整行,并把它放在一个新的表,你会命名为“没有购买”。

我开始使用像这样的东西:

With Range(Cells(row, detUnit), Cells(BottomRow, detUnit + 2)).Borders(xlEdgeTop) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With 

格式化,但我也有很多:

 Columns(prtFilesFORWINAnoMes2).Select Selection.Replace What:=" ", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False Columns(prtAfrKgAnoMes1).Select Selection.Replace What:=" ", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False 

在哪里我必须“删除”可能的错误,无论是input表A,B,C的数据都可能(而且有很多)。

为了节省一大堆时间,我也要以各种方式重组各种表格,所以我也得到了

 Rows("1:1").Select Selection.AutoFilter If ActiveSheet.AutoFilterMode = False Then Selection.AutoFilter ActiveWorkbook.Worksheets(ActiveSheet.Name).AutoFilter.Sort.SortFields.Clear ActiveWorkbook.Worksheets(ActiveSheet.Name).AutoFilter.Sort.SortFields.Add Key:=Cells(1, columnaDestiny), SortOn:=xlSortOnValues, Order:=xlAscending, _ DataOption:=xlSortTextAsNumbers With ActiveWorkbook.Worksheets(ActiveSheet.Name).AutoFilter.Sort .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With ActiveWorkbook.Worksheets(ActiveSheet.Name).AutoFilter.Sort.SortFields.Add Key:=Cells(1, columnaOrigin), SortOn:=xlSortOnValues, Order:=xlAscending, _ DataOption:=xlSortTextAsNumbers With ActiveWorkbook.Worksheets(ActiveSheet.Name).AutoFilter.Sort .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With 

实际上在每个小组的开始。

例如,这是“查看工作表C中的承诺是否在工作表B中完成”的主要代码段

 Do While row <= rowLength first = CoutryReference 'I've got to know which is the main country Select Case Cells(row, detOrigin) Case Is = CoutryReference dir = "EXPORT" 'Determine if it's Export / Import / Xtrade second = Cells(row, detDestiny) Case Else If Cells(row, detDestiny) = CoutryReference Then dir = "IMPORT" second = Cells(row, detOrigin) Else dir = "XTRADE" first = Cells(row, detOrigin) second = Cells(row, detDestiny) End If End Select If SearchInForwin(dir, first, second, Cells(row, detClient), Cells(row, detProduct)) = True Then Call FoundLine(row, dir) 'SearchInForwin will loop through the (already organized) list in Sheet B and if it finds a match ' it will copy that line to Sheet "Fulfilled" and return "TRUE" ' FoundLine will then copy the line we're currently reading the information from and paste it into "Fulfilled" as well row = row + 1 Loop 

这是SearchInForwin:

 Function SearchInForwin(direction As String, onecountry As String, othercountry As String, company As String, mode As String) As Boolean Sheets("SHEET B").Select Dim foUnd As Boolean, lookingRow As Long lookingRow = lastHiddenWon 'Since it's alphabetical by Company, with foUnd = False ' this we can jump to the last one found and start from there Do While lookingRow <= Cells(Rows.Count, forwOrigen).End(xlUp).row If Cells(lookingRow, forwEmpresa) = company Then foUnd = True 'First Loop it to quickly determine if there's a simple match If Cells(lookingRow, forwDireccion) = direction Then GoTo SecondBuc End If If (Cells(lookingRow, forwEmpresa) <> company And foUnd = True) Or Cells(lookingRow, forwAno) < yearAno Then foUnd = False 'This is because we should only take into account purchase data from the latest year (and it's pre-organized so the most recent data is on the top of the list) GoTo FIn End If lookingRow = lookingRow + 1 Loop SecondBuc: foUnd = False Do While Cells(lookingRow, forwEmpresa) = company And Cells(lookingRow, forwDireccion) = direction And Cells(lookingRow, forwAno) = yearAno 'The conditions are the only thing that keeps this second loop extremely short If Cells(lookingRow, forwAno) = yearAno And Cells(lookingRow, forwDestino) = othercountry And _ Cells(lookingRow, forwOrigen) = onecountry And InStr(1, Cells(lookingRow, forwTIPO), mode) > 0 Then Call CopyToHidden(lookingRow, mode) 'Copies the line foUnd = True lastHiddenWon = lookingRow + 1 End If lookingRow = lookingRow + 1 Loop FIn: SearchInForwin = foUnd End Function 

我可以上传我的模块的.bas,但所有的评论/variables都是西class牙语,因为我应该让潜在的同事可以看一下(这意味着他们希望能够解雇我,让别人继续我的工作,如果他们觉得)

如果问题是,速度会提高,从某种东西转换像:

 For i = 1 to 4000 If Cell(i,2) = X then ...do something EndIf 

 Set Ranges = Cell(i,2),Cell(4000,2) Loop through Variable 

那么答案就是方式会更快。 我也有类似的情况,从1000行到900K行大约有10-15张。 逐个检查细胞,花了30-60分钟,当我把它放在variables下,它是在5分钟。 至less在我的经验中,variables总是比从表单中读取要快。 我想如果你的阅读1或2次可能不明显。 ps上面没有真正的代码。