I have read just about every other question on here on merging rows and consolidating data. I did come across a solution I think will work for me, but when I ran the macro it didn't actually sum the right column. Being new to VBA, I'm having trouble figuring out what needs to change in the macro to work in my sheet.
Background:
I want to use a macro because I get a report every day that I have to manipulate so that it can process into our system. I have created a VBA macro to do the manipulation for me, but I have realized that the report now has duplicate lines with different values. Below is an example with the last set of numbers needing to be added together. (Column J on my actual report)
i.e.
Row 1: C3=1234, Name, C5=ABC, C5Name, C4=DEF, C4Name, 21361
Row 2: C3=1234, Name, C5=ABC, C5Name, C4=DEF, C4Name, 132165
This is the solution I found, but I need to know what to change to correspond with the column I actually need summed up.
Sub Merge()
Dim ColumnsCount As Integer
Dim i As Integer
Range("A1").Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, Orientation:=xlTopToBottom, DataOption1:=xlSortNormal
Do While ActiveCell.Row <= ActiveSheet.UsedRange.Rows.Count
If ActiveCell.Value = ActiveCell.Offset(1, 0).Value Then
For i = 1 To ColumnsCount - 1
ActiveCell.Offset(0, i).Value = ActiveCell.Offset(0, i).Value + ActiveCell.Offset(1, i).Value
Next
ActiveCell.Offset(1, 0).EntireRow.Delete shift:=xlShiftUp
Else
ActiveCell.Offset(1, 0).Select
End If
Loop
End Sub
Any and all help is greatly appreciated. Please let me know if I need to provide additional information.
~Andrea
It would have been better to see your table. You still have not explained enough. This answer is not so different from user1016274's answer. The code above first order by the columns B, D and H then checks and deletes the duplicates by the time adding up their J column values, by comparing same columns.
Sub Merge()
Range("A1").Sort Key1:=Range("B1"), Order1:=xlAscending, Key2:=Range("D1"), Order2:=xlAscending, _
Key3:=Range("H1"), Order3:=xlAscending, Header:=xlYes
'I assume there are column headers. If not, use "Header:=xlNo" instead of "Header:=xlYes"
Range("A2").Select 'I assume there are column headers. If not, use "Range("A1").Select" instead of "Range("A2").Select"
Do While ActiveCell.Row <= ActiveSheet.UsedRange.Rows.Count
If ActiveCell.Offset(0, 1).Value = ActiveCell.Offset(1, 1).Value And ActiveCell.Offset(0, 3).Value = ActiveCell.Offset(1, 3).Value And ActiveCell.Offset(0, 7).Value = ActiveCell.Offset(1, 7).Value Then
ActiveCell.Offset(0, 9).Value = ActiveCell.Offset(0, 9).Value + ActiveCell.Offset(1, 9).Value
ActiveCell.Offset(1, 0).EntireRow.Delete shift:=xlShiftUp
Else
ActiveCell.Offset(1, 0).Select
End If
Loop
End Sub
You don't have to loop through all columns just to add column J's values:
If ActiveCell.Value = ActiveCell.Offset(1, 0).Value Then
ActiveCell.Offset(0, 10).Value = ActiveCell.Offset(0, 10).Value + ActiveCell.Offset(1, 10).Value
ActiveCell.Offset(1, 0).EntireRow.Delete shift:=xlShiftUp
Else
ActiveCell.Offset(1, 0).Select
End If
BTW, are you sure you want to increment the active cell's row only if the row is not duplicated? Might be that it works because of the DeleteRow operation but I just wanted to ask.
edit: deleted orphaned Next statement, sorry.
Related
I would like to copy certain cells from a report to another worksheet.
There are two conditions and two rows to copy if one of the conditions applies.
As I am new to VBA, I don`t get the loop to work.
Main problem: How to increment the row that is to be searched and that is the paste target (B1->B2->B3..).
The loop is supposed to check and copy until the last row of the report.
So the
Can somebody help me how to code the loop or explain in an easy way how to do that? Thank you! :)
Sub CopyRow()
'Return to Sheets("CS15 Download"), Find Last Row and LastRow = that row
Sheets("CS15").Select
Range("A8").Select
Selection.End(xlDown).Select
ActiveCell.Offset(0, 1).Range("A1").Select
Selection.End(xlUp).Select
LastRow = ActiveCell.Row
Dim ObjDes As Variant
Const Lvl As Integer = 1
ObjDes = Range("Q1").Value
Range("B3").Select
If Range("B3").Value = Lvl Then
Sheets("Report").Range("B2").Value = Range("F3").Value
Sheets("Report").Range("C2").Value = Range("G3").Value
ActiveCell.Offset(1, 0).Range("A1").Select
ElseIf InStr(Range("G3").Value, ObjDes) > 0 Then
Sheets("Report").Range("B2").Value = Range("F3").Value
Sheets("Report").Range("C2").Value = Range("G3").Value
ActiveCell.Offset(1, 0).Range("A1").Select
Else
ActiveCell.Offset(1, 0).Range("A1").Select
End If
End Sub
I have several tables pasted one after another, I am trying to add two extra columns, one for the skill name and one for the date. When i run this code, the columns are added and I can see the pointer going to each cell, but it is not assigning any values. I will appreciate your suggestions on this code.
Dim date_var As String
Dim skill_var As String
Dim msg_var As Integer
Sub Add_Date_Skill()
ThisWorkbook.ActiveSheet.Range("A1").Select
ActiveCell.EntireColumn.Insert
ActiveCell.EntireColumn.Insert
ThisWorkbook.ActiveSheet.Range("C2").Select
Do While Not IsEmpty(ActiveCell.Value)
If ActiveCell.Value = "Date" Then
ActiveCell.Offset(0, 1).Select
Let date_var = ActiveCell.Value
ActiveCell.Offset(0, -1).Select
ElseIf ActiveCell.Value = "Split/Skill" Then
ActiveCell.Offset(0, 1).Select
Let skill_var = ActiveCell.Value
ActiveCell.Offset(0, -1).Select
Else
ActiveCell.Offset(0, -2).Select
ActiveCell.Value = skill_var
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = date_var
ActiveCell.Offset(0, 1).Select
End If
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Solved, the Date and Split/Skills have a Colon (:) at the end!
I have a worksheet named "subtotal" where I am identifying 2 line to be subtracted with 1 & 2 (line with "2" should be subtracted from line with "1"). I need to insert a row below the line with "2" in order to add the correct formula in the required cells.
I am selecting the column containing the criteria (1,2), then executing a find comand for the "2", I then use the offset property to select the cell below and insert a row. This works great, however when I apply the loop it will not stop. I have indicated that if the active cell = "2XXXXX" then exit Do. I have tried several variations and end up with the same endless loop. Can anyone tell me what i am doing wrong?
Here is my code:
Sub insert_row_1()
'
Range("D1").Select
Selection.End(xlDown).Activate
ActiveCell.Offset(1, 0).Activate
ActiveCell.FormulaR1C1 = "2XXXXX"
Range("A1").Select
Columns("D:D").Select
Selection.Find(What:="2", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
Do
If ActiveCell.Value = "2" Then
ActiveCell.Offset(1, 0).Activate
ActiveCell.EntireRow(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
ElseIf ActiveCell.Value <> "2" Then
With Columns("D")
Selection.FindNext(After:=ActiveCell).Activate
ActiveCell.Offset(1, 0).Activate
ActiveCell.EntireRow(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End With
ElseIf ActiveCell.Value = "2XXXXX" Then
Exit Do
End If
Loop
End Sub
Unfortunately, I was not able to get your loop to work, but, if I understand your goal correctly, there may be an easier way to accomplish what you need.
As I understand it, you want to:
Insert a row below every row that has a 2 in Column D
In column E of the new row, subtract the value of Column E one row above the new row from the value in column E one row above that.
The below will accomplish that:
Sub InsertAfter2()
For Each Cell In Range("D:D")
If Cell.Row <> 1 Then
If (Cells(Cell.Row - 1, 4).Value = 2) Then
Cell.EntireRow(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Cells(Cell.Row - 1, 4).Value = "Result:"
Cells(Cell.Row - 1, 5).Value = (Cells(Cell.Row - 3, 5).Value) - (Cells(Cell.Row - 2, 5).Value)
End If
End If
Next Cell
End Sub
This will take data that looks like:
And produce data that looks like:
Is there a way to automate checking a cell (in this case a year i.e. 2008 to 2013) and when a match is made execute a cut and paste, essentially sorting the data found in a range of cells (just to the right of the year) into columns? further along in the same row.
Edit
Ok Team I seem to have figured out how to do it manually, see an abbreviated portion of code
If ActiveCell = 2013 Then
ActiveCell.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=24
ActiveCell.Offset(0, 24).Range("A1").Select
ActiveSheet.Paste
End If
If ActiveCell = 2012 Then
ActiveCell.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=18
ActiveCell.Offset(0, 18).Range("A1").Select
ActiveSheet.Paste
End If
Now how to automate?
Second Edit...
Ok team I have solved the problem with the following code, thanks to the guys here in pointing me in the right direction.... great job...
Option Explicit
Sub NoTears()
Dim c As Range
Dim lastrow As Long
lastrow = Range("F" & Rows.Count).End(xlUp).Row
For Each c In Range("F1:C" & lastrow)
Select Case c.Value
'Case Is = 2009
' c.Offset(0, 2).Resize(1, 5).Cut Cells(Rows.Count, "??") _
.End(xlUp).Offset(1)
Case Is = 2010
c.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=8
c.Offset(0, 8).Range("A1").Select
ActiveSheet.Paste
Case Is = 2011
c.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=14
c.Offset(0, 14).Range("A1").Select
ActiveSheet.Paste
Case Is = 2012
c.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=20
c.Offset(0, 20).Range("A1").Select
ActiveSheet.Paste
Case Is = 2013
c.Offset(, 2).Range("A1:E1").Select
Selection.Cut
ActiveWindow.SmallScroll ToRight:=26
c.Offset(0, 26).Range("A1").Select
ActiveSheet.Paste
End Select
Next
End Sub
I would do something like this:
Not Tested
Dim Cell As Range
Dim lastRow as Long
lastRow = Range("F:F").Find("*", Range("F4"), searchdirection:=xlPrevious).Row 'this finds the last row in column F that contains data
For Each Cell In Range("F4:F" & lastrow) 'Loop through the whole table
Select Case Cell
Case 2008 'If the cell contains 2008 then...
lastRow = Range("AD:AD").Find("*", Range("AD4"),searchdirection:=xlPrevious).Row 'Find the last used row in your new table
Range(Cells(Cell.Row,8),Cells(Cell.Row,12).Copy Cells(lastRow + 1,30) 'Copy/paste the data into your new table
Case 2009
'Same concept as before
End Select
Next Cell
Not Tested
You will need to modify this to suit your needs. Specifically you'll need to update the column and offset numbers to match your data and tables correctly (I tried my best guess but I could be off).
Looking for help on a macro to take chunks of data on further rows, and place them into columns instead.
I've attached a picture to depict this. All of the chunks of data will split determined by the first column, 1 or 2 in the picture. I simply want to move chunk two up and next to 1. The only problem I've run into is that for each chunk, the number of columns is variable.
Edit: Image link incase the embedded isn't showing up: enter link description here
Would this be relatively close?
Sub macro()
Dim wav_name As String
Range("A1").Select
Do While ActiveCell.Value <> ""
ActiveCell.Offset(0, 2).Select
wav_name = ActiveCell.Value
ActiveCell.Offset(1, 0).Select
Do
If ActiveCell.Value = wav_name Then
ActiveCell.Offset(1, 0).Select
Else
Exit Do
End If
Loop
Range(ActiveCell.Offset(0, -2), ActiveCell.End(xlDown)).Select
Selection.Cut
ActiveCell.End(xlUp).Offset(0, 3).Select
ActiveSheet.Paste
Loop
Range("A1").Select
End Sub
What you have there is pretty workable with a one key exception.
Your cut selection is only grabbing the first row of data. You will need to change it to
Range(ActiveCell).Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
To handle the variable number of columns, you can capture the last column in section one by adding a varabile (i.e. LastCol) and putting the following code in your Do Loop
LastCol = Activecell.End(xlToRight).Column
Then replace the 3 in your last offset statement with your variable
Note that you can refactor the code to remove many of the select statements (includeing the ones I have mentioned above) if you need to improve the preformance of your code, but what you have written will work for you.
EDIT: Here is what your end code would look like
Sub macro()
Dim wav_name As String
Dim LastCol as Long
Range("A1").Select
Do While ActiveCell.Value <> ""
ActiveCell.Offset(0, 2).Select
wav_name = ActiveCell.Value
ActiveCell.Offset(1, 0).Select
LastCol = Activecell.End(xlToRight).Column
Do
If ActiveCell.Value = wav_name Then
ActiveCell.Offset(1, 0).Select
Else
Exit Do
End If
Loop
Range(ActiveCell.Offset(0, -2), ActiveCell.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Cut
ActiveCell.End(xlUp).Offset(0, LastCol +1).Select
ActiveSheet.Paste
Loop
Range("A1").Select
End Sub
I haven't tested this, so you may have to do some debugging... but it is now logically correct.