当我要求它不是时,为什么表单被包含在VBA中

时间:2014-11-27 06:13:21

标签: excel vba excel-vba

有谁知道为什么不按照我的代码中的定义排除所有工作表?看来这张表'资产'仍被包括在内。非常感谢

Sub Run_Me_To_Fix_Columns()
   Dim ws As Worksheet

'------------------------------------------------------------------
'List the names of the worksheets to exclude from Sub resizingColumns
'------------------------------------------------------------------

    Const excludeSheets As String = "Control,DIVA_Report,Asset"

'------------------------------------------------------------------

    For Each ws In ActiveWorkbook.Worksheets
        If IsError(Application.Match(ws.Name, Split(excludeSheets, ","))) Then
        Call resizingColumns(ws)
        End If
    Next
End Sub

Sub resizingColumns(ws As Worksheet)
       With ws
        ws.Range("A:AZ").ColumnWidth = 10
    End With
    For i = 1 To 24
        Numbers = WorksheetFunction.Count(ws.Columns(i))
        Text = WorksheetFunction.CountA(ws.Columns(i)) - Numbers
        If Numbers < Text Then
            ws.Columns(i).EntireColumn.AutoFit
        End If
    Next i
End Sub

1 个答案:

答案 0 :(得分:2)

在您的工具箱中拥有一些基本的调试技巧总是一个好主意。例如,您可以在测试之前插入类似以下的代码:

For Each s In Split(excludeSheets, ",")
    MsgBox "EX: [" & s & "]: " & CStr(len(s))
Next

For Each ws In ActiveWorkbook.Worksheets
    MsgBox "WS: [" & ws.Name & "]: " & CStr(len(ws.Name))
Next

For Each ws In ActiveWorkbook.Worksheets
    MsgBox "MATCH: " & ws.Name & ": " & CStr(Application.Match(ws.Name, Split(excludeSheets, ",")))
    MsgBox "ISERR: " & ws.Name & ": " & CStr(IsError(Application.Match(ws.Name, Split(excludeSheets, ","))))
Next

这将显示您正在检查的值(长度以确保它们之前或之后没有意外的空白区域,这是我之前用工作表名称咬过的东西)。


此外,我实际上将引导您完成一个不错的调试会议,以便您可以在该领域获得一些技能。首先,使用工作表“Sheet1”到“Sheet5”创建一个新工作簿,然后输入以下代码:

Sub test()
    Dim ws As Worksheet

    Const excludeSheets As String = "Sheet2,Sheet3,Sheet5"

    For Each s In Split(excludeSheets, ",")
        MsgBox "EX: [" & s & "]: " & CStr(Len(s))
    Next

    For Each ws In ActiveWorkbook.Worksheets
        MsgBox "WS: [" & ws.Name & "]: " & CStr(Len(ws.Name))
    Next

    For Each ws In ActiveWorkbook.Worksheets
        MsgBox "MATCH: [" & ws.Name & "]: " & CStr(Application.Match(ws.Name, Split(excludeSheets, ",")))
        MsgBox "ISERR: [" & ws.Name & "]: " & CStr(IsError(Application.Match(ws.Name, Split(excludeSheets, ","))))
    Next

    For Each ws In ActiveWorkbook.Worksheets
        If IsError(Application.Match(ws.Name, Split(excludeSheets, ","))) Then
            MsgBox "GOT: [" & ws.Name & "]"
        End If
    Next
End Sub

运行时,您会看到以下消息框:

EX: [Sheet2]: 6
EX: [Sheet3]: 6
EX: [Sheet5]: 6

WS: [Sheet1]: 6
WS: [Sheet2]: 6
WS: [Sheet3]: 6
WS: [Sheet4]: 6
WS: [Sheet5]: 6

MATCH: [Sheet1]: Error 2042
ISERR: [Sheet1]: True

MATCH: [Sheet2]: 1
ISERR: [Sheet2]: False

MATCH: [Sheet3]: 2
ISERR: [Sheet3]: False

MATCH: [Sheet4]: 2
ISERR: [Sheet4]: False

MATCH: [Sheet5]: 3
ISERR: [Sheet5]: False

GOT: [Sheet1]

尽管Sheet1不在排除列表中,但您可以从该输出中看到唯一的工作表输出为Sheet4。而且,从MATCH行开始,Sheet3Sheet4似乎都在排除列表的第2位找到。

因此,立即告诉您问题所在,Excel似乎做错了。但事实上,它正是按照你的要求做的。转到documentation for the Match function,我们会看到这个小片段:

  

<强> expression.Match (Lookup_value, Lookup_array, Match_type)

     
      
  • 如果Match_type为1,Match会找到小于或等于Lookup_value的最大值。 Lookup_array必须按升序排列:... - 2,-1,0,1,2,...,A-Z,FALSE,TRUE。

  •   
  • 如果Match_type为0,Match会找到完全等于Lookup_value的第一个值。 Lookup_array可以按任何顺序排列。

  •   
  • 如果Match_type为-1,Match会找到大于或等于Lookup_value的最小值。 Lookup_array必须按降序排列:TRUE,FALSE,Z-A,... 2,1,0,-1,-2,......等等。

  •   
  • 如果省略Match_type,则假定为1.

  •   

注意最后一句。由于您选择的默认匹配类型为“最大小于或等于”,因此Sheet1会导致错误,因为排除列表中没有小于或等于该条目的条目。

但是,对于Sheet4 匹配。 Sheet2Sheet3都小于或等于Sheet4Sheet3是其中最大的,因此它在第2位“找到”。

您可能会在您的情况下找到 stranger 结果,因为您的工作表不会按字母顺序排序。

然后解决方案是指定完全匹配,而不是使用默认(0调用添加到Match参数):

If IsError(Application.Match(ws.Name, Split(excludeSheets, ","), 0)) Then