Excel consolidate same values on column1 while keeping data - excel

I have a excel table which looks like this one.
As you can see, this products 2005 and 3004 are listed more than once because this same products have different price value based on sale scala. Like, if you buy 50 each of that item, the price gets lower.
What I want is -assuming there is a way to achieve- is this :
ProductID Column is Unique and entrys with same product ID gathers on 1 row. With their Sale Scala and Price(Per) values added(if there is) within next columns. Is there a solution to alter the table like this with coding ? There is too much line to manually edit.
Please Suggest. Thanks.

There are probably better ways to do this but I've created a simple loop that looks for duplicate values in column A then processes the data accordingly. I'm working bottom up for simplicity. Note: You'll have to manually create your headers when finished unless you want to add more logic.
EDIT Simpler code
Sub TransposeData()
Dim WS As Worksheet
Dim LastCell As Range
Dim LastCellRowNumber As Long
Set WS = Worksheets("Sheet1")
With WS
Set LastCell = .Cells(.Rows.Count, "A").End(xlUp)
LastCellRowNumber = LastCell.Row
End With
'Loop through column A bottom up
For i = LastCellRowNumber To 2 Step -1
' Check if value in current cell matches value in cell above it
If (Range("A" & i).Value = Range("A" & i).Offset(-1, 0).Value) Then
'Shift current values over
Range("C" & i & ":D" & i).Insert Shift:=xlToRight
'Copy new values down
Range("C" & i).Value = Range("C" & i - 1).Value
Range("D" & i).Value = Range("D" & i - 1).Value
'Delete row
Rows(i - 1).Delete Shift:=xlUp
End If
Next i
End Sub
Results:

Related

VBA Looping cells and Copy based on criteria

