2016-02-04 184 views
1

如果一個人通過細胞和lookinto的VLOOKUP公式要循環,並計算一個如下會這樣做:VBA搜索VLOOKUP在單元格範圍和計算

Dim r As Range 

For i = 1 To 100 
    With wsSWM.Columns(i).SpecialCells(xlCellTypeFormulas) 
     For Each r In .Cells 
      If Left(r.Formula, 8) = "=VLOOKUP" Then r.Value = r.Value 
     Next r 
    End With 
Next i 

但是,如果一個人依偎在之間vlookups其他計算則需要能夠在期望的範圍內找到VLOOKUP上的替換,但替換部分將是硬編碼的計算查找。

H4 + A10*VLOOKUP("This",A:1:B3,2,0)*A1/B2+C3 = H4 + A10*"lookupvalue"*A1/B2+C3 

一個如何去完成這個

+1

商店VLOOKUP到一個變量? – findwindow

+0

抱歉,請清楚您的問題和期望 – Siva

+0

您可以使用InStr查找啓動VLOOKUP的字符#,然後再次查找Intr以查找VLOOKUP的右括號中的字符#。您可以使用MID和REPLACE來計算查找的整個字符串。這假設VLOOKUP中沒有嵌套公式。 – Tom

回答

3

這將覆蓋式在多個vlookups,並將涵蓋VLOOKUP內的嵌入公式。它也將只使用#N/A是否有評估VLOOKUP任何錯誤:

Sub tgr() 

    Dim ws As Worksheet 
    Dim rFound As Range 
    Dim sFirst As String 
    Dim sSecond As String 
    Dim sTemp As String 
    Dim sVLOOKUP As String 
    Dim sValue As String 
    Dim lOpenParenCount As Long 
    Dim lCloseParenCount As Long 
    Dim i As Long 

    Set ws = ActiveWorkbook.ActiveSheet 

    With ws.UsedRange 
     Set rFound = .Find("VLOOKUP", .Cells(.Cells.Count), xlFormulas, xlPart) 
     If Not rFound Is Nothing Then 
      sFirst = rFound.Address 
      Do 
       If Left(rFound.Formula, 1) = "=" Then 
        Do While InStr(1, rFound.Formula, "VLOOKUP", vbTextCompare) > 0 
         sVLOOKUP = vbNullString 
         sValue = vbNullString 
         For i = InStr(1, rFound.Formula, "VLOOKUP", vbTextCompare) To Len(rFound.Formula) 
          sTemp = Mid(rFound.Formula, i, 1) 
          sVLOOKUP = sVLOOKUP & sTemp 
          Select Case sTemp 
           Case "(": lOpenParenCount = lOpenParenCount + 1 
           Case ")": lCloseParenCount = lCloseParenCount + 1 
              If lCloseParenCount = lOpenParenCount Then Exit For 
          End Select 
         Next i 
         On Error Resume Next 
         sValue = Evaluate(sVLOOKUP) 
         On Error GoTo 0 
         If Len(sValue) = 0 Then sValue = "#N/A" 
         rFound.Formula = Replace(rFound.Formula, sVLOOKUP, sValue) 
        Loop 
       Else 
        If Len(sSecond) = 0 Then sSecond = rFound.Address 
       End If 
       Set rFound = .FindNext(rFound) 
       If rFound Is Nothing Then Exit Do 
      Loop While rFound.Address <> sFirst And rFound.Address <> sSecond 
     End If 
    End With 

End Sub 
+0

這是迄今爲止我在堆棧交換中獲得的最佳答案,絕對沒有修改,效果很好,我真的很感激它! –

+0

此代碼沒有任何修改,現在評估sValue爲「」,因爲評估返回錯誤2042或NA爲每個單一的值,你有任何想法可能是什麼原因導致?一個高光和f9返回一個值表最肯定是工作不知道爲什麼這是 –

1

爲了做到這一點,你將需要:(1)取公式字符串; (2)分解與Vlookup相關的部分vs與其他部分相關的部分,將每個部分存儲爲它自己的字符串變量; (3)在VBA中'手動'運行Vlookup部分以查找值;和(4)用vlookup值替換單元格中的公式,然後是其他所有內容。

由於您的檢查公式假定VLOOKUP將位於單元格的開頭,這使得該過程稍微簡單一些,因爲我們不需要檢查VLOOKUP之前的「其他部分」。

我建議的代碼,以執行這些步驟將如下所示〔Ⅰ已經測試並確認其工作原理]:

Dim r As Range 
Dim lookupString as String 'stores the portion of the formula which represents the Vlookup 
Dim lookupValue as Double 'Stores the value of the lookup 
Dim otherString as String 'stores the rest of the string 
Dim formulaBrackets as Integer 'used to count how many brackets are contained within the Vlookup, to find where it ends 

