what would be the best way to merge similar rows (only order number letter different a4;a6;a8 and produced quantity) and sum (produced quantity e4;e6;e8) cells? This is how excel table looks
Clarification:
Here is the output I'm looking for
Rows 4;6;8 are the same except Order column (one letter added on 6 and 8) and Produced Column (different produced quantity). Rows 4,6,8 are merged and produced quantity is summed. Rows 6,8 is hidden or deleted.
Here is an example that could solve your problem:
Sub test()
i = 1
produced = 0
While Cells(i, 1) <> "" Or Cells(i + 1, 1) <> ""
If Cells(i, 1) <> "" Then
produced = Cells(i, 5)
j = 1
'second loop to add up every line with the same order, then suppress the lines
While Cells(j, 1) <> "" Or Cells(j + 1, 1) <> ""
If Left(Cells(j, 1), 7) = Left(Cells(i, 1), 7) And i <> j Then
produced = produced + Cells(j, 5)
Cells(j, 5).EntireRow.Select
Selection.Delete Shift:=xlUp
j = j - 1
End If
j = j + 1
Wend
End If
i = i + 1
Wend
Ok, here is the modified #Bitoubi code which helped me:
Sub RemoveSplitOrders()
i = 1
produced = 0
While Cells(i, 1) <> "" Or Cells(i + 1, 1) <> ""
If Cells(i, 1) <> "" Then
produced = Cells(i, 20)
j = 1
'second loop to add up every line with the same order, then suppress the lines
While Cells(j, 1) <> "" Or Cells(j + 1, 1) <> ""
If Left(Cells(j, 1), 8) = Left(Cells(i, 1), 8) Or Left(Cells(j, 1), 9) = Left(Cells(i, 1), 9) Then
If Cells(j, 2) = Cells(i, 2) And i <> j Then
produced = produced + Cells(j, 20)
Cells(i, 20).Value = produced
Range(Cells(j, 20), Cells(j + 1, 20)).EntireRow.Delete Shift:=xlUp
j = j - 1
End If
End If
j = j + 1
Wend
End If
i = i + 1
Wend
End Sub
Related
New to stack here.
I'm on VBA and am creating a quoting tool where outputs are generated if certain cells are populated from row 57 onwards. I.e. "For a = 57 to 1000".
For each of row "a" that has values, I'm trying to have Cells(a + 1, 6) output the sum of the previous a columns.
It took some time to find how to reference a range using cells, but I've been stuck from there. To reference the range I've found something along the lines of below
With Sheet1
.Range(.Cells(a, 6), .Cells(a + 1, 6)).Value2 = "b"
End With
The .Range(.Cells(a, 7), .Cells(a + 1, 7)) are the cells that I want to create a sum for but I'm not sure how to do this (and whether the With Sheet1 and End With sections are needed.
Full VBA code here:
Sub OnEntry()
On Error Resume Next
For a = 14 To 1000
If IsEmpty(Cells(a, 3)) = False And IsEmpty(Cells(a, 4)) = True Then
If IsEmpty(Cells(a + 2, 4)) = True And IsEmpty(Cells(a + 3, 4)) = True And IsEmpty(Cells(a + 2, 3)) = True Then
GoTo GoHere
End If
If IsEmpty(Cells(a, 4)) = True And IsEmpty(Cells(a + 1, 4)) = False Then
GoTo GoHere
End If
Find = Range("'Sheet1'!$B$6:$B$5000").Find(Cells(a, 3).Value).Address
Row# = Range(Find).Row
Cells(a, 4) = Sheets("Sheet1").Cells(Row#, 3)
Cells(a, 5).Value = "=VLOOKUP(C" & a & ", 'Sheet1'!$B$6:$F$5000, 4, 0)"
Cells(a, 7).Value = "=B" & a & "*E" & a
If Cells(a - 1, 1) = "Line" Then
Cells(a, 1).Value = 1
Else
Cells(a, 1).Value = Cells(a - 1, 1) + 1
End If
Cells(a + 1, 1).EntireRow.Insert
**Stuck here**
With Sheet2
.Range(.Cells(a + 1, 7), .Cells(a + 2, 7)).Value2 = "b"
End With
End If
Next a
GoHere:
WaitTime = Now() + TimeValue("00:00:02")
While Now() < WaitTime
DoEvents
Wend
End Sub
I have a sample MS Excel table:
I am trying to write a VBA macro that would allow me to compare rows, the comparison is done using multiple cells(A2:E2), and the rest of the cells(F2:I2) would merge its values without comparison. I would like to be able to compare one row - cells(A2:E2) to cells(A3:E3), then cells(A2:E2) to cells(A4:E4)... when it is done comparing it would merge the duplicates - so that cells(Fx:Ix) would merge as well.
The final effect would look like this:
So far I have came up with this code, but running it crashes Excel. Any kind of advice would be much appreciated.
Thanks in advance
Sub MergeDuplicateRows()
Dim i As Long
Dim j As Long
Dim RowCount As Long
Dim sameRows As Boolean
sameRows = True
RowCount = Rows.Count
Application.DisplayAlerts = False
Application.ScreenUpdating = False
For i = 1 To Range("B" & RowCount).End(xlUp).Row
For j = 1 To 5
If StrComp(Cells(i, j), Cells(i + 1, j), vbTextCompare) Then
sameRows = False
End If
Next j
If sameRows Then
Range(Cells(i, 1), Cells(i + 1, 1)).Merge
Range(Cells(i, 2), Cells(i + 1, 2)).Merge
Range(Cells(i, 3), Cells(i + 1, 3)).Merge
Range(Cells(i, 4), Cells(i + 1, 4)).Merge
Range(Cells(i, 5), Cells(i + 1, 5)).Merge
Range(Cells(i, 6), Cells(i + 1, 6)).Merge
Range(Cells(i, 7), Cells(i + 1, 7)).Merge
Range(Cells(i, 8), Cells(i + 1, 8)).Merge
Range(Cells(i, 9), Cells(i + 1, 9)).Merge
End If
sameRows = True
Next i
Application.DisplayAlerts = True
End Sub
Give this a shot - I had to change around some logic, change your For loop to a Do While loop, and instead of merging we're just deleting rows instead. I tested this on your sample data and it worked alright, I'm not sure how it will perform on 1500 rows, though:
Sub MergeDuplicateRows()
Dim i As Long
Dim j As Long
Dim sameRows As Boolean
Application.DisplayAlerts = False
Application.ScreenUpdating = False
i = 2
Do While Cells(i, 2).Value <> ""
For j = 1 To 5
If Cells(i, j).Value <> Cells(i + 1, j).Value Then
sameRows = False
Exit For
Else
sameRows = True
End If
Next j
If sameRows Then
If Cells(i, 6).Value = "" Then Cells(i, 6).Value = Cells(i + 1, 6).Value
If Cells(i, 7).Value = "" Then Cells(i, 7).Value = Cells(i + 1, 7).Value
If Cells(i, 8).Value = "" Then Cells(i, 8).Value = Cells(i + 1, 8).Value
If Cells(i, 9).Value = "" Then Cells(i, 9).Value = Cells(i + 1, 9).Value
Rows(i + 1).Delete
i = i - 1
End If
sameRows = False
i = i + 1
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
I found this code:
Add missing dates VBA
Sub InsertMissingDates()
Dim i As Long
Dim RowCount As Long
i = 4
Do
If Cells(i, 1) + 1 < Cells(i + 1, 1) Then
Rows(i + 1).Insert
Cells(i + 1, 1) = Cells(i, 1) + 1
End If
If (Cells(i + 1, 1) = "") Then
Cells(i + 1, 1) = Cells(i, 1) + 1
End If
i = i + 1
Loop Until Cells(i, 1).Value >= DateSerial(2016, 1, 30)
End Sub
How do I point to column E rather than it column A?
you need to change the parameter on Cells function
https://learn.microsoft.com/en-us/office/vba/api/excel.worksheet.cells
On Cells function the second parameter:
1- A
2- B
3- C
4- D
5- E
So if you change your Code and use 5 instead of 1 it will work on cell E
Sub InsertMissingDates()
Dim i As Long
Dim RowCount As Long
i = 4
Do
If Cells(i, 5) + 1 < Cells(i + 1, 5) Then
Rows(i + 1).Insert
Cells(i + 1, 5) = Cells(i, 5) + 1
End If
If (Cells(i + 1, 5) = "") Then
Cells(i + 1, 5) = Cells(i, 5) + 1
End If
i = i + 1
Loop Until Cells(i, 5).Value >= DateSerial(2016, 1, 30)
End Sub
Use a parameter to determine the column:
Sub InsertMissingDates()
Dim i As Long
Dim RowCount As Long
Dim WhichCol As String
i = 4
WhichCol = "D"
Do
If Cells(i, WhichCol) + 1 < Cells(i + 1, WhichCol) Then
Rows(i + 1).Insert
Cells(i + 1, WhichCol) = Cells(i, WhichCol) + 1
End If
If (Cells(i + 1, WhichCol) = "") Then
Cells(i + 1, WhichCol) = Cells(i, WhichCol) + 1
End If
i = i + 1
Loop Until Cells(i, WhichCol).Value >= DateSerial(2016, 1, 30)
End Sub
I'm trying to copy selected cells to another sheet, but I'm always getting error message: Wrong number of arguments or invalid property assignment
This code checks if "Cells(i, 20)" is less or greater than "Cells (i, 4)" by 10%. If it's not, it deletes the row, if it is it should copy selected cells to another sheet starting 48 row.
Maybe someone could point out, what I'm doing wrong here? Here's how my code looks like:
Sub CopyHighLow()
Sheets("ProductionHighLow").Select
i = 2
j = 48
produced = 0
While Cells(i, 1) <> "" Or Cells(i + 1, 1) <> ""
produced = Cells(i, 20)
ordered = Cells(i, 4)
If Cells(i, 20) > Cells(i, 4) * 0.9 And Cells(i, 20) < Cells(i, 4) * 1.1 Then
Cells(i, 22).Delete Shift:=xlUp
i = i - 1
Else
Range(Cells(i, 1), Cells(i, 2), Cells(i, 3), Cells(i, 4), Cells(i, 20)).Select
Selection.Copy Destination:=Sheets("Rytinis").Range(Cells(j, 1), Cells(j, 2), Cells(j, 3), Cells(j, 4), Cells(j, 5))
j = j + 1
End If
i = i + 1
Wend
End Sub
UPDATE here is working modified version:
Sub CopyHighLow()
Sheets("ProductionHighLow").Select
i = 2
j = 48
produced = 0
While Cells(i, 1) <> "" Or Cells(i + 1, 1) <> ""
produced = Cells(i, 20)
ordered = Cells(i, 4)
If Cells(i, 20) > Cells(i, 4) * 0.9 And Cells(i, 20) < Cells(i, 4) * 1.1 Then
Cells(i, 22).Delete Shift:=xlUp
i = i - 1
Else
Set RangeUnionCopy = Union(Cells(i, 1), Cells(i, 2), Cells(i, 3), Cells(i, 4), Cells(i, 20))
Set RangeUnionPaste = Union(Cells(j, 1), Cells(j, 2), Cells(j, 3), Cells(j, 4), Cells(j, 5))
RangeUnionCopy.Copy Destination:=Sheets("Rytinis").Range(RangeUnionPaste.Address)
j = j + 1
End If
i = i + 1
Wend
End Sub
Problem Explanation
Your problem relies in this line
Range(Cells(j, 1), Cells(j, 2), Cells(j, 3), Cells(j, 4), Cells(j, 5))
The Range object cannot handle more than 2 named cells (this way). You may see it directly in the compiler.
More info at its official documentation
Approach solution:
I would use Union prior to this, like so:
Set RangeUnion = Union(Cells(i, 1), Cells(i, 2), Cells(i, 3), Cells(i, 4), Cells(i, 20))
RangeUnion.Copy Destination:=Sheets("Rytinis").Range(RangeUnion.Address)
This should work for what you are aiming for.
Corrected code using Union:
Sub CopyHighLow()
Dim i, j, produced, ordered
Sheets("ProductionHighLow").Select
i = 2
j = 48
produced = 0
While Cells(i, 1) <> "" Or Cells(i + 1, 1) <> ""
produced = Cells(i, 20)
ordered = Cells(i, 4)
If Cells(i, 20) > Cells(i, 4) * 0.9 And Cells(i, 20) < Cells(i, 4) * 1.1 Then
Cells(i, 22).Delete Shift:=xlUp
i = i - 1
Else
Union(Cells(i, 1), Cells(i, 2), Cells(i, 3), Cells(i, 4), Cells(i, 20)).Select
Selection.Copy Destination:=Sheets("Rytinis").Cells(j, 1)
j = j + 1
End If
i = i + 1
Wend
End Sub
You need to tell it what sheet it copies from.
Sub CopyHighLow()
Sheets("ProductionHighLow").Select
i = 2
j = 48
produced = 0
While Cells(i, 1) <> "" Or Cells(i + 1, 1) <> ""
produced = Cells(i, 20)
ordered = Cells(i, 4)
If Cells(i, 20) > Cells(i, 4) * 0.9 And Cells(i, 20) < Cells(i, 4) * 1.1 Then
Cells(i, 22).Delete Shift:=xlUp
i = i - 1
Else
ActiveSheet.Range(Cells(i, 1), Cells(i, 2), Cells(i, 3), Cells(i, 4), Cells(i, 20)).Select
Selection.Copy Destination:=Sheets("Rytinis").Range(Cells(j, 1), Cells(j, 2), Cells(j, 3), Cells(j, 4), Cells(j, 5))
j = j + 1
End If
i = i + 1
Wend
End Sub
I wrote a very quick script for VBA that takes a spread sheet and organizes it appropriately. For some reason I have just tried using it and I get a user defined error at this loop:
Dim qu As Long
For j = i To 10 Step -1
If Cells(j, 10) = "" Then
qu = j - 1
Do While Cells(qu, 10) = Cells(qu - 1, 10)
Cells(qu, 11) = 10
Cells(qu - 1, 11) = 10
qu = qu - 1
Loop
Cells(j - 1, 11) = 10
End If
Next j
The whole code looks like this:
Sub PopulateNF()
i = 10
Do While Cells(i, 2) <> ""
i = i + 1
Loop
For k = 10 To i Step 1
If Cells(k, 1) <> "" Then
Cells(k, 10) = ""
Else
If InStr(1, Cells(k, 2), "Received") Then
Cells(k, 10) = -1
ElseIf InStr(1, Cells(k, 2), "Workflow") Then
Cells(k, 10) = 0
ElseIf InStr(1, Cells(k, 2), "Forwarded") Then
Cells(k, 10) = 1
ElseIf InStr(1, Cells(k, 2), "Review Response") Then
Cells(k, 10) = 2
ElseIf InStr(1, Cells(k, 2), "Responded and Closed") Then
Cells(k, 10) = 4
ElseIf InStr(1, Cells(k, 2), "Sent") Then
Cells(k, 10) = 3
ElseIf InStr(1, Cells(k, 2), "Sent and Closed") Then
Cells(k, 10) = 3
End If
End If
Next k
Dim qu As Long
For j = i To 10 Step -1
If Cells(j, 10) = "" Then
qu = j - 1
Do While Cells(qu, 10) = Cells(qu - 1, 10)
Cells(qu, 11) = 10
Cells(qu - 1, 11) = 10
qu = qu - 1
Loop
Cells(j - 1, 11) = 10
End If
Next j
For a = i To 10 Step -1
If Cells(a, 1) <> "" Then
Cells(a, 11) = 10
End If
Next a
Const colA As Long = 11
Dim lngRow As Long
Dim lngLastRow As Long
lngLastRow = Cells.SpecialCells(xlCellTypeLastCell).Row
lngRow = 10
Do While lngRow <= lngLastRow
If Cells(lngRow, colA) = "" Then
Cells(lngRow, 1).EntireRow.Delete
lngLastRow = lngLastRow - 1
Else: lngRow = lngRow + 1
End If
Loop
d = 10
Do While Cells(d, 2) <> ""
d = d + 1
Loop
For k = 6 To d Step 1
If Cells(k, 1) = "" Then
Cells(k, 1) = Cells(k, 6)
Cells(k, 6) = ""
Cells(k, 2) = Cells(k, 7)
Cells(k, 7) = ""
Cells(k, 3) = Cells(k - 1, 3)
Cells(k, 4) = Cells(k - 1, 4)
Cells(k, 5) = Cells(k - 1, 5)
Cells(k, 6) = Cells(k - 1, 6)
Cells(k, 7) = Cells(k - 1, 7)
Cells(k, 8) = Cells(k - 1, 8)
Cells(k, 9) = Cells(k - 1, 9)
End If
Next k
Const colAN As Long = 1
Dim lngRowN As Long
Dim lngLastRowN As Long
lngLastRowN = Cells.SpecialCells(xlCellTypeLastCell).Row
lngRowN = 9
Do While lngRowN <= lngLastRowN
If Cells(lngRowN, colAN) = "" Then
Cells(lngRowN, 1).EntireRow.Delete
lngLastRowN = lngLastRowN - 1
ElseIf InStr(1, Cells(lngRowN, colAN), "_") Then
Cells(lngRowN, 1).EntireRow.Delete
lngLastRowN = lngLastRowN - 1
Else: lngRowN = lngRowN + 1
End If
Loop
Range("a9").CurrentRegion.Sort key1:=Range("a9"), order1:=xlAscending, Header:=xlGuess
Range("D:D").NumberFormat = "mm/dd/yyyy"
Range("F:I").NumberFormat = "mm/dd/yyyy"
Range("C:I").HorizontalAlignment = xlCenter
Range("a:a").VerticalAlignment = xlTop
Range("J:K").EntireColumn.Delete
Range("A:J").Font.Color = vbBlack
MsgBox ("Reformatting Complete")
End Sub
Any help would be greatly appreciated!
Stepping through the code looks like your loop doesn't know where to end.
Basically the line:
Do While Cells(qu, 10) = Cells(qu - 1, 10)
is never false and "qu-1" eventually becomes negative.
I'm not sure if this works with the greater bulk of your code, but you could try:
Do While qu <> 1
That should close your loop while still allowing you to modify cell values within the loop.