Move data to sheet2 based on formula bar cell reference - vba

I need additional info in sheet2, but I cant figure out how to add this.
I have in sheet1 a lot of data, but everything is divided into 3 sections
Section 1 of sheet1 is in columns A,B,C,D and contains -date,time,name,last
Section 2 of sheet1 is numeric data and its range is columns E to JX
Section 3 of sheet1 is in range JY:MV and it contains results(from section2)
Code that I have goes through section 3 and if value is <1 it copies that value into sheet 2 in column F, and it copies from that row section 1
Example:
If value 0.5 is found in sheet1 K32, sheet 2 looks like :
A B C D F
date time name last 0.5
Tasks that I need help
1)Is it possible to see in sheet2 in column E a sheet1 column name from where is value found?
2) Since every value in section 3 is result from 2 values from section2, can both of these values also be copies to sheet 2?
For Example
In sheet1, K50 is 0.2 and that result is from AA50(2.2) and AC50(2.0),formula used is (AA-AC)
Is it possible to copy 2.2 and 2.0 in sheet 2 also based on formula cell reference?
Summary:
Final sheet2 should look like this:
A B C D E F G H
date, time, name, last, Column name where value is found, value, data1, data2
So I need help do add columns E,G and H
Sub moveData()
Dim rng As Range
Dim iniCol As Range
Dim i
Dim v
Dim x
Dim myIndex
Dim cellVal
Dim totalCols
Dim sht1 As Worksheet
Dim sht2 As Worksheet
Dim ABC() 'var to store data from Cols A,B,C in Sheet1
Dim JYJZKA As Range 'var to store data from Cols K,L,M in Sheet1
Set sht1 = Sheets("Sheet1")
Set sht2 = Sheets("Sheet2")
Set rng = Range("JY1:KB400")
Set iniCol = Range("JY1:JY400")
totalCols = rng.Columns.Count 'Count the total of columns in the selectec range
myIndex = 0 'ini the index for rows in sheet2
For Each i In iniCol
x = -1
ABC = Range(Cells(i.Row, 1), Cells(i.Row, 4))
Set JYJZKA = Range(Cells(i.Row, 285), Cells(i.Row, 351))
'Copy range from A to C
sht2.Activate
myIndex = Application.WorksheetFunction.CountA(Columns(1)) + 1
For Each v In JYJZKA
If v.Value < 1 Then
x = x + 1
Range(Cells(myIndex + x, 6), Cells(myIndex + x, 6)).Value = v.Value
Range(Cells(myIndex + x, 1), Cells(myIndex + x, 4)).Value = ABC
End If
Next v
'Paste range equal to copy range.
'Application.CutCopyMode = False
sht1.Activate
Next i
End Sub