For i = 1 To 100 
    With wsSWM.Columns(i).SpecialCells(xlCellTypeFormulas) 
     For Each r In .Cells 
      If Left(r.Formula, 8) = "=VLOOKUP" Then 
       formulaBrackets = 0 
       For j = 1 to Len(r.Formula) 
        If Mid(r.Formula,j,1) = "(" Then 
         formulaBrackets = formulaBrackets + 1 
        ElseIf Mid(r.Formula,j,1) = ")" Then 
         formulaBrackets = formulaBrackets - 1 
         If formulaBrackets = 0 Then 
          lookupString = Mid(r.Formula,2,j-1) 'picks up the string starting from the V in Vlookup [excludes the '='], up to the final bracket 
          otherString = Mid(r.Formula,j+1,Len(r.Formula)) 'picks up the string starting AFTER the ending bracket, to the end of thes formula 
          r.Formula = "="&lookupString 'sets up the formula in the cell to calculate the vlookup as written 
          lookupValue = r.value 
          r.Formula = "=" & lookupValue & otherString 'recreates the formula, having replaced the vlookup with its calculated value 
          Exit For 
         End If 
        Else 
         'No action required 
        End If 
       Next j 

      End If 
     Next r 
    End With 
Next i 
+1

然後重新閱讀你的問題,我現在看到我的一些假設並不成立 - 儘管如此,你或其他人可能會以此爲出發點來確定Vlookup在其結尾括號中的位置,並且根據需要提取其餘部分... –

1

我來晚了黨在這一個,但這裏是我的解決方案。它與已經發布的兩個版本沒有太大區別,但是它的確使用了一個專門設計用於提取函數中LOOKUP的評估值的函數,並返回函數中已更改的公式。這樣,如果您循環遍歷一系列單元格,則可以根據特定條件選擇調用函數,例如,如果單元格具有公式,或者隱藏或者類似的話。

這裏的功能:

Function ExtractVLOOKUPValue(rng As Range) As Variant 
' This will extract the returned value of the first instance 
' of a VLOOKUP formula in a cell. 

' Constant declarations. 
Const sVLOOKUP  As String = "VLOOKUP" 
Const lVLOOKUP_LEN As String = 7 
Const sOPEN_PAREN As String = "(" 
Const sCLOSE_PAREN As String = ")" 

' Variable declarations. 
Dim lVlookupPos  As Long 
Dim lCnt   As Long 
Dim lParenCnt  As Long 
Dim sVlookupFormula As String 
Dim sResult   As String 

' Check first if the cell is a formula, and then 
' if a VLOOKUP formula exists in the cell. 
If rng.HasFormula Then 

    lVlookupPos = InStr(rng.Formula, sVLOOKUP) 
    If lVlookupPos <> 0 Then 

     ' Isolate the VLOOKUP formula itself. 
     For lCnt = lVlookupPos To Len(rng.Formula) 

      ' Count the open parentheses we encounter so that we can use 
      ' the apporpriate number of closing parentheses. 
      If Mid(rng.Formula, lCnt, 1) = sOPEN_PAREN Then lParenCnt = lParenCnt + 1 

      ' If we get to closing parenthese, start taking counts away from the 
      ' parencnt variable so we can keep track of the correct number of 
      ' parenthesis in hte formula. 
      If Mid(rng.Formula, lCnt, 1) = sCLOSE_PAREN Then 
       lParenCnt = lParenCnt - 1 

       ' If we get done to zero in the parencnt, then extract the formula. 
       If lParenCnt = 0 Then 
        sVlookupFormula = Mid(rng.Formula, lVlookupPos, lCnt + 1 - lVlookupPos) 
        Exit For 
       End If 

      End If 

     Next lCnt 

    End If 

End If 

' Now that we have the formula, we can evalutate the result. 
On Error Resume Next 
sResult = Evaluate(sVlookupFormula) 

' If we errored out, return the #N/A in the function. 
If Err.Number <> 0 Then 
    sResult = "#N/A" 
End If 

' Replace the VLOOKUP in the formula with the result, then return it to the function. 
sResult = Replace(rng.Formula, sVlookupFormula, sResult) 

' Return the result, having replaced the VLOOKUP function. 
ExtractVLOOKUPValue = sResult 

End Function 

而且這裏是你會如何稱呼它:

Sub ReplaceFormulaWithValue() 
Dim rng As Range 
Dim rCell As Range 

Set rng = Selection 

For Each rCell In rng 
    rCell.Formula = ExtractVLOOKUPValue(rCell) 
Next rCell 

End Sub 
+0

我也給這個一個鏡頭,看看它是如何疊加的 –

+0

這個代碼最大的問題是,有很多浪費時間循環遍歷所有的單元格與在一個範圍內搜索相比,它的速度比我給出的正確答案的代碼慢得多,但是對於深入的代碼感謝並回答 –

+0

哦,毫無疑問。這個版本只有在你想要採取行動或設置逐個細胞的使用標準時纔有用,比如說你想讓它在一些細胞上而不是在其他細胞上工作。但是,循環肯定比其他解決方案慢。 – Scott