2014-08-28 63 views
4

我有兩個問題,第一個是關於Excel無法在VBA中複製的公式,即使我使用記錄宏來檢索公式,第二個問題因爲我想不出解決我的第一個問題,是關於代碼效率: 基本上在小區AR2我把Excel公式:替代使用循環使代碼運行更快

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

IM這樣做了一堆的國家。

然後我在我的第二行上做自動填充單元格目的地,直到我的工作表上的數據最後一行才能得到結果。 主要問題是,在Excel中它工作正常,但是當用VBA錄像機在VBA中編碼時,我在下面的代碼中有錯誤。雖然我只是複製粘貼VBA錄音機的結果。 請找到下面的代碼。

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) 

正如上面的代碼didnt工作,我嘗試使用循環然而,我發現,它需要年齡得到的結果,因爲我有將近2萬行.... 5min即可瞬間的過程insteand做在VBA使用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 

如果在VBA中的Excel formulat不工作,我該怎麼代碼以高效,快捷的方式,以獲得該國至少20K行,而不必等待,幾乎可以即時得到結果,就像Excel公式自動填充模式一樣。

非常感謝FO r系統正在將幫助 奧利維爾

回答

0

好,一些非常簡單的建議:

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 

首先,如果你經常訪問一系列的價值,不訪問範圍對象每一次。這非常慢。將它的值保存到一個臨時變量,然後訪問該變量。 更好的辦法是將整個範圍保存在一個數組變量中,然後遍歷該數組。

其次,如果情況是相互排斥的,不只是寫一噸的if語句 - 使用 如果... elseif的...

等等這種方式,它不需要檢查其他條件是否已經找到匹配的條件。在上面的代碼中,我剛剛爲此使用了一個select case語句。

檢查一下它是否會加快速度。不是,您可以嘗試將可能的短代碼作爲關鍵字添加到Scripting.Dictionary中,並將替換(例如「NETHERLANDS」)作爲值。字典查找速度非常快。

如果這還比較慢,您可以隨時使用WorksheetFormula.something訪問VBA中的表單功能。

+0

究竟是我要放下的 – Tom 2014-08-28 10:41:43

+1

這在短期內有效,但缺點是所有的城市代碼和國家名稱都是硬編碼的! – 2014-08-28 10:44:47

+0

@ Jean-FrançoisCorbett我認爲這種方法的真正缺點是迭代次數和代碼行數量。 – 2014-08-28 11:07:46

4

您可以輕鬆地在沒有VBA的情況下執行此操作,如下所示;但我還會進一步提供VBA解決方案。

首先,我會說對你的查找數據進行硬編碼(即直接在你的VBA程序中編寫城市代碼和國家名稱)是不好的做法。這使得人們現在很難閱讀並檢查它們,並且稍後改變它們是不方便的。

在這個例子中,我將所有的城市代碼和國家名稱放在Excel工作表右側的查找表中(但如果您願意,可以將它放在其他隱藏工作表中)。然後,爲了使列A中列出的城市代碼與適當的國家相匹配,我只需使用例如在表格中查找表格中的城市代碼。在單元格B2中:

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

將公式一直向下複製。

enter image description here

如果你真的想VBA,就可以得到完全相同的結果(給出相​​同的輸入和查找表在同一位置)這一小段代碼:

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 

您會注意到,我從表格中將所有內容一次性讀取到數組,然後在這些數組中執行所有操作,最後寫回表單。這比在單個單元格中逐個讀/寫要快得多。

+1

我喜歡非vba方法:P – 2014-08-28 10:51:06

+0

++,不錯,除了您可能想要將這些20K行的計算切換爲手動或者將值複製粘貼爲值並替換原始值。 – 2014-08-28 10:56:43

+1

如果他確實想用excel公式解決這個問題 - 爲什麼不僅僅爲該查找表使用VLOOKUP?這應該達到相同的結果,甚至更簡單,也可能稍微更快。 – Bogey 2014-08-28 11:02:10