Duplicate in column - excel

I'm trying to write a code to solve this little issue that I have, but can't seem to get it. I have multiple columns in an excel spreadsheet and in one of those columns, there are duplicate values. What I want to do is to remove the second/duplicate value but also take the integer value in one of the other columns and add it to the row where the first value is and after that delete that "second" row. I tried with the .RemoveDuplicates command, but it just deleted the duplicate value and shifted the whole column up, so I can't add the values as I wanted.
Here's an example
I only need the duplicates removed from one of the columns, D, here we see that row 5 and 10 are similar in that column and what I want to do, is to add the numbers from column C in row 5 and delete row t´10, so I'll end up with this
I really hope any of you can help as I'm a bit lost. Thanks!

Without code, you could use the advanced copy to copy unique values into another range, sumif to get your total and index/match to bring in the other columns. Once you get that figured out, record it as a macro and clean it up.

Resume your data with Pivot Tables.
Your inputdata looks like this:
You could resume your data using Pivot Tables, and group the data by that 4th column and sum values in 3rd column. Something like this:
This way you could create a new datarange, where you have grouped your data as you wish, excluding innecesary rows. Try it!

Work from the bottom up if you are going to delete rows. See if there is a match to the value in column D above the row you are working on. If there is a match, sum the values in column C into the matched row and remove the row you're working on.
Sub words()
Dim i As Long, m As Variant
With Worksheets("sheet1")
For i = .Cells(.Rows.Count, "D").End(xlUp).Row To 2 Step -1
m = Application.Match(.Cells(i, "D").Value, .Range("D:D").Resize(i - 1, 1), 0)
If Not IsError(m) Then
.Cells(m, "C") = .Cells(m, "C").Value2 + .Cells(i, "C").Value2
.Cells(i, "D").EntireRow.Delete
End If
Next i
End With
End Sub

Related

Ignoring specific rows with VBA Excel

