宏不适用于一个以上字符的单元格

时间:2018-08-24 03:53:18

标签: excel excel-vba

我有一个电子表格,该电子表格在第6行中包含29列标题。在这29个标题下方,有扩展到10000行的数字数据。我想选择一个标题,然后输入一个最小值和一个最大值,以及任何超出该标题列的最大值或低于最小值的数据,违反条件的行将被删除。

我正在考虑用户在单元格A1和A2中输入一个最小值和最大值,然后从一个下拉框中选择一个标题,然后它运行并删除违反边界条件的行。到目前为止,我有这个。

Sub deleterows()
Application.ScreenUpdating = False

Dim Min As Integer
Dim Max As Integer
Dim i As Integer
Dim HeaderRange As Range
Dim matchval As Double
Dim str As String

'Finding column number for the header
'Header is selected in Row 3, headers for the data is in row 6
matchval = Application.Match(Range("A3"), Range("A6:AC6"), 0)
str = Split(Cells(, matchval).Address, "$")(1)

Set HeaderRange = Range(str & "6:" & str & Cells(6, Columns.Count).End(xlToLeft).Column).Find(What:=str, lookat:=xlWhole)
If Cells(1, 1).Value <> "" And IsNumeric(Cells(1, 1)) Then
       Min = Cells(1, 1).Value
End If
If Cells(2, 1).Value <> "" And IsNumeric(Cells(2, 1)) Then
       Max = Cells(2, 1).Value
End If
For i = Cells(Rows.Count, HeaderRange.Column).End(xlUp).Row To 7 Step -1
    If Cells(i, HeaderRange.Column).Value > Max Or Cells(i, HeaderRange.Column).Value < Min Then
            Rows(i).EntireRow.Delete
        End If
    Next i
End Sub

基本上,我先找到标题的位置,然后找到地址,将其转换为字符串,然后使用该标题的Column索引。然后,它会找到任何违反最小和最大条件的单元格并将其删除。

但是,当我尝试运行此命令时,尝试使用包含多个字符的标头时会遇到错误。因此,如果我有一个名为“ V”的标头,它运行良好,但是,如果我有一个名为“ Vradial”的标头,则我会收到一条错误消息,指出“运行时错误'91':对象变量或未设置块变量”:

For i = Cells(Rows.Count, HeaderRange.Column).End(xlUp).Row To 7 Step -1

任何帮助将不胜感激。

谢谢!

1 个答案:

答案 0 :(得分:1)

我找到了您的直接问题“为什么只有单个字符头起作用”的答案。我还注意到您在代码中有不必要的冗余(用户“ eirikdaude”的注释中已经提到/注意到)

“为什么只有单个字符标题起作用”

在下面的代码中使用 Find(What:= str)时,您只能找到一个字母(字母列标识符)。您应该查找/搜索的是写在工作表中的标题的值(实际文本)

Set HeaderRange = Range(str & "6:" & str & Cells(6, 
Columns.Count).End(xlToLeft).Column).Find(What:=str, lookat:=xlWhole)

您可以按如下方式编写该行:(我对其进行了测试并可以工作)

Set HeaderRange = Range(str & "6:" & str & Cells(6, 
Columns.Count).End(xlToLeft).Column).Find(What:=Range("A3"), lookat:=xlWhole)

“代码中不必要的冗余”

上面的校正在起作用时是不必要的。如果我没有记错的话,使用带有问题的代码行来查找标题列。如果是这样,您已经在下面的代码中找到了正确的标题列索引。

matchval = Application.Match(Range("A3"), Range("A6:AC6"), 0)  
'This is only the correct header column index because the match/search range starts from column "A"

因此,您可以忽略给您带来麻烦的那一行,并按如下所示编写代码:(并且不要忘了在末尾设置 Application.ScreenUpdating = True

Sub deleterows()
Application.ScreenUpdating = False

Dim Min As long 'if you expect the min or max to have decimals use Double or Single rather than Long 
Dim Max As long
Dim i As long 'I changed from Integer to Long because 99% of the time Long is better than Integer
Dim matchval As long 'application.match returns a position in an array. Hence Long/Integer are better than Double 

'Finding column number for the header
'Header is selected in Row 3, headers for the data is in row 6
matchval = Application.Match(Range("A3"), Range("A6:AC6"), 0)

If Cells(1, 1).Value <> "" And IsNumeric(Cells(1, 1)) Then
       Min = Cells(1, 1).Value
End If
If Cells(2, 1).Value <> "" And IsNumeric(Cells(2, 1)) Then
       Max = Cells(2, 1).Value
End If
For i = Cells(Rows.Count, matchval).End(xlUp).Row To 7 Step -1
    If Cells(i, matchval).Value > Max Or Cells(i, matchval).Value < Min Then
            Rows(i).EntireRow.Delete
        End If
    Next i

Application.ScreenUpdating = True
End Sub

希望这对您有所帮助。