VBA-某些数据仅在第二次运行后可见

时间:2019-02-08 09:44:05

标签: excel vba

下面的代码执行以下操作:

  1. 从“源”工作表中复制特定行
  2. 将行粘贴到“目标”工作表中
  3. 计算“类型”(E列)并将其插入J列

我遇到的问题是第3步。宏应该做的是:

  1. 第一列,第3-5行->插入列标题“缺陷”, “系统”,“脚本”
  2. 根据中的每个条件执行E列的CountIf函数 第一栏
  3. 在相应列的J列中输出值(计数) 第I列旁边的行

例如:

  • 第一列,第3行->缺陷
  • J列,第3行->发生“缺陷”的次数 列E

但是,似乎正在发生的事情是

  1. 第一列中填充了正确的条件
  2. 执行CountIf(看起来正确)并插入 J列中的值
  3. 在插入值时,将删除第一列中的条件 我只剩下J列中的数字值

现在,如果我第二次运行宏,那么它会按预期运行,我无法理解为什么。

此外,列E中没有“缺陷”条目,因此值是0。但是在第一次运行时,您看不到0,只是空白。在第二次运行中,它显示值为0。

Sub Copy()

    Dim xRg As Range, xCell As Range
    Dim i As Long, J As Long, K As Long, x As Long, count As Long
    Dim y As Workbook
    Dim ws1 As Worksheet
    Dim element As Variant, myarray As Variant

    myarray = Array("Defect", "System", "Script")

    i = Worksheets("source").UsedRange.Rows.count
    J = Worksheets("target").UsedRange.Rows.count

    count = 3

    Set y = Workbooks("myWKBK.xlsm")

    Set ws1 = y.Sheets("target")

    If J = 1 Then

        If Application.WorksheetFunction.CountA(Worksheets("target").UsedRange) = 0 Then J = 0

    End If

    lngLastRow = Cells(Rows.count, "C").End(xlUp).Row

    Set xRg = Worksheets("source").Range("E3:E" & lngLastRow & i)

    On Error Resume Next
    Application.ScreenUpdating = False

    With ws1

        'Assign name to columns where values will be pasted
        .Range("$B$2").Value = "ID"
        .Range("$C$2").Value = "Status"
        .Range("$D$2").Value = "Description"
        .Range("$E$2").Value = "Type"
        .Range("$F$2").Value = "Folder"
        .Range("$G$2").Value = "Defect ID"
        .Range("$I$2").Value = "Type"
        .Range("$I$3").Value = "Defect"
        .Range("$I$4").Value = "System"
        .Range("$I$5").Value = "Script"
        .Range("$J$2").Value = "Count"

    End With

    For Each element In myarray

        For K = 1 To xRg.count

            If CStr(xRg(K).Value) = element Then

                LastRow = ws1.Cells(Rows.count, "B").End(xlUp).Row + 1
                xRg(K).EntireRow.Copy Destination:=ws1.Range("A" & LastRow)

                J = J + 1

            End If

        Next

        x = Range("E" & Rows.count).End(xlUp).Row

        Range("J" & count) = Application.WorksheetFunction.CountIf(Range("E3:E" & x), element)

        count = count + 1

    Next element

    ws1.Columns("B:J").AutoFit

    Application.ScreenUpdating = True

End Sub

编辑:

值得一提的是,下面的子程序本身就可以正常工作:

Sub CountIf()

    Dim element As Variant
    Dim myarray As Variant

    myarray = Array("Defect", "System", "Script")

    Dim count As Long

    count = 3

    For Each element In myarray

        Dim x As Long
        x = Range("E" & Rows.count).End(xlUp).Row
        Range("J" & count) = Application.WorksheetFunction.CountIf(Range("E3:E" & x), element)

        count = count + 1

    Next element

End Sub

此函数仅自行执行CountIf,并且完全按预期工作。

1 个答案:

答案 0 :(得分:0)

这是代码中非常漂亮的一部分:

Set xRg = Worksheets("source").Range("E3:E" & lngLastRow & i)

它可以正确设置Range对象的父级工作表,因此VBA知道在哪里查看。但是,由于某些原因,并不总是这样。看看这些行:

lngLastRow = Cells(Rows.count, "C").End(xlUp).Row
x = Range("E" & Rows.count).End(xlUp).Row
Range("J" & count) = Application.WorksheetFunction.CountIf(Range("E3:E" & x), element)

未设置工作表的位置。因此,它使用代码所在的ActiveSheet或工作表(如果它在工作表中而不在模块中)。按照代码的漂亮部分(例如,定义工作表)尝试重写它:

With Worksheet("SomeName")
    lngLastRow = .Cells(Rows.count, "C").End(xlUp).Row
    x = .Range("E" & Rows.count).End(xlUp).Row
    .Range("J" & count) = Application.WorksheetFunction.CountIf(Range("E3:E" & x), element)
End With

下一步要调试,请尝试删除On Error Resume Next,因为它会忽略应用程序中的错误,并可能因此提供错误的结果。