多个IF语句使用VBA循环

数据:

这只是我使用的数据的一个示例。

请find下面的输出。 “通过代码输出”是我们运行代码时得到的结果。 “预期产出”是我们正在寻找的。

数据+输出

我之前粘贴的第一个代码及其修改后的版本似乎给出了结果,但唯一的问题是,它将不join一个或两个相似的值。

原始信息:

我已经写了一个“如果陈述”。 该语句比较两行,并在其中一列显示注释。 虽然该语句在excel中运行良好,但VBE中logging的代码却不能。 请帮忙。

声明:

=IF(D2=D3,(IF(G2+H2+G3+H3=0,CONCATENATE("Batch ","'",C2,"'"," has no earnings/hours"),(CONCATENATE(IF(G2=0,"",CONCATENATE("paying ","'",F2,"'"," earnings ",G2)),IF(H2=0,"",IF(H2<>0,IF(G2=0,CONCATENATE("paying ","'",F2,"'"," hours ",H2),CONCATENATE(" and hours ",H2)))),IF(G3=0,"",CONCATENATE(" , paying ","'",F3,"'"," earnings ",G3)),IF(H3=0,"",IF(H3<>0,IF(G3=0,CONCATENATE(" , paying ","'",F3,"'"," hours ",H3),CONCATENATE(" and hours ",H3)))))))),IF(D2<>D3,IF(G2+H2=0,CONCATENATE("Batch ","'",C2,"'"," has no earnings/hours"),CONCATENATE("Batch ","'",C2,"'",CONCATENATE(IF(G2=0,"",CONCATENATE(" paying ","'",F2,"'"," earnings ",G2)),IF(H2=0,"",IF(G2=0,CONCATENATE(" paying ","'",F2,"'"," hours ",H2),CONCATENATE(" and hours ",H2)))))))) 
  1. 我试图为此语句录制一个macros,但是当我在macros中执行录制的代码时出现错误。
  2. 我想将这个语句转换成macros,并将其作为循环直到最后一行结束。
  3. 我想比较行1和行2中的特定单元格,然后执行上面的语句。 然后比较第1行和第2行中两个不同单元格的值,将结果粘贴到另一个单元格中。 一旦执行了这些任务,删除第二行并运行相似的单元格值的循环,join第一个注释和第二个注释。 如果下一行的值不同,则不要删除该行并运行循环,直到所有行的末尾。
  4. 另外,第二个“如果陈述”没有做它想要做的工作。

第二如果陈述:

 =IF(D2<>D3,I2,IF(D2=D3,IF(AND(I2="Y",I3="Y"),"Y",lf(AND(I2="Y",I3="N"),"Y",IF(AND(I2="N",I3="Y"),"Y",IF(AND(I2="N",I3="N"),"N")))))) 