[Copy A2 to E2 till the end of row of the table and check if the cell is within the same month](https://i.stack.imgur.com/Q7YAx.png)
Hi,
I would like to loop through rows from a sheet table from column A2 to E2 to A3 to E3... till the end of the table Ai to Ei by defining a variable and counting the last row of the table.
As the second step, I would like to copy the cells into another sheet and fill it the corresponding months.
[Desired Output--> it will copy the data and return to another sheet in the corresponding month] (https://i.stack.imgur.com/zhgYh.png)
Instead, I've changed the data type into a number format and have set up two condition to loop through.
eg. 1/1/2017 change to 42736
28/2/2017 change to 42794
Sub Mike_Copy_cell()
Dim i As Long 'for looping inside each cell
Dim myvalue As Variant
Dim Lastrow As Long
Const StartRow As Byte = 2
Dim LastMonth As Long
("Mike Filter").Select
Lastrow = Range("A" & StartRow).End(xlDown).Row
For i = StartRow To Lastrow
myvalue = Range("H" & i).Value
If myvalue \< Sheets("Automate Report").Range("A" & i).Value \_
'First data Feb Data 42794 \< Jan Category 42736
Then Sheets("Automate Report").Range("B" & i).Value = ""
'leave the cells in blanks and loop through next cell
If myvalue > Sheets("Automate Report").Range("A" & i).Value _
'First data Feb Data 42794 > Jan Category 42736
Then Range("A" & i, "E" & i).Copy Sheets("Automate Report").Range("B" & i, "F" & i)
'Copy the cells into corresponding category
Next i
End sub()
In my output, it is able to loop through and copy all the cells. However, I am wondering the reason why VBA output is not able leave any blank cells when the first condition is met ?
**I am expecting some blanks in the table if it is not data is not within the same month or in my case is less than criteria I have set. **
The output of my code
If myvalue < Sheets("Automate Report").Range("A" & i).Value _
Then Sheets("Automate Report").Range("B" & i).Value = ""
Greatly appreciate if you can advise the flaws in my code. Massive Thanks.
Best regards,
Kenneth
I'll try to help. But before, may I give you two suggestions that might help you?
First, for me the best way to find the last row is, instead of using xldown from the first row, using xlup from the very last row of excel. This way, if there is a blank in any middle row, the code still gives you the last row with value.
Second, I found that referring to any cells with the "range" method may limit you sometimes when using variables in this reference. I think using the "cells(row, column)" method is more useful.
Why not trying this?
Lastrow = Cells(Rows.Count, 1).End(xlUp).Row
Sorry for the suggestions, It's just that I wish someone had taught them to me sooner.
Back to the topic, I think the problem is how you structure the "if" statement. Allow me to change it a bit:
Lastrow = Cells(Rows.Count, 1).End(xlUp).Row
For i = StartRow To Lastrow
myvalue = cells(i, 8).Value
'if myvalue date is equal or previous to the one found in Ai...
If myvalue <= Sheets("Automate Report").cells(i, 1).Value then
Sheets("Automate Report").cells(i, 2).Value = ""
'but if myvalue is later than Ai...
else
sheets("Automate Report").select
range(cells(i, 1), cells(i, 5).select
selection.copy
cells(i, 2).select
activesheet.paste
end if
Next i
Hope this helps. Best regards,
Mike
I'm not sure what your code is doing but consider using an array(12) of row numbers, one for each month. Copy lines into corresponding month and increment the row number for that month. For example ;
Option Explicit
Sub Mike_Copy_cell()
Const LINES_MTH = 5 ' lines per month
Dim wb As Workbook
Dim wsIn As Worksheet, wsOut As Worksheet
Dim lastrow As Long, rIn As Long, rOut(12) As Long
Dim uid As String, prevuid As String
Dim dAVD As Date, m As Long, n As Long
Set wb = ThisWorkbook
Set wsIn = wb.Sheets("Mike Filter")
Set wsOut = wb.Sheets("Automate Report")
' space out months
For n = 0 To 11
rOut(n + 1) = 2 + n * LINES_MTH
wsOut.Cells(rOut(n + 1), "A").Value2 = MonthName(n + 1)
Next
n = 0
With wsIn
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
For rIn = 2 To lastrow
dAVD = .Cells(rIn, "D")
' create a unique ID to skip duplicates
uid = .Cells(rIn, "A") & Format(.Cells(rIn, "D"), "YYYY-MM-DD")
If uid <> prevuid Then
m = Month(dAVD)
.Cells(rIn, "A").Resize(, 5).Copy wsOut.Cells(rOut(m), "B")
rOut(m) = rOut(m) + 1
n = n + 1
End If
prevuid = uid
Next
End With
MsgBox n & " lines copied to " & wsOut.Name, vbInformation
End Sub

Using a cell in a loop to define a range in vba. I want to basically delete the row of that cell and the next 3 ones

I'm basically writing a clean up program to make it more straight forward to access data. Anywho, I ran into possibly a nomenclature error. I want to use the "current" cell in a "for" loop to delete that row and the next 3 rows. Code looks something like this:
For Each SingleCell In SingleSheet1.Range("a1:a40")
If SingleCell.Value = "S" Or SingleCell.Value = "B" Then
Range(SingleCell.Range, SingleCell.Range.Offset(4, 0)).EntireRow.Delete Shift:=xlUp
Else
End If
Next
I tried to define the range to delete as specified in the code but it gave me a runtime error
Delete backwards looping trough row number:
Sub EXAMPLE_1()
Dim i As Long
For i = 40 To 1 Step 1
If Range("A" & i).Value = "S" Or Range("A" & i).Value = "B" Then Range("A" & i & ":A" & i + 3).EntireRow.Delete Shift:=xlUp
Next i
End Sub
Sub EXAMPLE_2()
Dim i As Long
Dim LR As Long 'in case last row is not always number 40, adapt it dinamically
LR = Range("A" & Rows.Count).End(xlUp).Row
For i = LR To 1 Step 1
If Range("A" & i).Value = "S" Or Range("A" & i).Value = "B" Then Range("A" & i & ":A" & i + 3).EntireRow.Delete Shift:=xlUp
Next i
End Sub
Your code looses the reference for the deleted rows and you should iterate backwards, if you like iteration between cells (which is slow), but a better/faster solution will be to build a Union range and delete all rows at the code end, at once:
Sub testDeleteOffset()
Dim sh As Worksheet, Urng As Range, i As Long
Set sh = ActiveSheet
For i = 1 To 40
If sh.Range("A" & i).Value = "S" Or sh.Range("A" & i).Value = "B" Then
addToRange Urng, sh.Range("A" & i, "A" & i + 3)
i = i + 4
End If
Next i
If Not Urng Is Nothing Then Urng.EntireRow.Delete xlUp
End Sub
If the involved range is huge, a better solution will be to place some markers for the necessary rows (after last existing column), sort on that marker column and delete the (consecutive marked) rows. Another column with the initial order would be necessary to re-sort according to it at the end... The idea is that building a Union range having more than 1000 areas may become slow.

Find duplicates in Column A and combine and separate all text values in column D then remove all duplicate rows

I have a script but it only takes the first value in column D then removes all duplicates. I'm sorry but I'm just learning VBA and need some help. Can this be adjusted or programmed differently to combine all the text values in column D separated by a colon?
To explain we are exporting ticket data and importing to a new tool but their import won't accept duplicates of ticket IDs (numbers, 1000-9000). Our thought is if we can combine the labor descriptions which contains our labor notes then we can retain the data we need and ignore the other info we do not need.
Sub foo()
Dim ws As Worksheet
Dim lstrow As Long
Set ws = Sheets("g1") ' Change to your sheet
With ws
lstrow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("B4:M" & lstrow)
.Offset(, 26).FormulaR1C1 = "=IFERROR(INDEX(R4C[-26]:R" & lstrow & "C[-26],MATCH(1,INDEX((R4C1:R" & lstrow & "C1 = RC1)*(R4C[-26]:R" & lstrow & "C[-26] <>""""),),0)),"""")"
ws.Calculate
.Value = .Offset(, 26).Value
.Offset(, 26).ClearContents
End With
With .Range("A4:M" & lstrow)
.Value = .Value
.RemoveDuplicates 1, xlGuess
End With
End With
End Sub
This definitely removes all duplicates but only keeps the first cell value it finds in the secondary column.

How do I move specific valued cells in VBA?

I am working with a dataset that contains both numbers and names. In the dataset, some numbers and names are displayed and instead of manually going through thousands of rows I tried to make a script but it doesn´t happen anything.
Here is the code:
Sub MoveCells()
Dim row As Long
For row = 2 To LastRow
If Range("C" & row).Value Like "*0*" Then
Dim i As Integer
For i = 1 To 2
Range("C" & row).Insert Shift:=xlToRight
Next
End If
Next
End Sub
I am trying to move the cell that has a 0 in it, and the cell to the right of it, one step to right.
E.g. Cells C4 & D4 to D4 & E4.
I've made some adjustments to your code which will acheive the outcome you described.
Private Sub MoveCells()
Dim TargetRow As Long
Dim LastRow As Long
Dim ColumnCValue As Variant
Dim ColumnDValue As Variant
With Sheets("Sheet1")
LastRow = .Cells(.Rows.Count, 3).End(xlUp).row
End With
For TargetRow = 2 To LastRow
If Sheets("Sheet1").Range("C" & TargetRow).Value Like "*0*" Then
ColumnCValue = Sheets("Sheet1").Range("C" & TargetRow).Value
ColumnDValue = Sheets("Sheet1").Range("D" & TargetRow).Value
Sheets("Sheet1").Range("D" & TargetRow).Value = ColumnCValue
Sheets("Sheet1").Range("E" & TargetRow).Value = ColumnDValue
Sheets("Sheet1").Range("C" & TargetRow).ClearContents
End If
Next
End Sub
Now we first assign a value to for LastRow and when the If...Then statement is true, assign the values of Column C and Column D to the respective variables. Then, write those values 1 row to the right and finally clear the contents from Column C.

Need to Identify Certain Cells and then move the whole row to another worksheet

There is a master order form that has several SKU numbers on it such as 22-1,22-99, 11-1,11-22 etc. What I have been struggling to do is identify all the cells that start with the same number and then select the entire row to move them to a new worksheet. The code provided moves a single cell but I have to move the entire row next with that cell.
Sub Findandcut()
Dim row As Long
For row = 2 To 1000
' Check if "save" appears in the value anywhere.
If Range("A" & row).Value Like "*save*" Then
' Copy the value and then blank the source.
Range("I" & row).Value = Range("A" & row).Value
Range("A" & row).Value = ""
End If
Next
End Sub
The output needed would be all the SKUs that start with the same number get moved to a new worksheet.
Take a look at Range.EntireRow : https://learn.microsoft.com/en-us/office/vba/api/excel.range.entirerow
You can select your entire row like this:
ws.Range("*any cell in the row you want*").EntireRow.Select
then do what you want with the row (i.e, move it, copy it, etc)
Edit2: full working code which should do what you want it to do.
Sub Findandcut()
Dim row As Long
For row = 2 To 1000
' Check if "save" appears in the value anywhere.
If Range("A" & row).Value Like "*save*" Then
' Copy the value and then blank the source.
Range("A" & row).EntireRow Cut Sheet2.Range("I" & row) 'cut and paste to Sheet2
Range("A" & row).Value = "" 'delete row for cleanup purposes
End If
Next
End Sub
Sub Findandcut()
Dim rw As Long
Dim lastrow As Long
lastrow = Worksheets("Sheet2").UsedRange.Rows(Worksheets("Sheet2").UsedRange.Rows.Count).row
For rw = 1000 To 2 Step -1
With Worksheets("Sheet1")
' Check if "save" appears in the value anywhere.
If .Cells(rw, 1).Value Like "*11-*" Then
' Cut the value and then blank the source and shift up
.Cells(rw, 2).EntireRow.Cut Destination:=Worksheets("Sheet2").Cells(lastrow, 1)
.Cells(rw, 2).EntireRow.Delete (xlUp)
End If
End With
lastrow = Worksheets("Sheet2").UsedRange.Rows(Worksheets("Sheet2").UsedRange.Rows.Count).row +1
Next
End Sub
I think this should do what you are looking for.

Resources