替代使用循环使代码运行更快

我有两个问题,第一个是关于一个excel公式,我不能在VBA复制,即使我已经使用loggingmacros来检索公式,第二个来,因为我不能解决我的第一个问题,是关于代码效率:基本上在细胞AR2我把一个Excel的公式:

IF=(P2="LDN";"UK;IF(P2="MAD";"SPAIN" IF(P2="PRA";"CZECH REPUBLIC";""))))))))) 

即时通讯为一些国家做这个。

然后即时通讯在我的第二行做自动填充单元格目的地,直到我的工作表上的数据最后一行才能得到结果。 主要的问题是,在Excel中,它运作良好,但是当用VBA录像机在VBA编码时,我在下面的代码中有一个错误。 虽然我只是复制粘贴VBA录音机的结果。 请find下面的代码。

  i = Range("A:A").Find("*", [A1], xlValues, xlWhole, xlByRows, xlPrevious).Row Range("AR2").Select ActiveCell.FormulaR1C1 = _ "=IF(RC[-28]=""LDN"",""UK"",IF(RC[-28]=""MAD"",""SPAIN"",IF(RC[-28]=""STO"",""SWEDEN"",IF(RC[-28]=""DUB"",""IRELAND"",IF(RC[-28]=""SAO"",""BRASIL"",IF(RC[-28]=""PAR"",""FRANCE"",IF(RC[-28]=""TOR"",""CANADA"",IF(RC[-28]=""TOK"",""JAPAN"",IF(RC[-28]=""ZUR"",""SWITZERLAND"",IF(RC[-28]=""HKG"",""HONG KONG"",IF(RC[-28]=""HEL"",""FINLAND"",IF(RC[-28]=""MIL"",""ITALY"",IF(R"& _ ""FRA"",""GERMANY"",IF(RC[-28]=""COP"",""DANEMARK"",IF(RC[-28]=""BRU"",""BELGIUM"",IF(RC[-28]=""AMS"",""NETHERLANDS"",IF(RC[-28]=""SIN"",""SINGAPORE"",IF(RC[-28]=""SEO"",""SOUTH KOREA"",IF(RC[-28]=""OSL"",""NORWAY"",IF(RC[-28]=""LIS"",""PORTUGAL"",IF(RC[-28]=""NYK"",""USA"",IF(RC[-28]=""VIE"",""AUSTRIA"",IF(RC[-28]=""LUX"",""LUXEMBOURG"",IF(RC[-28]=""JOH"",""SOUTH AF"& _ "(RC[-28]=""MEX"",""MEXICO"",IF(RC[-28]=""SYD"",""AUSTRALIA"",IF(RC[-28]=""TAI"",""TAIWAN"",IF(RC[-28]=""VAR"",""POLAND"",IF(RC[-28]=""BUD"",""HUNGARY"",IF(RC[-28]=""IST"",""TURKEY"",IF(RC[-28]=""BAN"",""INDIA"",IF(RC[-28]=""MOS"",""RUSSIA"",IF(RC[-28]=""TEL"",""ISRAEL"",IF(RC[-28]=""KUA"",""MALAYSIA"",IF(RC[-28]=""ATH"",""GREECE"",IF(RC[-28] =""PRA"",""CZECH REPUBLIC"& _ "))))))))))))))))))))))))))))))))))" Range("AR2").Select Selection.AutoFill Destination:=Range("AR2:AR" & i) 

由于上面的代码没有工作,我试图在vba中使用循环但是我发现,它需要年龄得到的结果,因为我有近20k行…. 5分钟来处理insteand即时结果与Excel公式:代码我的循环在这里:

 For j = 2 To i If Range("P" & j) = "AMS" Then Range("AR" & j) = "NETHERLANDS" If Range("P" & j) = "ATH" Then Range("AR" & j) = "GREECE" If Range("P" & j) = "BAN" Then Range("AR" & j) = "INDIA" If Range("P" & j) = "BRU" Then Range("AR" & j) = "BELGIUM" If Range("P" & j) = "BUD" Then Range("AR" & j) = "HUNGARY" If Range("P" & j) = "COP" Then Range("AR" & j) = "DANEMARK" . . . . . If Range("P" & j) = "VAR" Then Range("AR" & j) = "POLAND" If Range("P" & j) = "VIE" Then Range("AR" & j) = "AUSTRIA" If Range("P" & j) = "ZUR" Then Range("AR" & j) = "SWITZERLAND" Next j 

