VLookup字母数值 - 删除行

时间:2017-02-06 18:20:27

标签: excel excel-vba vlookup vba

我现在正在努力解决VLookup问题。我正在努力做一些真正超出我头脑的事情,但我认为只要稍加帮助,我就可以做到。

  1. 首先,我创建了一张带表格的单独表格,这样我就可以给一些字母赋一个数字,这样我就可以量化它们的价值。
  2. Letter Tables

    1. 有了这些信息,我想详细说明一个VBA公式,它能够检查一个表中列中的那些字母(带一个数字),并删除每一行的字母值低于给定的字母值数。 (忽略第I栏中的Ns)
    2. Letter Tables 2]

      1. 到目前为止,我有这样的事情:

        Sub DeletarIndices()
        
            indice = InputBox("Digite o IC/IV Desejado", "GBG Pneus")
        
            Set planilhaV = Sheets("IV")
            Dim vValores As String
            sResult = Application.VLookup("Y", planilhaV.Range("A2:B11"), 2)
        
            Application.ScreenUpdating = False
            Application.Calculation = xlCalculationManual
            Dim i As Long
            For i = Range("A" & Rows.Count).End(xlUp).Row To 1 Step -1
                If Not (Range("A" & i).Value > sResult) Then
                    Range("A" & i).EntireRow.Delete
                End If
            Next i
            Application.Calculation = xlCalculationAutomatic
            Application.ScreenUpdating = True
        
        End Sub
        
      2. 当我运行代码时,会打开一个输入框并询问将在代码中使用的值。该字母将转换为数字,并将用作比较以删除较低的值。但... 就在这里:

        If Not (Range("A" & i).Value > sResult) Then
        

        字母仍然是一个数字,所以当它检查表格时,只会删除低于该值的数字,而不会删除值较低的字母。我需要的就是那个。分析这些字母并删除行,而不是数字。

        感谢任何可以帮助我的人!

2 个答案:

答案 0 :(得分:1)

假设您的字母优先顺序始终是按字母顺序排列的,那么您不需要将字母转换为数字,您可以简单地将字母与字母进行比较。我还要注意,你确定最后一行(Range("A" & Rows.Count).End(xlUp).Row)的方法并不好,我建议你找一个更可靠的方法。

假设您的数据以您显示的方式呈现 - 将H列中的数据作为3个字符的代码,其中字母是最后一个字符(例如" 91B"," 89D"等等) - 让我们一步一步:(注意没有查找工作表planilhaV了)

1)声明我们的变量

Dim indice As String   ' To hold our user input letter
Dim rowLetter As String   ' To hold the current row letter value
Dim firstRow As Long   ' First row of your data
Dim lastRow As Long   ' Last row of your data
Dim currentRow As Long   ' Current row for your loop counter
Dim sht As Worksheet   ' To hold the worksheet you're working on

2)分配一些值

Set sht = ThisWorkbook.Worksheets("*WORKSHEET NAME*")   ' Use the name of your worksheet
firstRow = 1
lastRow = sht.Range("A" & Rows.Count).End(xlUp).Row

3)获取用户输入

indice = UCase(InputBox("Digite o IC/IV Desejado", "GBG Pneus"))   ' Convert user input to upper case and store

4)进行处理

For currentRow = lastRow To firstRow Step -1
    rowLetter = UCase(Right(sht.Range("H" & currentRow).Value, 1))   ' Get letter from code in column H, converted to upper case
    If rowLetter < indice Then   ' Compare the letters, and if smaller than user input...
        sht.Rows(currentRow).EntireRow.Delete   ' Delete the row
    End If
Next currentRow

那应该是这样做的。宣布您计划使用的所有变量是一个好主意,使用Option Explicit将确保您无需先声明它就可以使用任何内容。

修改

@LeonVFX:如果字母的值不总是按字母顺序增加,那么你可以使用查找表,或者你可以在代码中进行比较。

如果您选择使用原始示例中的查找表,则可以按如下方式调整上面的代码:

Dim indice As String   ' To hold our user input letter
Dim indiceValue As Long   ' To hold the numeric value of our user input letter
Dim rowLetter As String   ' To hold the current row letter
Dim rowLetterValue As Long   ' To hold the numeric value of the current row letter
Dim firstRow As Long   ' First row of your data
Dim lastRow As Long   ' Last row of your data
Dim currentRow As Long   ' Current row for your loop counter
Dim sht As Worksheet   ' To hold the worksheet you're working on
Dim planilhaV As Worksheet   ' To hold your lookup worksheet

Set sht = ThisWorkbook.Worksheets("*WORKSHEET NAME*")   ' Use the name of your worksheet
Set planilhaV = ThisWorkbook.Worksheets("IV")   ' As in your original example
firstRow = 1
lastRow = sht.Range("A" & Rows.Count).End(xlUp).Row

