【问题标题】:Insert formula into cell if the cell to the right has text in it如果右侧的单元格中有文本,则将公式插入单元格
【发布时间】:2021-11-08 05:37:44
【问题描述】:

我要完成的任务是,如果单元格 G21 到 G27 中有任何文本,那么将在其左侧的相应单元格中粘贴一个 vlookup 公式

例如。单元格 G31 包含文本,因此公式 =VLOOKUP(G31,Data!$P$2:$Q$110,2,FALSE) 在单元格 F31 中

这是我到目前为止的代码,但我是初学者,我不知道如何插入 vlookup 以自动引用它旁边的单元格。

Private Sub Worksheet_Caps()
    Dim SrchRng As Range, cel As Range
    Set SrchRng = Range("G31:G27")
    For Each cel In SrchRng
        If cel.Value <> "" Then
            cel.Offset(0, -1).Value= VLOOKUP(cel,Data!P2:Q110,2,FALSE)
        End If
 End Sub

【问题讨论】:

  • 如果单元格有“文本”或不为空?我的意思是,您指的是单元格格式吗?查看您的代码,如果不为空,它看起来会认为它“有文本”。如果是这样,您是要放置一个公式,还是使用 VBA 计算 Vlookup?您的代码没有做/尝试任何可能的替代方案......
  • 应该已经澄清了,如果单元格为空,则不应放置Vlookup。如果它不为空,则应将 Vlookup 直接放在左侧的单元格中。我原本想让它在 VBA 中计算,但我想不通!
  • 非空*...

标签: excel vba


【解决方案1】:

VLookup 与匹配

  • 两种解决方案都会写入值(而不是公式),因为您在 cmets 中写了 “我最初希望它在 VBA 中计算,但我无法计算出来!”。

快速修复(不推荐)

Option Explicit

Sub Worksheet_Caps()
    
    Dim SrchRng As Range: Set SrchRng = Range("G21:G27")
    Dim LkpRng As Range: Set LkpRng = Worksheets("Data").Range("P2:Q110")
    
    Dim SrchCell As Range
    Dim MatchValue As Variant
    For Each SrchCell In SrchRng.Cells
        If Len(CStr(SrchCell.Value)) > 0 Then
            MatchValue = Application.VLookup(SrchCell.Value, LkpRng, 2, False)
            If Not IsError(MatchValue) Then
                SrchCell.Offset(, -1).Value = MatchValue
            'Else
                'SrchCell.Offset(, -1).Value = Empty
            End If
        End If
    Next SrchCell

End Sub

改进

  • 以下使用更灵活的Application.Match 代替VLookup 的任何“风味”。
  • 调整(使用)常量部分中的值。
Option Explicit

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Performs a 'VLookup' using 'Application.Match'.
' Remarks:      Uses the 'RefColumn' and 'GetRange' functions.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub WorksheetCaps()
    On Error GoTo ClearError
    
    ' Source
    Const sName As String = "Data" ' Worksheet Name
    Const slFirst As String = "P2" ' First Lookup Cell Address
    Const svCol As String = "Q" ' Value Column
    ' Destination
    Const dName As String = "Sheet1" ' Worksheet Name
    Const dlFirst As String = "G21" ' First Lookup Cell Address
    Const dvCol As String = "F" ' Value Column
    ' Workbook
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    ' Create a reference to the Source Lookup Range ('slrg').
    Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
    Dim slfCell As Range: Set slfCell = sws.Range(slFirst)
    Dim slrg As Range: Set slrg = RefColumn(slfCell)
    If slrg Is Nothing Then Exit Sub ' no data in source
    ' You can always use a static range instead of the previous 3 lines:
    'Dim slrg As Range: Set slrg = sws.Range("P2:P110")
    
    ' Create a reference to the Destination Lookup Range ('dlrg').
    Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
    Dim dlfCell As Range: Set dlfCell = dws.Range(dlFirst)
    Dim dlrg As Range: Set dlrg = RefColumn(dlfCell)
    If dlrg Is Nothing Then Exit Sub ' no data in destination
    ' You can always use a static range instead of the previous 3 lines:
    'Dim dlrg As Range: Set dlrg = dws.Range("G21:G27")
    
    ' Create a reference to the Source Value Range ('svrg').
    Dim svrg As Range: Set svrg = slrg.EntireRow.Columns(svCol)
    ' Write the values from the Source Value Range
    ' to the Source Value Array ('svData').
    Dim svData As Variant: svData = GetRange(svrg)
    
    ' Write the values from the Destination Lookup Range
    ' to the Destination Array ('dData').
    Dim dData As Variant: dData = GetRange(dlrg)
    
    ' Declare additional variables.
    Dim smrIndex As Variant ' Source Match Row Index
    Dim dlValue As Variant ' Destination Lookup Value
    Dim dr As Long ' Destination Row Counter
    
    ' Loop through the elements (rows) of the Destination Array.
    For dr = 1 To UBound(dData, 1)
        ' Write the (lookup) value of the current element
        ' in the Destination Array to a variable ('dlValue').
        dlValue = dData(dr, 1)
        ' Replace the (lookup) value of the current element
        ' in the Destination Array with 'Empty'.
        dData(dr, 1) = Empty
        If Not IsError(dlValue) Then ' not an error value
            If Len(dlValue) > 0 Then ' not a blank
                ' Attempt to find a match of the current
                ' Destination Lookup value in the Source Lookup Range.
                smrIndex = Application.Match(dlValue, slrg, 0)
                If IsNumeric(smrIndex) Then ' a match (the first occurrence)
                    ' Write the corresponding value (in the same row)
                    ' of the Source Lookup Range in the Source Value Array
                    ' to the current element in the Destination Array.
                    dData(dr, 1) = svData(smrIndex, 1)
                'Else  ' not a match (resulting in an error value)
                End If
            ' Else ' a blank: Empty, ="", ',...
            End If
        ' Else ' any error value
        End If
    Next dr
    
    ' Create a reference to the Destination Value Range ('dvrg').
    Dim dvrg As Range: Set dvrg = dlrg.EntireRow.Columns(dvCol)
    ' Write the (modified) values from the Destination Array
    ' to the Destination Value Range (in one go).
    dvrg.Value = dData
    
    ' Save the workbook.
    wb.Save

    ' Inform the user.
    MsgBox "The lookup has finished successfully.", _
        vbInformation, "Worksheet Caps"
 
