Excel VBA如果然后没有正确评估

时间:2016-10-17 16:35:24

标签: excel vba excel-vba

我有以下代码,在我看来IF语句有问题。工作簿中有两个选项卡,ALLDATA选项卡和COMP选项卡。该宏应该按日期(ALLDATA选项卡的A列)按金额填充收款人列表(ALLDATA选项卡的第1行)(COMP选项卡上的单独列,以第1行为首)。它应该跳过具有0或空值的单元格。具有数据的所有单元格将具有正值,这就是我正在检查>的原因。 0.以下是ALLDATA选项卡的示例:

enter image description here

这就是我期望输出在COMP选项卡上的样子:

enter image description here

以下是实际输出的结果:

enter image description here

这是我的代码:

Sub Payee_Date()
'
' Payee_Date Macro
'
Application.ScreenUpdating = False

'Select the COMP tab
Sheets("COMP").Activate

'Find the last row of the COMP tab
Dim compLastRow As Long
compLastRow = Cells(Rows.Count, 1).End(xlUp).Row

'Clear the COMP tab
With Sheets("COMP")
    .Rows(2 & ":" & compLastRow).Delete
End With

'Select the ALLDATA tab
Sheets("ALLDATA").Activate

'Find the last row of the ALLDATA tab
Dim alldataLastRow As Long
alldataLastRow = Cells(Rows.Count, 1).End(xlUp).Row

'Find the last column of the ALLDATA tab
Dim alldataLastColumn As Long
With ActiveSheet
    alldataLastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With

'Loop through the sheet and populate the COMP tab
Dim alldataColNum As Integer
Dim alldataRowNum As Integer
Dim compRowNum As Long
Dim payee As String
Dim day As String
Dim amount As Double

compRowNum = 2

For alldataColNum = 2 To alldataLastColumn Step 1
    For alldataRowNum = 2 To alldataLastRow Step 1
        If Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value > 0 And   IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False Then _
            amount = Cells(alldataRowNum, alldataColNum).Value2
            payee = Cells(1, alldataColNum).Value2
            day = Cells(alldataRowNum, 1).Value2

                Sheets("COMP").Activate
                Range("A" & compRowNum).Value = day
                Range("B" & compRowNum).Value = payee
                Range("C" & compRowNum).Value = amount
                Sheets("ALLDATA").Activate

                compRowNum = compRowNum + 1
    Next alldataRowNum
Next alldataColNum

Application.ScreenUpdating = True

'
End Sub

任何帮助识别我的有缺陷的逻辑/代码都将非常感激。

4 个答案:

答案 0 :(得分:3)

你有一个非常细微的错误,它由行继续符号引入:

If Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value > 0 And   IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False Then **_**

该延续字符会导致"然后"如果测试条件的计算结果为true,则执行下一语句的部分,并立即终止IF块。控制继续,执行跟随它的所有行 - 你打算由' if / then'控制。脱掉那个尾随" _"并添加一个" End If"就在最里面的Next之前,它应该解决你的问题。

For alldataRowNum = 2 To alldataLastRow Step 1
    If Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value > 0 And   IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False Then 
        amount = Cells(alldataRowNum, alldataColNum).Value2
        payee = Cells(1, alldataColNum).Value2
        day = Cells(alldataRowNum, 1).Value2

            Sheets("COMP").Activate
            Range("A" & compRowNum).Value = day
            Range("B" & compRowNum).Value = payee
            Range("C" & compRowNum).Value = amount
            Sheets("ALLDATA").Activate

            compRowNum = compRowNum + 1
   End If ' Add the IF block closure here
Next alldataRowNum

答案 1 :(得分:2)

逻辑行

VBA规范定义了逻辑代码行的概念。

这跨越代码模块中的4行:

If _
    True _
        Then _
            MsgBox "Hi!"

但就VBA而言,它只是一行逻辑代码行;语句的解析和解释如下:

If True Then MsgBox "Hi!"

哪个是完全有效的VBA:下划线字符被解析为行继续标记,VBA将其解释为位于同一逻辑行。

也适用于评论(虽然这是一件好事,但这是有争议的):

'This comment starts here _
         ...and continues there

内联与阻止条件

条件If语句支持两种语法:

  • 内联语法,如上所述:

    If True Then MsgBox "Hi!"
    
  • 阻止语法:

    If True Then
        MsgBox "Hi!"
    End If
    

使用块语法时,Then关键字和End If标记之间的每个语句都将按指定条件有条件地执行。

如果在代码的逻辑行上的Then关键字后面有任何语句,VBA会尝试将该指令解析为内联语法< / em>的;如果{EndOfLineInstruction}令牌(新行,基本上)跟在Then关键字之后,VBA将解析条件作为块语法,并且期望在到达当前范围的末尾之前遇到End If标记(例如End Sub标记)。如果没有End If令牌,则VBA会抛出编译错误。

在您的情况下,您有:

If someCondition Then _
    DoSomething
    DoSomethingElse

解析为:

If someCondition Then DoSomething
DoSomethingElse

但你的意图是:

If someCondition Then
    DoSomething
    DoSomethingElse
End If

答案 2 :(得分:1)

条件的一部分总是测试为真,因为您存储了之前迭代的值,所以每次测试都会重复它。你的条件:

IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False

应该是:

Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2 = ""

这将捕获空单元格并跳过它们。

答案 3 :(得分:0)

尝试替换此行:

If Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value > 0 And   IsEmpty(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum).Value2) = False Then _

使用:

If IsNumeric(Sheets("ALLDATA").Cells(alldataRowNum, alldataColNum)) Then 

正如您所使用的那样&#34; - &#34;如果没有数字,我认为检查一个值是否为数字就足够了。