If语句1的VBE代码:

 ActiveCell.FormulaR1C1 = _ "=IF(RC[-6]=R[1]C[-6],(IF(RC[-3]+RC[-2]+R[1]C[-3]+R[1]C[-2]=0,CONCATENATE(""Batch "",""'"",RC[-7],""'"","" has no earnings/hours""),(CONCATENATE(IF(RC[-3]=0,"""",CONCATENATE(""paying "",""'"",RC[-4],""'"","" earnings "",RC[-3])),IF(RC[-2]=0,"""",IF(RC[-2]<>0,IF(RC[-3]=0,CONCATENATE("" paying "",""'"",RC[-4],""'"",""hours"", RC[-2]),CONCATENATE("" and hours "",RC[-2]))" & _ "1]C[-3]=0,"""",CONCATENATE("" , paying "",""'"",R[1]C[-4],""'"","" earnings "",R[1]C[-3])),(IF(R[1]C[-2]=0,"""",IF(R[1]C[-2]<>0,IF(R[1]C[-3]=0,CONCATENATE("" paying "","""",R[1]C[-4],""'"","" hours "",R[1]C[-2]),CONCATENATE("" and hours "",R[1]C[-2]))))))))),IF(RC[-6]<>R[1]C[-6],IF(RC[-3]+RC[-2]=0,CONCATENATE(""Batch "",""'"",RC[-7],""'"","" has no earnings/hours"")" & _ "CONCATENATE(""Batch "",""'"",RC[-7],""'"",CONCATENATE(IF(RC[-3]=0,"""",CONCATENATE("" paying "",""'"",RC[-4],""'"",""earnings "",RC[-3])),IF(RC[-2]=0,"""",IF(RC[-3]=0,CONCATENATE("" paying "",""'"",RC[-4],""'"","" hours "",RC[-2]),CONCATENATE("" and hours "",RC[-2]))))))))" 

最终产出

代码1:

 Sub CompareAndCompare() Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet4") Dim A As Range, B As Range, C As Range, D As Range, E As Range, F As Range Dim compRange As Range: Set compRange = ws.Range("D2", ws.Cells(ws.Rows.Count, "D").End(xlUp)) Dim state1 As String For Each A In compRange 'A = D2 on first iteration of the loop Set B = A.Offset(1) 'B = D3 Set C = A.Offset(0, 3) 'C = G2 Set D = A.Offset(0, 4) 'D = H2 Set E = A.Offset(1, 3) 'E = G3 Set F = A.Offset(1, 4) 'F = H3 Set G = A.Offset(0, 5) 'G = I2 Set H = A.Offset(1, 5) 'H = I3 state1 = "" If A.Value = B.Value Then If G.Value = "N" And H.Value = "N" Then 'Statement 2 ws.Range("K" & A.Row).Value = "N" Else If G.Value = "" And H.Value = "Y" Then ws.Range("K" & A.Row).Value = "Y" Else If G.Value = "Y" And H.Value = "" Then ws.Range("K" & A.Row).Value = "Y" Else If G.Value = "N" And H.Value = "" Then ws.Range("K" & A.Row).Value = "N" Else If G.Value = "" And H.Value = "N" Then ws.Range("K" & A.Row).Value = "N" Else If G.Value = "" And H.Value = "" Then ws.Range("K" & A.Row).Value = "" Else: ws.Range("K" & A.Row).Value = "Y" End If End If End If End If End If End If If C.Value + D.Value + E.Value + F.Value = 0 Then state1 = "'" & ws.Range("F" & A.Row).Value & "', " & "'" & ws.Range("F" & A.Offset(1).Row).Value & "' has no earnings/hours" Else If C.Value <> 0 Then _ state1 = state1 & "paying '" & ws.Range("F" & A.Row).Value & "' earnings " & C.Value If D.Value <> 0 Then If C.Value = 0 Then state1 = state1 & "paying '" & ws.Range("F" & A.Row).Value & "' earnings " & D.Value Else state1 = state1 & " and hours " & D.Value End If End If If E.Value <> 0 Then _ state1 = state1 & " paying '" & ws.Range("F" & A.Offset(1).Row).Value & "' earnings " & E.Value If F.Value <> 0 Then If E.Value = 0 Then state1 = state1 & " paying '" & ws.Range("F" & A.Offset(1).Row).Value & "' hours " & F.Value Else state1 = state1 & " and hours " & F.Value End If End If End If B.EntireRow.Delete Else 'D2 <> D3 ws.Range("K" & A.Row).Value = G.Value 'Statement 2 If C.Value + D.Value = 0 Then state1 = "'" & ws.Range("F" & A.Row).Value & "' has no earnings/hours" Else 'state1 = "'" & ws.Range("F" & A.Row).Value & "'" If C.Value <> 0 Then _ state1 = " paying '" & ws.Range("F" & A.Row) & "' earnings " & C.Value If D.Value <> 0 Then If C.Value = 0 Then state1 = " paying '" & ws.Range("F" & A.Row) & "' hours " & D.Value Else state1 = " and hours " & D.Value End If End If End If End If ws.Range("J" & A.Row).Value = state1 Next A End Sub 

代码2:

 Sub CompareAndCompare1() Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet4") Dim A As Range, B As Range Dim compRange As Range: Set compRange = ws.Range("D2", ws.Cells(ws.Rows.Count, "D").End(xlUp)) Dim state1 As String For Each A In compRange 'A = D2 on first iteration of the loop Set B = A.Offset(1) 'B = D3 Set C = A.Offset(0, 7) 'C =K2 Set D = A.Offset(1, 7) 'D = K3 state1 = "" If A.Value = B.Value Then If C.Value = "N" And D.Value = "N" Then 'Statement 2 ws.Range("L" & A.Row).Value = "N" Else If C.Value = "" And D.Value = "Y" Then ws.Range("L" & A.Row).Value = "Y" Else If C.Value = "Y" And D.Value = "" Then ws.Range("L" & A.Row).Value = "Y" Else If C.Value = "N" And D.Value = "" Then ws.Range("L" & A.Row).Value = "N" Else If C.Value = "" And D.Value = "N" Then ws.Range("L" & A.Row).Value = "N" Else If C.Value = "" And D.Value = "" Then ws.Range("L" & A.Row).Value = "" Else: ws.Range("L" & A.Row).Value = "Y" End If End If End If End If End If End If state1 = "Batch " & ws.Range("C" & A.Row).Value & ": " & ws.Range("J" & A.Row).Value & ", " & ws.Range("J" & A.Offset(1).Row).Value B.EntireRow.Delete Else 'D2<>D3 ws.Range("L" & A.Row).Value = C.Value state1 = "Batch " & ws.Range("C" & A.Row).Value & ": " & ws.Range("J" & A.Row).Value End If ws.Range("M" & A.Row).Value = state1 Next A End Sub 

代码3:

 Sub CompareAndCompare2() Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet4") Dim A As Range, B As Range Dim compRange As Range: Set compRange = ws.Range("A2", ws.Cells(ws.Rows.Count, "A").End(xlUp)) Dim state1 As String For Each A In compRange 'A = A2 on first iteration of the loop Set B = A.Offset(1) 'B = A3 Set C = A.Offset(0, 11) 'C =L2 Set D = A.Offset(1, 11) 'D = L3 state1 = "" If A.Value = B.Value Then If C.Value = "N" And D.Value = "N" Then 'Statement 2 ws.Range("N" & A.Row).Value = "N" Else: ws.Range("N" & A.Row).Value = "Y" End If state1 = "For file# " & ws.Range("A" & A.Row).Value & ", " & ws.Range("M" & A.Row).Value & ", " & ws.Range("M" & A.Offset(1).Row).Value B.EntireRow.Delete Else 'A2<>A3 ws.Range("N" & A.Row).Value = C.Value state1 = "For file# " & ws.Range("A" & A.Row).Value & ", " & ws.Range("M" & A.Row).Value End If ws.Range("O" & A.Row).Value = state1 Next A End Sub 

公式转换为macros

我重新创build了您添加的最后一张照片的原始版本:

在这里输入图像说明

使用下面的重大修改的代码

 Sub CompareAndCompare() Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(1) Dim A As Range, B As Range, C As Range, D As Range, E As Range, F As Range, finalR As Range Dim compRange As Range: Set compRange = ws.Range("D2", ws.Cells(ws.Rows.Count, "D").End(xlUp)) Dim state1 As String, stateTypeA As String, yn As String, myCell As Variant Dim myRow As Long, STATEMENT As String, tempString() As String Dim passOne As Boolean, firstTime As Boolean: firstTime = True Dim st1 As String, st2 As String, output1 As Range, output2 As Range Dim idNo As Range, batchNo1 As Range, batchNo2 As Range For myRow = 2 To compRange.Count + 1 'This loop puts statements in "J" stateType = "" StartOver: Set A = ws.Range("D" & myRow) 'A = D2 Set C = ws.Range("G" & myRow) 'C = G2 Set D = ws.Range("H" & myRow) 'D = H2 Set output1 = ws.Range("J" & myRow) If A.Value = "" Then Exit For STATEMENT = "" If C.Value = 0 Then STATEMENT = STATEMENT & "1" If D.Value = 0 Then STATEMENT = STATEMENT & "2" If C.Value <> 0 Then STATEMENT = STATEMENT & "3" If D.Value <> 0 Then STATEMENT = STATEMENT & "4" stateType = "(" & ws.Range("F" & myRow).Value & ") " Select Case STATEMENT Case "12" 'C = 0, D = 0 state1 = "*" Case "34" 'C <> 0, D <> 0 state1 = stateType & "has earnings of " & C.Value & " and " & D.Value & " hours" Case "14" 'C = 0, D <> 0 state1 = stateType & "has " & D.Value & " hours" Case "23" 'D = 0, C <> 0 state1 = stateType & "has earnings of " & C.Value Case Else: MsgBox STATEMENT 'If a case isn't defined, show STATEMENT so code can be added End Select output1.Value = state1 Next myRow '////////////////////////////////////////////////////////////////////////////////////////////////////////////// For myRow = 2 To compRange.Count + 1 'This Loop concatenates "J" when same "D" Reiterate: Set A = ws.Range("D" & myRow) 'A = D2 on first iteration of the loop Set B = A.Offset(1) 'B = D3 If A.Value = "" Then Exit For If A.Value = B.Value Then CheckForMore: Set G = A.Offset(0, 5) 'G = I2 Set H = A.Offset(1, 5) 'H = I3 If (G.Value = "N" And H.Value = "N") Or ((G.Value = "" Or H.Value = "") And (G.Value = "N" Or H.Value = "N")) Then 'Statement 2 yn = "N" Else: yn = "Y" End If ws.Range("K" & myRow).Value = yn Set B = A.Offset(1) st1 = "(" & ws.Range("F" & myRow).Value & ")" st2 = "(" & ws.Range("F" & myRow + 1).Value & ")" Set output1 = ws.Range("J" & myRow) Set output2 = ws.Range("J" & myRow + 1) If firstTime = True Then If output1.Value = "*" Then firstTime = False stateType = st1 End If End If If output2.Value = "*" And A.Value = B.Value Then If stateType = "" Then stateType = st2 Else: stateType = stateType & ", " & st2 End If B.EntireRow.Delete GoTo CheckForMore ElseIf output1.Value = "*" And firstTime = False And A.Value = B.Value Then output1.Value = "* have no earnings/hours, " & output2.Value B.EntireRow.Delete GoTo Reiterate ElseIf output1.Value <> "*" And firstTime = False And A.Value = B.Value Then output1.Value = output1.Value & ", " & output2.Value B.EntireRow.Delete GoTo Reiterate ElseIf output1.Value <> "*" And stateType <> "" And A.Value = B.Value Then output1.Value = output1.Value & ", * have no earnings/hours, " & output2.Value B.EntireRow.Delete GoTo Reiterate ''''''''''''''''''''''' ElseIf output1.Value = "*" And A.Value <> B.Value Then output1.Value = "* have no earnings/hours " ElseIf output1.Value <> "*" And stateType <> "" Then output1.Value = output1.Value & ", * have no earnings/hours " End If output1.Value = Replace(output1.Value, "*", stateType) firstTime = True stateType = "" Else output1.Value = Replace(output1.Value, "*", stateType) firstTime = True stateType = "" End If Next myRow Set finalR = ws.Range("A2", ws.Cells(ws.Rows.Count, "A").End(xlUp)) passOne = False '///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// For Each myCell In finalR 'This loop finalizes and removes duplicates myRow = myCell.Row finalAgain: Set output1 = ws.Range("J" & myRow) Set output2 = ws.Range("J" & myRow + 1) Set idNo = ws.Range("A" & myRow) Set batchNo1 = ws.Range("C" & myRow) Set batchNo2 = ws.Range("C" & myRow + 1) If myCell.Value = myCell.Offset(1).Value Then If passOne = False Then output1.Value = "FOR " & idNo.Value & ", FROM BATCH " & batchNo1.Value & ": " & output1.Value _ & Chr(10) & "FROM BATCH " & batchNo2.Value & ": " & output2.Value Else: output1.Value = output1.Value & Chr(10) & "FROM BATCH " & batchNo2.Value & ": " & output2.Value End If myCell.Offset(1).EntireRow.Delete passOne = True GoTo finalAgain Else: If passOne = False Then output1.Value = "FOR " & idNo.Value & ", FROM BATCH " & batchNo1.Value & ": " & output1.Value End If passOne = False Next myCell End Sub 

会产生以下结果:

在这里输入图像说明

这看起来类似于你想要的东西。 我对格式进行了一些编辑,使其更易于阅读。 让我知道你的想法,如果这对你的作品:)



下面的原始答案(看看如何将EXCEL公式转换成VBA代码很有用)

我不确定我是否理解你的问题的范围,但是这是直接的转换,尽我所能了解它。 让我知道,如果它的function,你应该怎么想。


我重新创build你的工作表:

在这里输入图像说明


做这样一个转换时,你想要做的第一件事就是把你的公式分解成适当的代码格式。 我包括了ElseEnd if/conc行,使得最后的圆括号更容易遵循:

声明1

 ----------------------------STATEMENT 1----------------------------- IF(D2=D3, (IF(G2+H2+G3+H3=0, CONCATENATE("Batch ","'",C2,"'"," has no earnings/hours"), Else (CONCATENATE( IF(G2=0, "", Else CONCATENATE("paying ","'",F2,"'"," earnings ",G2) end if), IF(H2=0, "", Else IF(H2<>0, IF(G2=0, CONCATENATE("paying ","'",F2,"'"," hours ",H2), Else CONCATENATE(" and hours ",H2) end if) end if) end if), IF(G3=0, "", Else CONCATENATE(" , paying ","'",F3,"'"," earnings ",G3) end if), IF(H3=0, "", Else IF(H3<>0, IF(G3=0, CONCATENATE(" , paying ","'",F3,"'"," hours ",H3), Else CONCATENATE(" and hours ",H3) end if) end if) end if) end concatenate)) end if)) IF(D2<>D3, IF(G2+H2=0, CONCATENATE("Batch ","'",C2,"'"," has no earnings/hours"), Else CONCATENATE("Batch ","'",C2,"'", CONCATENATE( IF(G2=0, "", Else CONCATENATE(" paying ","'",F2,"'"," earnings ",G2) end if), IF(H2=0, "", Else IF(G2=0, CONCATENATE(" paying ","'",F2,"'"," hours ",H2), Else CONCATENATE(" and hours ",H2) end if) end if) end concatenate) end concatenate) end if) end if) end if) 

声明2

 ----------------------------STATEMENT 2----------------------------- =IF(D2<>D3, I2, Else IF(D2=D3, IF(AND(I2="Y",I3="Y"), "Y", Else IF(AND(I2="Y",I3="N"), "Y", Else IF(AND(I2="N",I3="Y"), "Y", Else IF(AND(I2="N",I3="N"), "N" end if) end if) end if) end if) end if) end if) 

有了这个容易阅读的格式,这只是使用适当的VBA词汇表和一点清理的问题

 Sub CompareAndCompare() Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(1) Dim A As Range, B As Range, C As Range, D As Range, E As Range, F As Range Dim compRange As Range: Set compRange = ws.Range("D2", ws.Cells(ws.Rows.Count, "D").End(xlUp)) Dim state1 As String For Each A In compRange 'A = D2 on first iteration of the loop Set B = A.Offset(1) 'B = D3 Set C = A.Offset(0, 3) 'C = G2 Set D = A.Offset(0, 4) 'D = H2 Set E = A.Offset(1, 3) 'E = G3 Set F = A.Offset(1, 4) 'F = H3 Set G = A.Offset(0, 5) 'G = I2 Set H = A.Offset(1, 5) 'H = I3 state1 = "" If A.Value = B.Value Then If G.Value = "N" And H.Value = "N" Then 'Statement 2 ws.Range("K" & A.Row).Value = "N" Else: ws.Range("K" & A.Row).Value = "Y" End If If C.Value + D.Value + E.Value + F.Value = 0 Then state1 = "Batch '" & ws.Range("C" & A.Row).Value & "' has no earnings/hours" Else If C.Value <> 0 Then _ state1 = state1 & "paying '" & ws.Range("F" & A.Row).Value & "' earnings " & C.Value If D.Value <> 0 Then If C.Value = 0 Then state1 = state1 & "paying '" & ws.Range("F" & A.Row).Value & "' earnings " & D.Value Else state1 = state1 & " and hours " & D.Value End If End If If E.Value <> 0 Then _ state1 = state1 & " , paying '" & ws.Range("F" & A.Offset(1).Row).Value & "' earnings " & E.Value If F.Value <> 0 Then If E.Value = 0 Then state1 = state1 & " , paying '" & ws.Range("F" & A.Offset(1).Row).Value & "' hours " & F.Value Else state1 = state1 & " and hours " & F.Value End If End If End If B.EntireRow.Delete Else 'D2 <> D3 ws.Range("K" & A.Row).Value = G.Value 'Statement 2 If C.Value + D.Value = 0 Then state1 = "Batch '" & ws.Range("C" & A.Row).Value & "' has no earnings/hours" Else state1 = "Batch '" & ws.Range("C" & A.Row).Value & "'" If C.Value <> 0 Then _ state1 = state1 & " paying '" & ws.Range("F" & A.Row) & "' earnings " & C.Value If D.Value <> 0 Then If C.Value = 0 Then state1 = state1 & " paying '" & ws.Range("F" & A.Row) & "' hours " & D.Value Else state1 = state1 & " and hours " & D.Value End If End If End If End If ws.Range("J" & A.Row).Value = state1 Next A End Sub 

当我在表单上运行此代码时,这是结果输出:

在这里输入图像说明


它在D2:D3相同时删除行,并继续处理该范围内的其余项(这是dynamic的)。 我没有改变你想要的输出结果。 让我知道你的想法。