ProcExit:
    Exit Sub
ClearError:
    Debug.Print "Run-time error '" & Err.Number & "': " & Err.Description
    Resume ProcExit
End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Creates a reference to the one-column range from the first cell
'               of a range ('FirstCell') to the bottom-most non-empty cell
'               of the first cell's worksheet column.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefColumn( _
    ByVal FirstCell As Range) _
As Range
    If FirstCell Is Nothing Then Exit Function
    
    With FirstCell.Cells(1)
        Dim lCell As Range
        Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
            .Find("*", , xlFormulas, , , xlPrevious)
        If lCell Is Nothing Then Exit Function
        Set RefColumn = .Resize(lCell.Row - .Row + 1)
    End With

End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Returns the values of a range ('rg') in a 2D one-based array.
' Remarks:      If ˙rg` refers to a multi-range, only its first area
'               is considered.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function GetRange( _
    ByVal rg As Range) _
As Variant
    If rg Is Nothing Then Exit Function
    
    If rg.Rows.Count + rg.Columns.Count = 2 Then ' one cell
        Dim Data As Variant: ReDim Data(1 To 1, 1 To 1): Data(1, 1) = rg.Value
        GetRange = Data
    Else ' multiple cells
        GetRange = rg.Value
    End If

End Function

【讨论】:

    【解决方案2】:

    请尝试下一个方法:

    1. 如果您需要放置公式来计算Vlookup,请使用以下方式:
    cel.Offset(0, -1).Formula2 = "=Vlookup(" & cel.Address & ",Data!P2:Q110,2,False)"  
    
    1. 您需要在 VBA 中计算 Vlookup,使用下一个替代方法:
    cel.Offset(0, -1).Value = WorksheetFunction.VLookup(cel.Value, Sheets("Data").Range("P2:Q110"), 2, False)
    

    已编辑:

    应该调整你的整个代码,以便同时处理VLookup函数没有任何匹配的情况:

    Private Sub Worksheet_Caps()
        Dim SrchRng As Range, cel As Range, VLKresult
        
        On Error Resume Next 'for the case of no any matched cells
         Set SrchRng = Range("G31:G27").SpecialCells(xlCellTypeConstants) 'the range without empty cells
        On Error GoTo 0
        If Not SrchRng Is Nothing Then
            For Each cel In SrchRng
                VLKresult = Application.VLookup(cel.Value, Sheets("Data").Range("P$2:Q$110"), 2, False)
                If Not IsError(VLKresult) Then
                    cel.Offset(0, -1).Value = VLKresult
                Else
                    cel.Offset(0, -1).Value = "N/A"
                End If
           Next
        End If
     End Sub
    

    【讨论】:

    • 我使用了您的第二个示例,现在我收到“运行时错误 '1004':无法获取 WorksheetFunction 类的 VLookup 属性。”我假设这是因为该范围内的某些单元格是空的。
    • 这应该意味着 Vlookup 不会为该单元格值返回任何内容。现在我关闭了我的笔记本电脑。我明天会告诉你如何处理它,如果不是太晚的话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多