Compare 2 columns and remove duplicates without shifting - excel

I have this below datasheet,
COLA COLB
ABC 10
ABC 10
ABC 15
XYZ 10
XYZ 15
XYZ 15
I want to compare both the columns and if they are duplicate I want to remove blank the cell, I don't want to shift.
For example like this,
COLA COLB
ABC 10
ABC 15
XYZ 10
XYZ 15
How can I do this in excel?
Cheers!!

no vba method
Step 1 identify rows to remove using formula.
place this formula at C2 and fill down.
=IF(COUNTIFS(A$2:A2,A2,B$2:B2,B2)=1,1,"REMOVE")
Step 2 Filter for "REMOVE" only
Step 3 Select entire rows and just press DEL button, then remove filter.

Try this.
Option Explicit
Dim i, j, count, lastrow As Integer
Dim number As Long
Sub delete_duplicates()
lastrow = Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row
For i = 1 To lastrow
number = Cells(i, 2)
For j = 1 To lastrow
If number = Cells(j, 2) Then
count = count + 1
If count > 1 Then
Cells(j, 2) = ""
End If
End If
Next j
count = 0
Next i
End Sub

Related

Separating responses from multiple response survey into separate columns with sorting

I need help separating responses from a survey into different columns. Each "check all that apply" question has the responses from each respondent in one cell (e.g. 1,3,4 or 1,2 or 2,4, etc.). For example, I want to create x number of columns for all the answer choices, then code the responses 'yes' or 'no' in excel.
Q2
1,2,3
2,3,4
3,4
1,3,4
1,2,4
...
I learned how to separate the column by comma using Text to column but this is the code after I separate it:
Q2
1 2 3
2 3 4
3 4
1 3 4
1 2 4
...
What I want is each column have a similar value per row. Here is an example :
Q2
1 2 3
2 3 4
3 4
1 3 4
1 2 4
...
Is there a way to do it without moving each cell manually since there is like 100 answer? Thanks
For Office 365 Insider Channel:
=LET(ζ,0+TEXTSPLIT(A1,","),XLOOKUP(SEQUENCE(,MAX(ζ)),ζ,ζ,""))
Copy down to get similar results for the strings in A2, A3, etc.
If you didn't have access to Office 365 insider, you could do a similar thing using Split in VBA:
Sub test()
Dim LString As String
Dim LArray() As String
' Change to Long for larger ranges (question only required 100 rows)
Dim i As Integer, j As Integer, k As Integer, lastElement As Integer, LR As Integer
Const LC = 5
LR = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To LR
LString = Cells(i, 1)
LArray = Split(LString, ",")
lastElement = UBound(LArray, 1)
k = 0
For j = 1 To LC
If k > lastElement Then
Exit For
Else
If LArray(k) = j Then
Cells(i, j + 1) = LArray(k)
k = k + 1
End If
End If
Next j
Next i
End Sub
Assumes responses in each row are in ascending order and output range is initially blank.

Excel VBA - macro filling rows with numbers 1 to 3 exceeds desired range

I have stumbled upon a problem which solution seems to be very close but I still can't get it.
Code below is supposed to fill specific cells with a number between 1,2,3 so it looks like
row2 (as it starts from row2) - 1
row3 - 2
row4 - 3
row5 - 1
row6 - 2
...
Let's say that "range" variable returns 700 rows. I'd like to have above numbers in specified order only in these 700 rows however when I run the code pasted below it returns 3 times more filled cells. I'm more than certain it's somewhere in either first For or the inner one but I can't still bite it correctly :(
Sub level()
Set sf = ThisWorkbook.Sheets("formatted")
Dim range As Long
range = sf.Cells(Rows.Count, 6).End(xlUp).Row
x = 2
For i = 2 To range
For y = 1 To 3
sf.Cells(x, 9).Value = y
sf.Cells(x, 11).Value = y
x = x + 1
Next y
Next i
End Sub
Use Mod:
Sub level()
Set sf = ThisWorkbook.Sheets("formatted")
Dim rng As Long
rng = sf.Cells(Rows.Count, 6).End(xlUp).Row
Dim i As Long
For i = 2 To rng
sf.Cells(i, 9) = ((i - 2) Mod 3) + 1
Next i
End Sub

Remove any rows containing values from previous row's cell's values