See if this can get your started.
I've loaded the large block of data into a variant array. This greatly speeds up the looping through individual cell comparisons.
Sub section_3_to_Sheet2()
Dim r As Long, c As Long, vVALs As Variant, vTMP As Variant
With Worksheets("Sheet1")
With .Range(.Cells(2, 1), .Cells(Rows.Count, "MV").End(xlUp))
vVALs = .Value2
End With
End With
With Worksheets("Sheet2")
For r = LBound(vVALs, 1) To UBound(vVALs, 1)
For c = 285 To UBound(vVALs, 2)
If vVALs(r, c) < 1 Then
vTMP = Array(vVALs(r, 1), vVALs(r, 2), vVALs(r, 3), vVALs(r, 4), _
"=ADDRESS(" & r + 1 & ", " & c & ", 4, 1, """ & .Name & """)", _
vVALs(r, c), vVALs(r, c - 280))
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Resize(1, 7) = vTMP
End If
Next c
Next r
End With
End Sub
Typically, blocks of data like this have column header labels so I started you off in row 2, not row1 as your sample data might indicate.
The location of the original data is supplied with an ADDRESS function.
Since E:JX is not the same number of columns as JY:MV, I was a little confused on what value to return as the second (e.g. data2) value. I opted for a simple offset.

Related

vba to search cell values in another workbook's column

I have a column "F" in workbook1 containing some values (obtained after using some excel formulas to extract and concatenate from other columns) like
blah-rd1
blah-rd5
blah-rd6
blah-rd48do I want to do this
blah-rd100
etc
I have another column "D" in workbook2 containing values like
rndm-blah-rd1_sgjgs
hjdf-blah-rd5_cnnv
sdfhjdf-blah-rd100_cfdnnv
ect
Basically "Blah-rdxx" is always present alongwith other strings in D column of workbook2
Now, what I want to do is -
If value in D column of workbook2 contains value of F column of workbook1 Then
copy corresponding value of S column of workbook2 in H column of workbook1 (5th column)
This is where I have reached so far but it doesnt copy anything probably coz there is some problem and the outer loop is not iterating, I tried following solution Nested For Next Loops: Outer loop not iterating and added n counter but still outer loop doesn't iterate -
Sub findandcopy()
Dim r As Range
Dim f As Range
Dim i As Long
Dim j As Long
Dim w1 As Worksheet
Dim w2 As Worksheet
Dim n As Integer
Set w1 = Workbooks("Book1.xlsm").Worksheets("sheet1")
Set w2 = Workbooks("Book2.xlsx").Worksheets("sheet1")
n = 0
For i = 1 To w2.Cells(Rows.Count, 1).End(xlUp).Row
For j = 1 To w1.Cells(Rows.Count, 1).End(xlUp).Row + n
If InStr(1, w2.Cells(i, 1).Value, w1.Cells(j, 3).Value) > 0 Then
w2.Cells(i, 2).Copy (w2.Cells(j, 5))
Exit For
n = n + 1
End If
Next j
Next i
End Sub
Try this
Option Explicit
Public Sub FindAndCopy()
Const F = "F"
Const D = "D"
Const H = 2
Const S = 15
Dim ws1 As Worksheet: Set ws1 = Workbooks("Book1.xlsm").Worksheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = Workbooks("Book2.xlsm").Worksheets("Sheet1")
Dim lr1 As Long: lr1 = ws1.Cells(ws1.Rows.Count, F).End(xlUp).Row
Dim lr2 As Long: lr2 = ws2.Cells(ws2.Rows.Count, D).End(xlUp).Row
Dim itm1 As Range, itm2 As Range
Application.ScreenUpdating = False
For Each itm2 In ws2.Range(ws2.Cells(1, D), ws2.Cells(lr2, D)) 'Book2
For Each itm1 In ws1.Range(ws1.Cells(1, F), ws1.Cells(lr1, F)) 'Book1
If Not IsError(itm1) And Not IsError(itm2) Then
If InStr(1, itm2.Value2, itm1.Value2) > 0 Then
itm1.Offset(, H).Formula = itm2.Offset(, S).Formula 'Book1.H = Book2.S
Exit For
End If
End If
Next
Next
Application.ScreenUpdating = True
End Sub
The original code, with explanations of functional issues:
Sub findandcopy()
Dim w1 As Worksheet, w2 As Worksheet
Dim i As Long, j As Long, n As Integer
Set w1 = Workbooks("Book1.xlsm").Worksheets("sheet1")
Set w2 = Workbooks("Book2.xlsx").Worksheets("sheet1")
n = 0
For i = 1 To w2.Cells(Rows.Count, 1).End(xlUp).Row 'for each used cell in w2.colA
For j = 1 To w1.Cells(Rows.Count, 1).End(xlUp).Row + n 'for each used cell in w1.colA
'Find the text from w1.colC (current w1 row), within cell in w2.colA (current w2 row)
If InStr(1, w2.Cells(i, 1).Value, w1.Cells(j, 3).Value) > 0 Then
'If found then copy cell in w2.colB into cell in w2.colE (current w2 row)
w2.Cells(i, 2).Copy (w2.Cells(i, 5))
Exit For 'this exits the inner For loop
n = n + 1 'this would jump over the next cell(s) in w1, but never executes
End If
Next j
Next i
End Sub
The missing indentation makes it hard to follow
There are unused variables (r, f), and w1 / w2 names can mean Workbook, or Worksheet
"Option Explicit" should be used at the top of every module
The code doesn't handle cells with errors
#N/A, #VALUE!, #REF!, #DIV/0!, #NUM!, #NAME?, or #NULL!
If you'd like a more detailed review of the code, once it's fixed you can post it on Code Review

Sum multiple column with match criteria in row data vba

I wanna ask related to excel vba.
I'm trying to consolidate data from worksheet, containing data like screenshot(1).
What i'm want to do is to consolidate data with unique row is in row H (CTP.GRP) and sum column M(Nominal) populate to another sheet in column utlization & column P(Mtm in IDR) Popullate data to another sheet column market value
My code only sum one column, anyone can help with code how to sum two column?
Sub ins_data()
Dim x As Variant
Dim y As Variant
Dim countDict As Variant
Dim a As Long
Set countDict = CreateObject("Scripting.Dictionary")
x = Sheets("Data").Range("A2").CurrentRegion
ReDim y(1 To UBound(x, 1), 1 To UBound(x, 2))
For a = 2 To UBound(x, 1)
cat1 = x(a, 8)
val1 = x(a, 16)
If countDict.exists(cat1) Then
countDict(cat1) = countDict(cat1) + val1
Else
countDict(cat1) = val1
End If
Next a
i = 1
For Each d In countDict
y(i, 2) = d
y(i, 8) = countDict(d)
i = i + 1
Next d
ThisWorkbook.Sheets("X").Range("B5").Resize(UBound(y), UBound(y, 2)).Value = y
Expected result:
Edited after OP’s further clarification
you could use this code:
Option Explicit
Sub ins_data()
Dim countDict As Object, countDict2 As Object
Set countDict = CreateObject("Scripting.Dictionary")
Set countDict2 = CreateObject("Scripting.Dictionary")
Dim x() As Variant
x = Sheets("Data").Range("A2").CurrentRegion.Value2
Dim a As Long
For a = 2 To UBound(x, 1)
countDict(x(a, 8)) = countDict(x(a, 8)) + x(a, 13)
countDict2(x(a, 8)) = countDict(x(a, 8)) + x(a, 16)
Next
With ThisWorkbook.Sheets("X").Range("B5").Resize(countDict.Count) ‘ change “B5” to the actual worksheet “X” cell you want to start writing Sheets("Data")) column H unique values from
.Value = Application.Transpose(countDict.Keys)
.Offset(, 6).Value = Application.Transpose(countDict.Items) ‘ change “6” to your actual column offset from Sheets("X") referenced column (currently, “B”) you want to start writing Sheets("Data")) column M consolidated sum from
.Offset(, 7).Value = Application.Transpose(countDict2.Items) ‘ change “7” to your actual column offset from Sheets("X") referenced column (currently, “B”) you want to start writing Sheets("Data")) column P consolidated sum from
End With
End Sub

VBA- Delete row if value is not a Duplicate and keep all rows with duplicate values

I've been working on a VBA script for a while now that goes through the values of a column and deletes all rows with values appearing only once (pretty much the inverse of deleting duplicates).
Column Headers to make explanation easier
There are numbers in the 'VTR' column that appear more than once. most appear just once.
I'd like the macro to delete all rows where the number in the 'VTR' column appears only once.(in the case of one of these numbers appearing more than once, the difference lies at the 'AFTARTKRZ' column where the value can either be (GAPNK or GAPN2) or RSLNV or RSVNK. (GAPNK or GAPN2 are the same thing)
i.e a row can appear either once with AFTARTKRZ,
(GAPNK or GAPN2)
-OR twice
either (GAPNKorGAPN2), RSLNV
or (GAPNKorGAPN2), RSVNK
OR thrice
(GAPNK or GAPN2), RSLNV, RSVNK.
I'd like to delete all those that appear only once (GAPNKorGAPN2)
Furthermore, I'd like to then add the values of the 'AFTARTKRZ' values of the duplicates to 2 extra columns at the end.
i.e, when a (GAPNK or GAPN2) appears two or threee other times, I'd like to input the 'AFTARTKRZ' column value in the 2 last columns at the end.
Something like this should be the final result
VTR|AFTARTKRZ | Add1 | Add2
11 |GAPNK |RSLNV | RSVNK| - VTR appeared thrice
12 |GAPN2 |RSLNV | | - Appeared twice as (GAPNKorGAPN2), RSLNV
13 |GAPNK |RSVNK | | - Appeared twice as (GAPNKorGAPN2), RSVNK
14 |GAPN2 | |
15 |GAPNK | |
16 |GAPN2 | |
The relevant part begins at '~~~~ Work on A
Sub Test()
Dim wb As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
Dim RowsToTestC As Range, Delrange As Range
Dim i As Long, Lrow As Long, Lop As Long
Set ws1 = ThisWorkbook.Worksheets(1)
ThisWorkbook.ActiveSheet.Name = "A"
ws1.Copy ThisWorkbook.Sheets(Sheets.Count)
ThisWorkbook.ActiveSheet.Name = "B"
Set ws2 = ThisWorkbook.Worksheets(2)
ws1.Copy ThisWorkbook.Sheets(Sheets.Count)
ThisWorkbook.ActiveSheet.Name = "C"
Set ws2 = ThisWorkbook.Worksheets(3)
'~~~~ Work on C
Worksheets("C").Activate
With ActiveSheet
ActiveSheet.Range("A:AQ").RemoveDuplicates Columns:=6, Header:=xlNo
End With
Worksheets("C").Activate
Application.ScreenUpdating = False
'~~> Delete all but RSV
For Lrow = Range("D" & Rows.Count).End(xlUp).Row To 2 Step -1
If Range("D" & Lrow).Value = "GAPNK" Or Range("D" & Lrow) = "GAPN2" Then
Rows(Lrow).EntireRow.Delete
End If
Next Lrow
'~~~~ Work on B
Worksheets("B").Activate
With ActiveSheet
ActiveSheet.Range("A:AQ").RemoveDuplicates Columns:=6, Header:=xlNo
End With
Worksheets("B").Activate
Application.ScreenUpdating = False
'~~> Delete all but GAP
For Lrow = Range("D" & Rows.Count).End(xlUp).Row To 2 Step -1
If Range("D" & Lrow).Value = "RSVNK" Or Range("D" & Lrow) = "RSLNV" Then
Rows(Lrow).EntireRow.Delete
End If
Next Lrow
'~~~~ Work on A
Worksheets("A").Activate
Range("AR1").Select
ActiveCell.FormulaR1C1 = "RSVNK"
Range("AS1").Select
ActiveCell.FormulaR1C1 = "RSLNV"
With ws1
'~~> Get the last row which has data in Col A
Lop = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Loop through the rows
For i = 2 To Lop
'~~> For for multiple occurances
If .Cells(i, 6).Value <> "" And .Cells(i, 4).Value <> "" Then
If Application.WorksheetFunction.CountIf(.Columns(6), .Cells(i, 6)) = 1 And _
Application.WorksheetFunction.CountIf(.Columns(4), .Cells(i, 4)) = 1 Then
'~~> Store thee row in a temp range
If Delrange Is Nothing Then
Set Delrange = .Rows(i)
Else
Set Delrange = Union(Delrange, .Rows(i))
End If
End If
End If
Next
End With
End Sub
The logic of your code isn't valid.
The condition If Application.WorksheetFunction.CountIf(.Columns(4), .Cells(i, 4)) = 1 will always be False because this is the column containing your AFTARTKRZ keys. I don't know how many rows of data you have, but even in the 10 row sample you gave us the result is always greater than 1.
I do think you're making this unnecessarily complicated. Aren't you just trying to populate two lists: one of GAPs and the other of RSVs? You then want to create a third list where the GAP entries have corresponding RSV entries?
That could be done in a couple of short routines. You could do away with all of your sheet copying and row deleting and simply write your three lists directly to your sheets.
The code below shows you how this could be done. I've created 4 sheets, so you may need to add another to your Workbook: Sheet1 is your summary list (A), Sheet2 is your GAP list (B), Sheet3 is your RSV list (C), and Sheet4 holds the raw data.
Hopefully this code can get you started:
Option Explicit
Public Sub RunMe()
Const AFTARTKRZ_COL As Long = 4
Const VTR_COL As Long = 6
Dim data As Variant
Dim GAPs As Collection
Dim RSVs As Collection
Dim multis As Collection
Dim vtrKey As String
Dim multi(0 To 1) As Long
Dim i As Long, r As Long, c As Long
Dim v As Variant
Dim countRSV As Long
Dim output() As Variant
'Name your sheets.
'If you have fewer than 3 sheets or
'sheets already names A, B, C then this
'will throw an error.
Sheet1.Name = "A"
Sheet2.Name = "B"
Sheet3.Name = "C"
'Initialise the 3 collections
Set GAPs = New Collection
Set RSVs = New Collection
Set multis = New Collection
'Read the data - I've put my dummy data on Sheet4
data = Sheet4.UsedRange.Value2
'Iterate rows and place row in relevant collection
For r = 1 To UBound(data, 1)
vtrKey = CStr(data(r, VTR_COL))
On Error Resume Next 'removes duplicate entries
Select Case data(r, AFTARTKRZ_COL)
Case Is = "GAPNK", "GAPN2": GAPs.Add r, vtrKey
Case Is = "RSLNV": RSVs.Add r, vtrKey & "|RSLNV"
Case Is = "RSVNK": RSVs.Add r, vtrKey & "|RSVNK"
End Select
On Error GoTo 0
Next
'Check if each GAP also has RSVs
For Each v In GAPs
vtrKey = CStr(data(v, VTR_COL))
countRSV = 0
If Exists(RSVs, vtrKey & "|RSLNV") Then countRSV = countRSV + 1
If Exists(RSVs, vtrKey & "|RSVNK") Then countRSV = countRSV + 2
If countRSV > 0 Then
multi(0) = CLng(v)
multi(1) = countRSV
multis.Add multi, vtrKey
End If
Next
'Write your outputs
'Sheet C
ReDim output(1 To RSVs.Count + 1, 1 To UBound(data, 2))
For c = 1 To UBound(data, 2)
output(1, c) = data(1, c)
Next
i = 2
For Each v In RSVs
For c = 1 To UBound(data, 2)
output(i, c) = data(v, c)
Next
i = i + 1
Next
With Sheet3
.Cells.Clear
.Range("A1").Resize(UBound(output, 1), UBound(output, 2)).Value = output
.Columns.AutoFit
End With
'Sheet B
ReDim output(1 To GAPs.Count + 1, 1 To UBound(data, 2))
For c = 1 To UBound(data, 2)
output(1, c) = data(1, c)
Next
i = 2
For Each v In GAPs
For c = 1 To UBound(data, 2)
output(i, c) = data(v, c)
Next
i = i + 1
Next
With Sheet2
.Cells.Clear
.Range("A1").Resize(UBound(output, 1), UBound(output, 2)).Value = output
.Columns.AutoFit
End With
'Sheet A
ReDim output(1 To multis.Count + 1, 1 To 5)
output(1, 1) = "VTR"
output(1, 2) = "AFTARTKRZ"
output(1, 3) = "Add1"
output(1, 4) = "Add2"
i = 2
For Each v In multis
r = v(0)
output(i, 1) = data(r, VTR_COL)
output(i, 2) = data(r, AFTARTKRZ_COL)
output(i, 2) = data(r, AFTARTKRZ_COL)
Select Case v(1)
Case 1
output(i, 3) = "RSLNV"
output(i, 5) = "Appeared twice as (GAPNK or GAPN2), RSLNV"
Case 2
output(i, 3) = "RSVNK"
output(i, 5) = "Appeared twice as (GAPNK or GAPN2), RSVNK"
Case 3
output(i, 3) = "RSLNV"
output(i, 4) = "RSVNK"
output(i, 5) = "VTR appeared thrice"
End Select
i = i + 1
Next
With Sheet1
.Cells.Clear
.Range("A1").Resize(UBound(output, 1), UBound(output, 2)).Value = output
.Columns.AutoFit
End With
End Sub
Private Function Exists(col As Collection, key As String) As Boolean
Dim v As Variant
On Error Resume Next
v = col(key)
On Error GoTo 0
Exists = Not IsEmpty(v)
End Function

How to set this dynamic range in vba?

Here are 3 worksheets.
Case:
I want to sum the days for each person. The result is displayed on worksheet-report.
The days information is stored in worksheet-day. The day is not fixed. The range of the days is dynamic which should be according to
row: that person row in worksheet-day
column :Worksheets("button").Cells(1, 2 ) to Worksheets("button").Cells(2, 2)
For example :
Worksheets("button").Cells(1, 2 ) 'store 3
Worksheets("button").Cells(2, 2 ) 'store 5
In column A of worksheet-report ,the sum of day of Peter ,Tom ,Mary should be calculated .The result should be displayed on column B correspondingly .
Then ,their sum of the days should be searched in worksheet-day and add up the total within the range (D:F 'because the value in worksheet("button"))
The result should be :
Peter: 2
Tom: 3
Mary: 3
Lastly,this result displayed on worksheet-report column B correspondingly .
Here is my code:
Sub gg()
row = Worksheets("report").Range("A" & Rows.Count).End(xlUp).row
Row2 = Worksheets("day").Range("A" & Rows.Count).End(xlUp).row
Dim rng As Range 'the range for sum
Dim row999 As Integer 'store the selected row index
For k = 2 To Row2 'check and store appropriate row
If Worksheets("report").Cells(1, k).Value = Worksheets("day").Cells(1, k).Value Then
row999 = ActiveCell.row
End If
Next k
rng = Range(Cells(Worksheets("button").Cells(1, 2), row999), Cells(Worksheets("button").Cells(2, 2), row999))
For j = 2 To row 'do the sum
Worksheets("report").Cells(2, i) = Application.WorksheetFunction.Sum(rng)
Next j
End Sub
I guess the rng is inaccurate here.
rng = Range(Cells(Worksheets("button").Cells(1, 2), row999), Cells(Worksheets("button").Cells(2, 2), row999))
The problem that you are having is that the names do not match. Tom is uppercase on Report and lower case on day. Mary has an extra space on the Day worksheet "mary ".
Try to use shorter variable names when possible so that you can read each line of code without having to scan back and forth with your eyes.
Sub ProcessDays()
Dim day1 As Integer, day2 As Integer
Dim i As Integer, j As Integer
Dim name1 As String, name2 As String
With Worksheets("button")
day1 = .Cells(1, 2)
day2 = .Cells(2, 2)
End With
With Worksheets("day")
For i = 2 To Worksheets("report").Range("A" & Rows.Count).End(xlUp).Row
For j = 2 To .Range("A" & Rows.Count).End(xlUp).Row
name1 = UCase(Trim(Worksheets("report").Cells(i, 1)))
name2 = UCase(Trim(.Cells(j, 1)))
If name1 = name2 Then
Set rng = .Range(.Cells(j, day1), .Cells(j, day2))
Worksheets("report").Cells(i, 2) = WorksheetFunction.Sum(rng)
End If
Next
Next
End With
End Sub
The first parameter passed to Cells is the row, and the second parameter is the column.
You should also qualify which worksheet the range is on.
So your line saying:
rng = Range(Cells(Worksheets("button").Cells(1, 2), row999), Cells(Worksheets("button").Cells(2, 2), row999))
should say
rng = Worksheets("day").Range(Cells(row999, Worksheets("button").Cells(1, 2)), _
Cells(row999, Worksheets("button").Cells(2, 2)))
However, you have a lot of other errors in your code. I believe what you want is:
Sub gg()
Dim lastrowReport As Long
Dim lastrowDay As Long
Dim rowReport As Long
Dim rowDay As Long
lastrowReport = Worksheets("report").Range("A" & Rows.Count).End(xlUp).row
lastrowDay = Worksheets("day").Range("A" & Rows.Count).End(xlUp).row
Dim rng As Range 'the range for sum
For rowReport = 2 To lastrowReport ' loop through each of the rows on the report
For rowDay = 2 To lastrowDay ' find the entry for this person on the days sheet
If Worksheets("report").Cells(rowReport, 1).Value = Worksheets("day").Cells(rowDay, 1).Value Then
set rng = Worksheets("day").Range(Worksheets("day").Cells(rowDay, Worksheets("button").Cells(1, 2)), _
Worksheets("day").Cells(rowDay, Worksheets("button").Cells(2, 2)))
Worksheets("report").Cells(rowReport, 2) = Application.WorksheetFunction.Sum(rng)
Exit For
End If
Next
Next
End Sub

Give unique reference to each unique value

I have an excel table that has some duplicates and we currently have a count of these however I want to populate a unique number for each duplicate. e.g.
Number Count Sequence
1 2 1
1 2 1
2 3 2
2 3 2
2 3 2
3 4 3
3 4 3
3 4 3
3 4 3
4 2 4
4 2 4
5 5 5
5 5 5
5 5 5
5 5 5
5 5 5
I was playing with the following IF statement but I want it to check through the whole range and check if it has any in a wrong order but still the same.
=IF(IF(IF(A2=A1,TRUE,FALSE)=FALSE,1,0)>=0,IF(IF(A2=A1,TRUE,FALSE)=FALSE,1,0)+D1,IF(IF(A2=A1,TRUE,FALSE)=FALSE,1,0))
is this possible?
It will add the unique ref into the a Column which is 3 columns up from what every you set col equal to.
It also requires that col + 3 to be blank, this will make the checking easier.
Sub SomeSub()
Dim Array1 As Variant
Dim Array2 As Variant
With ActiveSheet.UsedRange
LastRow = .Rows(.Rows.Count).Row
End With
'Setting up the array for assigning each row value to the array
ReDim Array1((LastRow + 1))
ReDim Array2((LastRow + 1))
'Here youwill set what column is the "Number" Column
col = 1
'Assigning the row data into the arrays
'Starting at 2 to skip the title row
For r = 2 To LastRow
'Values in Column 1 go to Array1
Array1(r) = Cells(r, col)
'Values in Column 2 go to Array2
Array2(r) = Cells(r, col + 1)
Next r
'Setting unquie ref to 1
Seq = 1
'Running through each row of data
For i = 2 To LastRow
'col + 3 refers to a column on beyond the Sequence colum
'If the column is blank then that row has not been checked yet
If Cells(i, col + 3) = "" Then
'Assign the Uniqui ref to the row
Cells(i, col + 3).Value = Seq
'Running through the rest of the rows to check if they are like the current row
For n = i + 1 To (LastRow)
'If cell is blank then the row has been checked
If Cells(n, col + 3) = "" Then
'Array(i) is the current row
'Array(n) are the leading rows after row i
'If the current row is the same as any leading row then the uniquie ref = seq
If Array1(i) = Array1(n) And Array2(i) = Array2(n) Then Cells(n, col + 3).Value = Seq
'Else a value has been added
Else
'Do nothing
End If
Next n
'Increment the seq
Seq = Seq + 1
'Ending the If Cells(i, col + 3) = "" Then
End If
Next i
End Sub
You can first loop through the column and get the unique items using collections.
This part of the code:
On Error Resume Next
For Each Cell In Rng.Cells
cUnique.Add Cell.Value, CStr(Cell.Value)
Next Cell
Will only get the unique items, as a collection of items cannot have duplicates.
Use this to Number the duplicates.Change the sheet name as required.
Sub NumberDupes()
Dim cUnique As Collection
Dim Rng As Range
Dim Cell As Range
Dim sh As Worksheet
Dim vNum As Variant
Dim LstRw As Long
Dim c As Long, clr As Long, x, r As Range
Set sh = Sheets("Sheet2")
With sh
.Columns("B:B").ClearContents
LstRw = .Cells(.Rows.Count, "A").End(xlUp).Row
Set Rng = .Range(.Cells(2, 1), .Cells(LstRw, 1))
Set cUnique = New Collection
Rng.Interior.ColorIndex = xlNone
clr = 1
On Error Resume Next
For Each Cell In Rng.Cells
cUnique.Add Cell.Value, CStr(Cell.Value)
Next Cell
On Error GoTo 0
For Each vNum In cUnique
For c = 1 To LstRw
Set r = .Cells(c, 1)
x = Application.WorksheetFunction.CountIf(.Range(.Cells(1, 1), .Cells(c, 1)), r)
If r = vNum Then
If x > 1 Then
r.Offset(, 1) = clr
End If
End If
Next c
clr = clr + 1
Next vNum
End With
End Sub
Use this to Color the Duplicates, this will work on a small scale, depends on how many unique items there are, it's cool example though. Edited code from my answer here.
Sub ColorDupes()
Dim cUnique As Collection
Dim Rng As Range
Dim Cell As Range
Dim sh As Worksheet
Dim vNum As Variant
Dim LstRw As Long
Dim c As Long, clr As Long, x, r As Range
Set sh = Sheets("Sheet2")
With sh
LstRw = .Cells(.Rows.Count, "A").End(xlUp).Row
Set Rng = .Range(.Cells(2, 1), .Cells(LstRw, 1))
Set cUnique = New Collection
Rng.Interior.ColorIndex = xlNone
clr = 3
On Error Resume Next
For Each Cell In Rng.Cells
cUnique.Add Cell.Value, CStr(Cell.Value)
Next Cell
On Error GoTo 0
For Each vNum In cUnique
For c = 1 To LstRw
Set r = .Cells(c, 1)
x = Application.WorksheetFunction.CountIf(.Range(.Cells(1, 1), .Cells(c, 1)), r)
If r = vNum Then
If x > 1 Then
r.Interior.ColorIndex = clr
End If
End If
Next c
clr = clr + 1
Next vNum
End With
End Sub
In C1 just 1 and in C2:
=MIN(IF(($A$2:A2=A3)*($B$2:B2=B3),$D$2:D2,MAX($D$2:D2)+1))
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
and simply autofill down from C3
hmm... i think i got it wrong :/
if only looking at Column A then this should be enough:
=MIN(IF($A$2:A2=A3,$D$2:D2,MAX($D$2:D2)+1))
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
looking at your formula it can be shortened:
=IF(IF(IF(A2=A1,TRUE,FALSE)=FALSE,1,0)>=0,IF(IF(A2=A1,TRUE,FALSE)=FALSE,1,0)+D1,IF(IF(A2=A1,TRUE,FALSE)=FALSE,1,0))
'IF(A2=A1,TRUE,FALSE)=FALSE ==>> A1<>A2
=IF(IF(A1<>A2,1,0)>=0,IF(A1<>A2,1,0)+D1,IF(A1<>A2,1,0))
'IF(A1<>A2,1,0)>=0 ==>> TRUE
=IF(TRUE,IF(A1<>A2,1,0)+D1,IF(A1<>A2,1,0))
'IF(TRUE => allways true
=IF(A1<>A2,1,0)+D1
'last skip
=D1+(A1<>A2)