我有以下代码,在我看来IF语句有问题。工作簿中有两个选项卡,ALLDATA选项卡和COMP选项卡。该宏应该按日期(ALLDATA选项卡的A列)按金额填充收款人列表(ALLDATA选项卡的第1行)(COMP选项卡上的单独列,以第1行为首)。它应该跳过具有0或空值的单元格。具有数据的所有单元格将具有正值,这就是我正在检查>的原因。 0.以下是ALLDATA选项卡的示例:
这就是我期望输出在COMP选项卡上的样子:
以下是实际输出的结果:
这是我的代码:
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
任何帮助识别我的有缺陷的逻辑/代码都将非常感激。
答案 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;如果没有数字,我认为检查一个值是否为数字就足够了。