I have an excel table that should contains only unique values in each row. If any of the previous cell values repeating anywhere in the other rows, the complate row should be deleted. The example table is like so
Example
Table The result
______ _____
0 1 3 0 1 3
6 4 1 5 -> 8 9 2
8 9 2
The second row should be cleared because the first row already contains 1 . But the third row should be there because it doesn't contains any duplicates from the previous rows.
I need excel formula to filter like so or vba code with multi dimensional array clearing the unwanted rows.
Try this one...
It works with all the samples I took.
Dim i, j, k, l As Long
LastRow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
LastCol = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Column
For k = 1 To LastRow
For i = k + 1 To LastRow
For j = 1 To LastCol
For l = 1 To LastCol
If (Sheets(1).Cells(i, j).Value2 <> "") And _
(Sheets(1).Cells(k, j).Value2 <> "") And _
(Sheets(1).Cells(i, j).Value2 = Sheets(1).Cells(k, l).Value2) Then
Sheets(1).Cells(i, j).EntireRow.ClearContents
End If
Next
Next
Next
Next
Range("A:A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete

Compare Values Across Different Sheets (VBA/Formulas)

I have two excel sheets, one cumulative (year-to-date) and one periodic (quarterly). I am trying to check for potential entry errors.
Simplified ytd table:
ID Q1/18 Q2/18 Q3/18 Q4/18 Q1/19 Q2/19 ...
1 6 12 20 28 10 20
2 5 11 18 26 10 20
3 5 11 18 26 10 20
Simplified quarterly table:
ID Q1/18 Q2/18 Q3/18 Q4/18 Q1/19 Q2/19 ...
1 6 6 8 8 10 10
2 5 6 7 8 10 10
3 5 6 7 8 10 10
In the above example there are no entry errors.
I am trying to create a third sheet that would look something like this
ID Q1/18 Q2/18 Q3/18 Q4/18 Q1/19 Q2/19 ...
1 T T T T T
2 T T T T T
3 T T T T T
I initially tried using a formula like this:
=IF('YTD'!C2-'YTD LC'!B2-'QTR'!B2=0,T,F)
I don't particularly like this because the formula will not apply in the first quarter. This also assumes that my data in both sheets are ordered in the same way. Whilst I believe it to be true in all cases, I would rather have something like an index-match to confirm.
I tried working on a VBA solution based on other solutions I found here but made less progress than via the formulas:
Sub Compare()
lrow = Cells (Rows.Count, 1).End(xlUp).Row
lcol = Cells(1, Columns.Count).End(xltoLeft).Column
Sheets.Add
ActiveSheet.Name = "Temp Sheet"
For i = 2 To lrow
For j = 3 To lcol
valytd = Worksheets("YTD").Cells(i,j).Value
valytd = Worksheets("YTD").Cells(i,j).Value
If valytd = valytd Then
Worksheets("Temp").Cells(i,j).Value = "T"
Else:
Worksheets("Temp").Cells(i,j).Value = "F"
Worksheets("Temp").Cells(i,j).Interior.Color Index = 40
End If
Next j
Next i
End Sub
In my opinion the easiest way is to:
Create a sheet & copy paste row 1 + Column 1 like image below (Title & IDs)
Use Sum Product to get your answers
Formula:
=IF(SUMPRODUCT((Sheet1!$B$1:$G$1=Sheet3!$B$1)*(Sheet1!$A$2:$A$4=Sheet3!A2)*(Sheet1!$B$2:$G$4))=SUMPRODUCT((Sheet2!$B$1:$G$1=Sheet3!$B$1)*(Sheet2!$A$2:$A$4=Sheet3!A2)*(Sheet2!$B$2:$G$4)),"T","F")
Formula Notes:
Keep fix the range with Quarters using double $$ -> Sheet1!$B$1:$G$1
keep fix the range with IDs using double $$ -> Sheet1!$A$2:$A$4
Keep fix the range with values -> Sheet1!$B$2:$G$
Keep fix column header -> =Sheet3!$B$1
Leave variable rows number -> =Sheet3!A2
Images:
This should do the trick, the code is all commented:
Option Explicit
Sub Compare()
Dim arrYTD As Variant, arrQuarterly As Variant, arrResult As Variant
Dim Compare As Scripting.Dictionary 'You need Microsoft Scripting Runtime for this to work
Dim i As Long, j As Integer, x As Integer
With Application
.EnableEvents = False
.Calculation = xlCalculationManual
.DisplayAlerts = False
.ScreenUpdating = False
End With
With ThisWorkbook
arrYTD = .Sheets("Name of YTD sheet").UsedRange.Value 'this will get everything on that sheet
arrQuarterly = .Sheets("Name of Quarterly sheet").UsedRange.Value 'this will get everything on that sheet
End With
ReDim arrResult(1 To UBound(arrYTD), 1 To UBound(arrYTD, 2)) 'resize the final array with the same size of YTD
Set Compare = New Scripting.Dictionary
'Here we fill the dictionary with the ID's position on the arrQuarterly array
For i = 2 To UBound(arrQuarterly) '2 because 1 is headers
If Not Compare.Exists(arrQuarterly(i, 1)) Then 'this is an error handle if you have duplicated ID's
Compare.Add arrQuarterly(i, 1), i 'now we know the position of that ID on the table
Else
'Your handle if there was a duplicated ID
End If
Next i
'Let's fill the headers on the result array
For i = 1 To UBound(arrYTD, 2)
arrResult(1, i) = arrYTD(1, i)
Next i
'Now let's compare both tables assuming the columns are the same on both tables (same position)
For i = 1 To UBound(arrYTD)
arrResult(i, 1) = arrYTD(i, 1) 'This is the ID
For j = 2 To UBound(arrYTD, 2)
x = Compare(arrYTD(i, 1)) 'this way we get the position on the quarterly array for that ID
If arrYTD(i, j) = arrQuarterly(x, j) Then 'compare if they have the same value on both sides
arrResult(i, j) = "T"
Else
arrResult(i, j) = "F"
End If
Next j
Next i
With ThisWorkbook.Sheets("Name of the result sheet") 'paste the array to it's sheet
.Range("A1", .Cells(UBound(arrResult), UBound(arrResult, 2))).Value = arrResult
End With
End Sub

how to transform three columns to a matrix using macro

I need some help converting three colums into a matrix using excel macro.
Here is an example:
From this:
A A 0
A B 23
A C 3
B A 7
B B 56
B C 33
C A 31
C B 6
C C 5
to this:
A B C
A 0 23 3
B 7 56 33
C 31 6 5
Hope you can help me.
Thanks
Not quite sure what exactly you are meaning by matrix. For the code below I assumed you were looking for a way to read the data in the first two columns as Row and Column data of the output table. Assume the input data is in the Columns 1 - 3 of "Sheet1"
Sub ConvertTableOfData()
Dim testArray(1 to 3)
Dim chkROW as Integer
Dim chkCOL as Integer
Dim chkVAL as Integer
'// index the Row and Column headers
testArray(1) = "A"
testArray(2) = "B"
testArray(3) = "C"
'// Iterate through every row in the initial dataset
For i = 1 to Worksheets("Sheet1").Cells(1, 1).End(xlDown).Row
With Worksheets("Sheet1")
'// Assign the Output Row and Column values
'// based on the array indices
For j = 1 to UBound(testArray, 1)
If .Cells(i, 1) = testArray(j) Then
chkROW = j
End If
If .Cells(i, 2) = testArray(j) Then
chkCOL = j
End If
Next j
'// store the actual value
chkVAL = .Cells(i, 3)
End With
'// output table (in Sheet2)
With Worksheets("Sheet2")
.Cells(chkROW, chkCOL) = chkVAL
End With
Next i
'// Add headers to Output table
For i = 1 to 3
With Worksheets("Sheet2")
.Cells(i + 1, 1) = testArray(i)
.Cells(i, i + 1) = testArray(i)
End With
Next i
End Sub
You can also perform this without VBA.
Assume your table of data is in the range A1:C9.
Assume the first number (0) in the 3 by 3 grid of data is cell F3, with A, B, C in the row above, and A, B, C in the column to the left.
Enter the formula in cell F3 as
=INDEX($C$1:$C$9,SUMPRODUCT(--($A$1:$A$9=$E3),--($B$1:$B$9=F$2),ROW($A$1:$A$9)))
Copy this formula to all 9 cells in the 3 by 3 grid.
This generalized to any size of data.

Resources