Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 提高宏循环速度,在c上进行数据转换。76000行数据_Vba_Performance_Excel - Fatal编程技术网

Vba 提高宏循环速度,在c上进行数据转换。76000行数据

Vba 提高宏循环速度,在c上进行数据转换。76000行数据,vba,performance,excel,Vba,Performance,Excel,我已经尝试了两种不同的方式来配置我拥有的电子表格工具,用于将客户提供的数据转换为我们自己的数据代码 数据集可能特别大(这是76335行),因此宏性能非常重要 我尝试的第一种方法是将一系列索引/匹配公式记录到VBA中,让代码将它们插入到M到Y列中,并向下拖动到原始数据集中最后一行所在的位置(位于a到J列中)。这些公式中只有一个是数组公式,我尝试过不使用数组公式的代码,但总体上没有什么好处。这种方法(我们称之为方法A)花费了14分8秒(使用i7-2600 CPU和8GB RAM的Windows PC

我已经尝试了两种不同的方式来配置我拥有的电子表格工具,用于将客户提供的数据转换为我们自己的数据代码

数据集可能特别大(这是76335行),因此宏性能非常重要

我尝试的第一种方法是将一系列索引/匹配公式记录到VBA中,让代码将它们插入到M到Y列中,并向下拖动到原始数据集中最后一行所在的位置(位于a到J列中)。这些公式中只有一个是数组公式,我尝试过不使用数组公式的代码,但总体上没有什么好处。这种方法(我们称之为方法A)花费了14分8秒(使用i7-2600 CPU和8GB RAM的Windows PC)

我认为如果让VBA进行excel公式所做的计算,会提高性能,因此我运行了以下循环(方法B)

这竟然花了27分27秒。尽管有
Application.Calculation=xlCalculationManual
Application.screenupdate=False
Application.EnableEvents=False
,这仍然存在

为什么VBA计算方法较慢?这是否与我的循环效率低下有关?这可能是因为VBA必须来回引用电子表格的值吗


如能提供一般指导和建议,将不胜感激。我知道我有一个很大的数据集,但我希望能够以14分钟以上的速度运行此转换代码。

您需要使用数组-我已经切换了您的代码,并将所有内容放入数组中以完成大部分工作:

Sub SpeedUp()
Dim iLastRow As Long, iLastCol As Long, i As Long
Dim Arry() As Variant

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableEvents = False

iLastRow = ActiveSheet.Cells(Rows.Count, "F").End(xlUp).Row
iLastCol = ActiveSheet.Cells(5, Columns.Count).End(xlToLeft).Column 'I'm assuming Row 1 is the header row. Also, if you're creating colums (to column Y) then just change this to "iLastCol = 25"

ReDim Arry(1 To iLastRow, 1 To iLastCol) ' This array is a 2 dimensionnel array and you can referance rows/columns within it like you would using Cells([Row number],[Column number])
Arry = Range(Cells(1, 1), Cells(iLastRow, iLastCol))

For i = 6 To iLastRow
    If Arry(i, 13) = "BIN" Then '13 corresponds to column M
        Arry(i, 14) = "Duplicate"
    Else
        Arry(i, 14) = Arry(i, 2) & "-" & Arry(i, 4) & "-" & Arry(i, 13)
    End If

    If Arry(i, 2) = "Duplicate" Then
        Arry(i, 15) = "D"
        Else
        Arry(i, 15) = "N"
    End If

    If Arry(i, 5) = "Groundwater" Then
        Arry(i, 16) = "WG"
        ElseIf Arry(i, 5) = "Leachate" Then
        Arry(i, 16) = "LE"
        ElseIf Range("E2") = "Surface water" Then
        Arry(i, 16) = "WS"
        Else
        Arry(i, 16) = "Other"
    End If

'Plus another six If statements similar to the above to populate Cols P to Y... Not included here to keep this code on StackOverflow easier to read
Next i

ThisWorkbook.Worksheets("CONVERSION").Range(Cells(1, 1), Cells(iLastRow, iLastCol)) = Arry ' Sets all the values

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True

End Sub

如果你把它发布到代码审查网站上,你可能会在这个问题上做得更好-他们处理的是提高代码的性能,而对于不起作用的代码,你可以从数组中尝试它,而不是varArray=range(“a1:x70000”)。value并解决这个问题。另外,看看range(“P”&i)=开关(不是速度提升,但您没有在此工作簿中使用
。工作表(“转换”)…以
块结尾。您引用的块中的每个范围都在使用,例如,
范围(“M”&i)
。这将仅在当前活动的工作表上操作。您需要在范围前加上句号/句号,以便它在转换工作表上工作,具体如下:
.range(“M”和i)
这看起来不错,但我收到消息“编译错误:无法分配到数组”…@AndrewAbbott My bad-现在应该可以工作了。请告诉我您得到的时间我还不太清楚,现在出现运行时错误13类型不匹配…可能值得添加的是,我的标题行实际上在第5行。仅供参考,我需要删除
此工作簿。Worksheets(“转换”)
零件来源Arry@AndrewAbbott对不起,你是对的(从未测试过!)-我再次调整了它
Sub SpeedUp()
Dim iLastRow As Long, iLastCol As Long, i As Long
Dim Arry() As Variant

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableEvents = False

iLastRow = ActiveSheet.Cells(Rows.Count, "F").End(xlUp).Row
iLastCol = ActiveSheet.Cells(5, Columns.Count).End(xlToLeft).Column 'I'm assuming Row 1 is the header row. Also, if you're creating colums (to column Y) then just change this to "iLastCol = 25"

ReDim Arry(1 To iLastRow, 1 To iLastCol) ' This array is a 2 dimensionnel array and you can referance rows/columns within it like you would using Cells([Row number],[Column number])
Arry = Range(Cells(1, 1), Cells(iLastRow, iLastCol))

For i = 6 To iLastRow
    If Arry(i, 13) = "BIN" Then '13 corresponds to column M
        Arry(i, 14) = "Duplicate"
    Else
        Arry(i, 14) = Arry(i, 2) & "-" & Arry(i, 4) & "-" & Arry(i, 13)
    End If

    If Arry(i, 2) = "Duplicate" Then
        Arry(i, 15) = "D"
        Else
        Arry(i, 15) = "N"
    End If

    If Arry(i, 5) = "Groundwater" Then
        Arry(i, 16) = "WG"
        ElseIf Arry(i, 5) = "Leachate" Then
        Arry(i, 16) = "LE"
        ElseIf Range("E2") = "Surface water" Then
        Arry(i, 16) = "WS"
        Else
        Arry(i, 16) = "Other"
    End If

'Plus another six If statements similar to the above to populate Cols P to Y... Not included here to keep this code on StackOverflow easier to read
Next i

ThisWorkbook.Worksheets("CONVERSION").Range(Cells(1, 1), Cells(iLastRow, iLastCol)) = Arry ' Sets all the values

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True

End Sub