如果excel公式不能在VBA中工作,那么我怎样才能以高效快捷的方式进行编码,以便至less获得20k行的国家而无需等待,并且几乎可以像Excel公式自动填充模式那样得到结果。

非常感谢您的帮助Olivier

好的,几个非常简单的build议:

 Dim vals() As Variant vals = Range("P1:P1000") ' Substitute with the range you're looking at Dim i As Integer Dim val As String For i = LBound(vals, 1) To UBound(vals, 1) val = CStr(vals(i, 1)) Select Case val Case "AMS" Range("AR" & i + some_fixed_offset_if_needed) = "NETHERLANDS" Case "AR": ' ..... ' Case ..... End Select Next i 

首先,如果你经常访问范围的值,不要每次都访问范围对象。 这很慢。 将它的值保存到一个临时variables,然后访问该variables。 更好的办法是将整个范围保存在一个数组variables中,然后遍历该数组。

其次,如果案件互相排斥,不要只写一大堆If语句 – 使用If … ElseIf …

这样,如果已经find匹配的条件,则不需要检查其他条件。 在上面的代码中,我刚刚使用了一个select case语句来达到这个目的。

检查一下是否加快了一点。 不是,你可以尝试将可能的短代码添加到Scripting.Dictionary中作为键,并将replace(例如“NETHERLANDS”)作为值。 字典查找速度非常快。

如果还是比较慢的话,可以使用WorksheetFormula.something来访问VBA中的表单function。

你可以很容易地做到这一点,没有VBA如下所示; 但是我也会给出一个VBA解决scheme。

首先,我会说,对你的查找数据进行硬编码(即直接在你的VBA程序中编写城市代码和国名)是不好的做法。 这使得人们现在阅读和检查它们变得很困难,并且稍后改变它们是不方便的。

在这个例子中,我把所有的城市代码和国家名称放在Excel工作表右侧的查找表中(但如果您愿意的话,您可以将其放在其他隐藏表格中)。 然后为了将A列中列出的城市代码与相应的国家相匹配,我只需使用例如在单元格B2中查找表格中的城市代码:

 =INDEX($F$4:$F$12,MATCH(A2,$E$4:$E$12,0)) 

一直向下复制公式。

在这里输入图像描述

如果你真的想要VBA,你可以用这段简短的代码得到完全相同的结果(给定相同的input和查找表)

 Dim i As Long Dim cityCodes Dim countryNames Dim listOfCountryNames Dim listOfCityCodes 'Read look-up table from sheet. listOfCityCodes = WorksheetFunction.Transpose(Range("E4:E12").Value) listOfCountryNames = WorksheetFunction.Transpose(Range("F4:F12").Value) 'Read the input city codes from sheet to array cityCodes = Range("A2:A9").Value 'Make a blank array of same size to receive the corresponding country names ReDim countryNames(LBound(cityCodes, 1) To UBound(cityCodes, 1), _ LBound(cityCodes, 2) To UBound(cityCodes, 2)) 'Lookup individual country names one by one, write them in array For i = LBound(cityCodes, 1) To UBound(cityCodes, 1) countryNames(i, 1) = listOfCountryNames( _ WorksheetFunction.Match(cityCodes(i, 1), listOfCityCodes, 0)) Next i 'Write country names from array to sheet Range("B2:B9").Value = countryNames 

你会注意到我一次从表单读取数组到数组,然后在这些数组中执行所有操作,最后写回到表单。 这比在单个单元格中逐个读/写要快得多。