我目前处于两难境地。经过几个月的Macro / vba项目后,事情变得越来越大(大约4K行代码)并且因为它必须多次循环遍历许多列表,有时可能需要半小时才能完成,有时甚至会停止拥有没有任何明显的理由(或错误信息)。
我发现即使关闭屏幕更新后,虽然速度更快,但仍然可以节省大约5/10分钟的处理时间。
所以我的问题是:
如果程序没有使用“Variable = Cells(1,x)”而是使用“Variable = Worksheets(”Sheet1“),那么速度会有多大差异。单元格(1,x) “?
因为它在整个选项中只在选项卡之间切换两次,是否值得开始重写它以便它不会?
请考虑我的所有VBA知识都是通过反复试验自学,所以尽可能使用小词。
修改
我得到3张包含大量数据的内容(我不创建这些数据,也不能更改显示信息的内容和方式)。
表A列出了我公司的客户以及每个账户的负责人。
表B包含详细说明客户在过去两年内购买/出售给我公司的数据(包括成本,收入,规模,产品等信息)。
表C包含我们设法为其制定新“承诺”的新产品(因此,如果我们的一名员工设法让公司1声称他们将从现在开始向我们购买产品X,那么'承诺' '将在此处列出)。
我被要求做的(以及我的项目)首先用表B中的信息填写表A中每个客户的详细信息(因此对于客户A我们现在看到他们购买了X€in然后它将创建一张新表,显示表C中已经“完成”的所有“承诺”(我们详细说明这些是因为提供的价格(每单位)将低于客户'' '承诺'购买一定金额。问题在于许多客户利用这一点并承诺比他们实际购买的更多,所以我们需要做到这一点,看看谁在遵守他们的言论。)
此时,我创建了一个“Main.xlsm”并将信息转储到那里,从那里我必须为每位员工制作精益求精,仅详细说明客户的信息(大约有56名员工,你可以想想为什么我拼命地把它变成一个程序,而不是每次他们要求这个“报告”(至少每月两次)时手工完成。)
我没有使用可怕的“.select”选项时遇到的主要问题是我被要求为报表的某些部分提供特定格式,这些格式高度依赖于多个变量。这个以及大量的检查以确保数据没有错误以某种方式使我的程序中的代码行“大量”,因为他们有很多事情,如“如果去年他们有超过X%的交付,但他们支付Y%少于之前的那个,那么你必须使用blablablabla,如果它是Z%减去你必须...“或”如果客户去年购买但不是这个,你必须复制工作表A(包括格式)中的整行,并将其放在一个新的工作表上,您将其命名为“No Purchases”。
我开始使用像:
这样的东西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
我必须'删除'潜在的错误,无论输入的是表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
实际上在每个Sub的开头。
作为一个例子,这是“看看表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,但所有的评论/变量都是西班牙语,因为我应该让可能需要看一眼的潜在同事'可以理解'(意思是他们想要能够解雇我并让别人继续我的工作,如果他们愿意的话)
答案 0 :(得分:2)
如果问题是,那么速度会提高,以便从类似的东西切换:
contxt.save(nil) {
print(newItem)
// Navigate Back To Root vc
self.navigationController!.popToRootViewControllerAnimated(true)
}
func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
到
For i = 1 to 4000
If Cell(i,2) = X then
...do something
EndIf
然后答案是它会更快地完成。我有类似的情况,大约10-15张,从1000行到900K行。逐个细胞检查,花费30-60分钟,当我把它放入变量时,它是在5分钟内。至少根据我的经验,变量总是比从表格读取更快。我想如果你的阅读量是1或2倍,那么它可能并不明显。附:不是真正的代码。