indice = UCase(InputBox("Digite o IC/IV Desejado", "GBG Pneus"))   ' Convert user input to upper case and store
indiceValue = CLng(Application.VLookup(indice, planilhaV.Range("A2:B11"), 2, False))   ' Creating numeric indice value with lookup table

For currentRow = lastRow To firstRow Step -1
    rowLetter = UCase(Right(sht.Range("H" & currentRow).Value, 1))   ' Get letter from code in column H, converted to upper case
    rowLetterValue = CLng(Application.VLookup(rowLetter, planilhaV.Range("A2:B11"), 2, False))   ' Creating numeric value for current row letter with lookup table
    If rowLetterValue < indiceValue Then   ' Compare the numeric letter values, and if smaller than user input...
        sht.Rows(currentRow).EntireRow.Delete   ' Delete the row
    End If
Next currentRow

如果您发现它一次只删除一行,我的猜测是使用sht.Range("A" & Rows.Count).End(xlUp).Row查找最后一行是因为您没有A栏中的任何数据?如果您的数据位于原始示例中的H列中,请将代码中的A更改为H,您应该没问题,或者尝试找到更可靠的方法来设置{{1变量值。

答案 1 :(得分:0)

在论坛上得到一些帮助之后,我得到了这个答案,如果有人碰到这样的话,我会把它留在这里。

' Verifies if the digit is a number. If it is, returns True, False if it isn't.
Function ehNumero(ByVal digito As String) As Boolean

    a = Asc(digito)
    If a >= 48 And a <= 57 Then
        ehNumero = True
    Else
        enNumero = False
    End If

End Function

' Separates the code in a numeric and a alphabetic part.
Function separaCodigo(ByVal codigo As String, ByRef numero As Integer, ByRef letras As String) As Boolean
    p = 0
    For i = 1 To Len(codigo)
        digito = Mid(codigo, i, 1)
        If Not ehNumero(digito) Then ' Found the point break when it finds the first non-numeric digit.
            p = i
            Exit For
        End If
    Next i

    If p = 0 Or p = 1 Then
        numero = 0
        letras = ""
        separaCodigo = False
    Else
        codigo = UCase(codigo)
        numero = Int(Mid(codigo, 1, p - 1))
        letras = Mid(codigo, p)
        separaCodigo = True
    End If
End Function

' Gets the values from the configuration table.
Function valorDasLetras(ByVal letras As String) As Integer
    On Error GoTo trataErro

    valorDasLetras = Application.VLookup(letras, Worksheets("Configuração").Range("A2:B11"), 2, False)

    Exit Function

trataErro:
    valorDasLetras = 0 '

End Function

'Deletes the lines in the table in the interval.
Function deletar(ByVal numero As Integer, letras As String) As Integer

    valor = valorDasLetras(letras)
    If valor = 0 Then
        deletar = -1
        Exit Function
    End If

    limInf = numero
    limSup = valor

    Dim dados As Worksheet
    Set dados = ActiveWorkbook.ActiveSheet

    Dim linhasPraDeletar As Range
    totalLinhas = 0

    linha = 1
    Do While True

        curCodigo = dados.Cells(linha, 7) ' Using Column G

        If curCodigo = "" Then
            Exit Do
        End If

        Dim curNumero As Integer
        Dim curLetras As String
        If Not separaCodigo(curCodigo, curNumero, curLetras) Then
            deletar = -1
            Exit Function
        End If

        ' Gets the values for the letters from the table
        curValor = valorDasLetras(curLetras)
        If curValor = 0 Then
            deletar = -1
            Exit Function
        End If

        If curNumero < limInf Or curValor < limSup Then
            If linhasPraDeletar Is Nothing Then
                Set linhasPraDeletar = dados.Rows(linha)
            Else
                Set linhasPraDeletar = Union(linhasPraDeletar, dados.Rows(linha))
            End If
            totalLinhas = totalLinhas + 1
        End If

        linha = linha + 1
    Loop

    linhasPraDeletar.Select
    linhasPraDeletar.EntireRow.Delete ' <===== Comment to select, but do not delete, the line

    deletar = totalLinhas

End Function

' Run the code
Sub LimparValores()
    'On Error GoTo trataErro

    ' Reads the user code
    msg = "Input your code"
    codigo = InputBox(msg, "Código")
    If codigo = "" Then ' Cancelado
        Exit Sub
    End If

    ' Separates the user code number from letters
    Dim numero As Integer
    Dim letras As String
    If Not separaCodigo(codigo, numero, letras) Then
        MsgBox ("Invalid code: " & codigo)
        Exit Sub
    End If

    ' Calls the delete function
    linhas = deletar(numero, letras)
    If linhas = -1 Then
        MsgBox ("There was an error with the code (the letter does not exist in configuration)")
    Else
        If linhas = 0 Then
            MsgBox ("There are no rows in the interval - no row was deleted")
        Else
            MsgBox (linhas & " rows deleted!")
        End If
    End If

    Exit Sub

trataErro:
    MsgBox ("The code is not in the expected format.")

End Sub

希望将来帮助任何人!