I have a table in Excel like such, where the number of rows will vary each day:
Column A
Column B
Column C
Cell 1
Cell 2
Show
Cell 3
Cell 4
Show
Cell 5
Cell 6
Ignore
I am using vba to convert the range to a html table, and then email it.
I have a helper column (Column C), and I want to use a formula there to filter out certain rows.
However, that filter is not excluding hidden cells from being displayed in the html table.
I currently use this
Dim LastRow As Long LastRow = rInput.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
to find the last row of my table. This works great in projects where you want all of the table included.
I tried to change it to Find("Ignore", which gets me Object variable or With block variable not set
I tried including 'SpecialCells(xlCellTypeVisible)' in my
ConvertRangeToHTMLTable(Sheet2.Range("$A:$J").Rows("5:" & LastRow), 5)
and using a filter to hide the 'Ignore' cells. But that did not stop them showing in the emailed html table.
You probably have some sort of loop which goes over the rows right? It will not automatically skip the hidden rows just because they are filtered out, you need to specifically tell it to skip them. You can do something like:
For Each r In myRange.Rows
If Not r.EntireRow.Hidden Then
doSomething
End If
Next r
Ended up adjusting the table (and thus the range I cared about) to start at row 1 rather than row 5, and using
strBody = dsaEmailHeader & ConvertRangeToHTMLTable(Sheet2.Range("$A:$H").Rows("1:" & LastRow).SpecialCells(xlCellTypeVisible))
worked, where it didn't previously.

Excel remove duplicates based on 2 columns case-sensitive

I need to remove duplicates from an Excel worksheet based on the values in 2 columns while taking case into account.
In the example below, Rows 1 and 2 are duplicates (Row 2 should be removed). Row 3, 4, and 5 are unique.
Row
Column A
Column B
1
Abc
Def
2
Abc
Def
3
ABC
DEF
4
ABC
DeF
5
Abc
DeF
I've done this with other datasets using Data > Remove duplicates, but since it is case-insensitive, it won't work for this.
I also found this question, which is very similar, but only identifies duplicates based on 1 column.
(How to remove duplicates that are case SENSITIVE in Excel (for 100k records or more)?)
Try this code:
Sub SubRemoveDuplicates()
'Declarations.
Dim RngData As Range
Dim RngDataToBeCompared
Dim RngCell As Range
Dim RngRow As Range
'Settings.
Set RngData = Range("A1:C6")
Set RngDataToBeCompared = Range("B2:C6")
'Covering each row of the data to be compared.
For Each RngRow In RngDataToBeCompared.Rows
CP_Rerun_For:
'Covering each cell of the given row.
For Each RngCell In RngRow.Cells
'Checking if any cell is different from the one under it.
If RngCell.Value <> RngCell.Offset(1, 0).Value Then
'If said cell has been found, skip to the next row.
GoTo CP_Next_Row
End If
Next
'Checking if the range to be targeted is within RngData.
If Not Intersect(RngRow.Offset(1, 0).EntireRow, RngData) Is Nothing Then
'Deleting the row of duplicates.
Intersect(RngRow.Offset(1, 0).EntireRow, RngData).Delete (xlShiftUp)
'Rerunning this cycle for the given row in order to catch duplicates that comes in more than 2.
GoTo CP_Rerun_For
End If
CP_Next_Row:
Next
End Sub
Note: if you are going to cover an entire column with presumably many empty cells, the macro will cover (and eventually delete) all those empty cells too. The macro can be modified so it will stop when it encounters and empty row, or to dynamically determinate the appropriate range to be covered. Otherwise it might take more time than necessary.
I don't like using macros until it's last hope.
For your situation, I would suggest adding new columns, and with function
=lower(Column A), etc. get values of column A in lower case. Then I would add one more new column and do the same for Column B.
And after that, I would use Data/Remove Duplicates (converting range to Table format first). And then I would delete unnecessary columns which were added for converting everything to lowercase.
Use this frmula to manually delete. It combines two columns on one row and compares them with the column above.
=B2&C2=B1&C1
You can then edit or filter on Col D and delete.

Delete specific rows in Excel sheet

I have a table with multiple columns. I would like to delete specific rows within the table. The logic to delete is the following:
If in column B one cell contains a specific value, let's stick to "example" for this case, I would like to delete the following two rows after the row(s) which matched the criteria.
It is important to note that the criteria might appear several times within the table and that the table might have different lengths.
My idea was the following:
1. Identify all rows which contain "example" in column B
2. Store the row numbers in a variable
3. Go through the variable and create a new one which has twice the length of the first one and write the two following rows into the 2nd variable
4. Use the 2nd variable to delete the rows with that numbers.
Unfortunately, I am totally new to VBA and was not able to code it. I also tried to copy code together but I couldn't find a solution for my specific topic.
This is a very slight mod to your approach
starting from the bottom of column B, work upwards.
if we encounter "example", delete the two rows below
So if row#7 contains "example", delete row#7 and row#8
Before:
The code:
Sub RowKiller()
Dim N As Long, i As Long, t As String
t = "example"
N = Cells(Rows.Count, "B").End(xlUp).Row
For i = N To 1 Step -1
If Cells(i, "B") = t Then
Range(Cells(i + 1, "B"), Cells(i + 2, "B")).EntireRow.Delete
End If
Next i
End Sub
and after:
I think, instead, the best way to handle this is:
Loop through all of the populated rows from the last to the first. (this insures we don't pull the rug out from under us when deleting rows).
If "Example" is found in column B of that row, delete the two rows after it (we've already traversed those rows so deleting shouldn't be any big deal
Thats it.
Sub deleteRows()
Dim lastRow as Long
'get the last row
lastRow = Sheet1.Range("B" & Sheet1.Rows.Count).End(xlUp).Row
'Now work backwards
Dim i As Long
For i = lastRow to 1 Step -1 'change that 1 to whatever your first row is
If Sheet1.Cells(i, 2).value = "Example" Then
Sheet1.Rows(i + 1 & ":" & i + 2).Delete
End If
Next i
End Sub
I haven't tested that, but it looks right. You may have to tweak some things in there, but it will definitely get you in the ballpark.

VBA Code - Copying cells from one sheet to another sheet in excel depending on matching condition

I have two sheets Sheet1 and Sheet2 in excel .Sheet 1 has Columns C1,C2,C3,C4,C5.Sheet 2 has Columns C1,C2,C3.Now I have to perform 3 operations.
1.) Delete all rows in Sheet1 where values of Column 1 is not found in Column 1 of Sheet2.
2.) Replace values of C2,C3 of Sheet 2 into C2,C3 of Sheet 1 (C4,C5 remains the same) where value of C1 of Sheet 1 matches C1 of Sheet2.
3.) Append C1,C2,C3 data of Sheet 2 into Sheet 1 where values of C1 in Sheet 2 is not found in C1 of Sheet1(C4,C5 will be blank).
I am able to write the VB code for operation 1.Please help me with operation 2 and operation 3.
Sub delete_selected_rows()
Dim rng1 As Range, rng2 As Range, rngToDel As Range, c As Range
Dim lastRow As Long
With Worksheets("Sheet1")
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rng1 = .Range("A2:A" & lastRow)
End With
Set rng2 = Worksheets("Sheet2").Range("A:A")
For Each c In rng1
If IsError(Application.Match(c.Value, rng2, 0)) Then
'delete incidents which are not in process
If rngToDel Is Nothing Then
Set rngToDel = c
Else
Set rngToDel = Union(rngToDel, c)
End If
End If
Next c
If Not rngToDel Is Nothing Then rngToDel.EntireRow.Delete
End Sub
First, let my make two comments regarding your solution for step 1.
You could delete the rows on the spot if you stepped through the rows from the bottom to the top. (The row indexes only change for rows below the deleted one.)
IMO, it would be better to use rng2.Find instead of Applications.Match. This method of the range object returns the cell where a match is found and Nothing in case there is no match.
Now to step 2:
Using the notation as in your solution to step 1, you can get the row of the match in sheet2 using rng2.Find(c.Value).EntireRow. Then you can use its Cells property to get the second and third column.
Step 3:
You already know from step 1 how to find out that a row does not have a match in the other sheet. You just have to copy the values from the first three columns into the row after the last row of sheet1 for each row without a match in sheet1. (Best save the last row and then increment with each copied row.)
Above, I gave a simple solution to each step. However, if you have very large tables, this might be a bit slow. Basically, with this solution you are cycling through the rows three times, at each row, querying the worksheet for a value and searching all rows in the other table for a match.
An approach with better performance would be to load the entire ranges into two dimensional arrays using the Value property of the ranges, or better Value2. Then you can do something like a merge join to solve your three problems, i.e. you could sort both arrays by the first column using your favorite n*log(n) sorting algorithm and then step through both list in ascending order. While stepping through, you can save which rows to delete, update the appropriate rows, and append the additional rows. To enable this, you should keep track of the original rows while sorting the arrays. Finally, you would go through the rows marked for deletion from bottom to top and delete them. (You cannot delete right away since this messes up the row indexes for the rows below the deleted one.)
Yet another approach to implement your three steps, which combines ease of use and performance, is to write SQL queries against your sheets via ADODB.
Your first step would look something like this.
DELETE [sheet1$] WHERE [sheet1$].'header of first column' NOT IN (SELECT [sheet2$].'header of first column')
Step 2 would be an update statement and step 3 an insert into statement.

Loop through rows and edit them in VBA Excel2010

I am creating an interface with data entries.
These entries (1 per row) shall then be added to another entry in the same row.
Apparently it does not select the right rows and starts above row 4.
For Each row In Worksheets("A").Range("D4:D11") 'Start at row 4
.Cells(5, row) = wse.Cells(6, row) + wse.Cells(4, row)
'This is supposed to add entries from each looped row to cells in columns D and F into E.
Next row
Some of the entries even appear in columns A and B, while others appear in rows way below.
I am quite surprised that I was not able to find a solution for my problem, but maybe you can help me :)
Help is much appreciated. Thanks in advance!
In your case, row isn't what you think it is, it's a Range object.
You want something like:
For Each Rng In Worksheets("A").Range("D4:D11") 'Start at row 4
Worksheets("A").Cells(5, Rng.Row) = wse.Cells(6, Rng.Row) + wse.Cells(4, Rng.Row)
Next Rng

Resources