Sub CompareAndHighlight()
Dim xRange As Range, yRange As Range
Dim xCell As Range, yCell As Range
Dim Found As Range
Dim wsX As Worksheet: Set wsX = ThisWorkbook.Sheets("Sheet1")
Dim wsY As Worksheet: Set wsY = ThisWorkbook.Sheets("Sheet2")
LR1 = wsX.Range("A" & wsX.Rows.Count).End(xlUp).Row
LR2 = wsY.Range("A" & wsY.Rows.Count).End(xlUp).Row
Set xRange = wsX.Range("A1:A" & LR1)
Set yRange = wsY.Range("A1:A" & LR2)
For Each xCell In xRange
Set Found = yRange.Find(xCell.Value)
If Found Is Nothing Then
xCell.Interior.Color = RGB(255, 0, 0)
End If
Set Found = Nothing
Next xCell
End Sub
I use above code to compare two excel sheets. i do comparison only between only column "A".
What I want to do is compare other column sequentially like compare further "B" to "b" and "c" to "c".
how can i do that by changing the code.
I like to use the sheet.cells() destination so you can easily use integers to call out both rows and columns
Sub CompareAndHighlight()
Dim xRange, yRange, xCell, yCell, Found As Range
Dim i, LR1, LR2 As Integer
Dim wsX As Worksheet: Set wsX = ThisWorkbook.Sheets("Sheet1")
Dim wsY As Worksheet: Set wsY = ThisWorkbook.Sheets("Sheet2")
For i = 1 To 3 'Set to the number of the last column you want to run the comparison
LR1 = wsX.Cells(wsX.Rows.Count, i).End(xlUp).Row
LR2 = wsY.Cells(wsY.Rows.Count, i).End(xlUp).Row
Set xRange = wsX.Range(wsX.Cells(1, i), wsX.Cells(LR1, i))
Set yRange = wsY.Range(wsY.Cells(1, i), wsY.Cells(LR2, i))
For Each xCell In xRange
Set Found = yRange.Find(xCell.Value)
If Found Is Nothing Then
xCell.Interior.Color = RGB(255, 0, 0)
End If
Set Found = Nothing
Next xCell
Next i
End Sub
Modify if needed and try:
Option Explicit
Sub test()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim rngToSearch As Range, FindPosition As Range
Dim Lastrow1 As Long, Lastrow2 As Long, ColumnToSearch As Long, i As Long, y As Long
Dim strToSearch As String
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
Set ws2 = ThisWorkbook.Worksheets("Sheet2")
Lastrow1 = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
Lastrow2 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row
For i = 1 To Lastrow1
For y = 1 To 3
strToSearch = ws1.Cells(i, y).Value
If y = 1 Then
ColumnToSearch = 1
ElseIf y = 2 Then
ColumnToSearch = 2
ElseIf y = 3 Then
ColumnToSearch = 3
End If
Set rngToSearch = ws2.Range(ws2.Cells(1, ColumnToSearch), ws2.Cells(Lastrow2, ColumnToSearch))
Set FindPosition = rngToSearch.Find(strToSearch)
If FindPosition Is Nothing Then
ws1.Cells(i, y).Interior.Color = RGB(255, 0, 0)
End If
Next y
Next i
End Sub
Related
I am trying to color the cell when condition is met and valid value for package of a product is found in another column in a different sheet.
There is a problem with the if statement.
Sub validation()
Dim lastRow_s As Long
Dim lastRow_m As Long
lastRow_s = Sheets("product").Cells(Rows.Count, "D").End(xlUp).Row
lastRow_m = Sheets("product").Cells(Rows.Count, "H").End(xlUp).Row
For i = 2 To lastRow_s
For j = 2 To lastRow_m
If Sheets("product").Cells(i,"D").Value =
Sheets("valid_package").Cells(j,"A").Value And
Sheets("product").Cells(i, "H").Value =
Sheets("valid_package").Cells(j,"B").Value Then
Sheets("product").Cells(i, "H").Value = vbGreen
End If
Next j
Next i
End Sub
I am trying to iterate over two columns to make sure that the product in column D has a valid package in column H in the product sheet. In the valid_package sheet there is a column for product and package that are valid for this products, so valid_package looks like this:
Product (this is column A from valid package)
Package (this is column B from valid package)
Product A
65x3
Product A
63x3
Product B
65x3
Product B
60x3
Product C
15
Product C
10x3
Product C
15
Product D
10
The product sheet is like this if you take only the two columns:
Product (this is column D from products)
Package (this is column H from products)
Product A
65x3
Product C
63x3
Product B
65x3
Product C
60x3
Product A
15
Product B
10x3
Product C
15
Product E
10
Product C
15
Product D
10
I want to highlight correct package in column H for sheet product or incorrect package in column H for sheet product, it doesn't matter what is colored.
I get
Expected: "line number or label or statement or end of statement.
Color Conditionally Matching Cells
Option Explicit
Sub TestAll()
ValidationQuickFix
ValidationReadable
ValidationEfficient
' Result on 1000 matches in 10000 rows of destination
' with only 10 rows of unique source values:
' Quick Fix: 6,1875
' Readable: 2,21484375
' Efficient: 0,87890625
End Sub
Sub ValidationQuickFix()
Dim t As Double: t = Timer
ThisWorkbook.Activate
Dim lastRow_s As Long
lastRow_s = Worksheets("valid_package").Cells(Rows.Count, "A").End(xlUp).Row
Dim lastRow_d As Long
lastRow_d = Worksheets("product").Cells(Rows.Count, "D").End(xlUp).Row
Dim i As Long, j As Long
For i = 2 To lastRow_d
For j = 2 To lastRow_s
If Worksheets("product").Cells(i, "D").Value = _
Worksheets("valid_package").Cells(j, "A").Value Then
If Worksheets("product").Cells(i, "H").Value = _
Worksheets("valid_package").Cells(j, "B").Value Then
Worksheets("product").Cells(i, "H").Interior.Color = vbGreen
Else
Worksheets("product").Cells(i, "H").Interior.Color = xlNone
End If
End If
Next j
Next i
Debug.Print "Quick Fix: " & Timer - t
End Sub
Sub ValidationReadable()
Dim t As Double: t = Timer
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sws As Worksheet: Set sws = wb.Worksheets("valid_package")
Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, "A").End(xlUp).Row
Dim dws As Worksheet: Set dws = wb.Worksheets("product")
Dim dlRow As Long: dlRow = dws.Cells(dws.Rows.Count, "D").End(xlUp).Row
Dim i As Long, j As Long
For i = 2 To dlRow
For j = 2 To slRow
If dws.Cells(i, "D").Value = sws.Cells(j, "A").Value Then
If dws.Cells(i, "H").Value = sws.Cells(j, "B").Value Then
dws.Cells(i, "H").Interior.Color = vbGreen
Else
dws.Cells(i, "H").Interior.Color = xlNone
End If
End If
Next j
Next i
Debug.Print "Readable: " & Timer - t
End Sub
Sub ValidationEfficient()
Dim t As Double: t = Timer
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sws As Worksheet: Set sws = wb.Worksheets("valid_package")
Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, "A").End(xlUp).Row
Dim srg1 As Range: Set srg1 = sws.Range("A2:A" & slRow)
Dim srg2 As Range: Set srg2 = sws.Range("B2:B" & slRow)
Dim dws As Worksheet: Set dws = wb.Worksheets("product")
Dim dlRow As Long: dlRow = dws.Cells(dws.Rows.Count, "D").End(xlUp).Row
Dim drg1 As Range: Set drg1 = dws.Range("D2:D" & dlRow)
Dim drg2 As Range: Set drg2 = dws.Range("H2:H" & dlRow)
Dim ddrg As Range
Dim dCell As Range
Dim sIndex As Variant
Dim dr As Long
For dr = 1 To drg1.Rows.Count
sIndex = Application.Match(drg1.Cells(dr).Value, srg1, 0)
If IsNumeric(sIndex) Then
If drg2.Cells(dr).Value = srg2.Cells(sIndex).Value Then
If ddrg Is Nothing Then
Set ddrg = drg2.Cells(dr)
Else
Set ddrg = Union(ddrg, drg2.Cells(dr))
End If
End If
End If
Next dr
If Not ddrg Is Nothing Then
drg2.Interior.Color = xlNone
ddrg.Interior.Color = vbGreen
End If
Debug.Print "Efficient: " & Timer - t
End Sub
Please, test the next code. It should be fast, using Find, placing the range to be colored in a Union range and coloring it at the code end. I hope that I correctly understood what you want and mostly what you have...
Sub validation()
Dim shP As Worksheet, shVP As Worksheet, rngColor As Range, rngA As Range, rngB As Range
Dim lastRow_P As Long, lastRow_VP As Long, cellMatch As Range, i As Long
Set shP = Sheets("product")
Set shVP = Sheets("valid_package")
lastRow_P = shP.cells(rows.Count, "D").End(xlUp).row
lastRow_VP = shVP.cells(rows.Count, "A").End(xlUp).row
Set rngA = shVP.Range("A2:A" & lastRow_VP)
For i = 2 To lastRow_P
Set cellMatch = rngA.Find(what:=shP.cells(i, "D").Value, LookIn:=xlValues, Lookat:=xlWhole)
If Not cellMatch Is Nothing Then
If cellMatch.Offset(0, 1).Value = shP.cells(i, "H").Value Then
If rngColor Is Nothing Then
Set rngColor = shP.cells(i, "H")
Else
Set rngColor = Union(rngColor, shP.cells(i, "H"))
End If
End If
End If
Next i
If Not rngColor Is Nothing Then rngColor.Interior.color = vbGreen
End Sub
I'm trying to arrange some uniformly scattered information from a spreadsheet to another. The information I'm interested in is in Sheet2 and I wish to place them in a customized manner in Sheet1.
I've tried with:
Sub ArrangeInformation()
Dim ws As Worksheet, cel As Range
Set ws = ThisWorkbook.Sheets("Sheet2")
Set tws = ThisWorkbook.Sheets("Sheet1")
For Each cel In ws.Range("A1:A" & ws.Cells(Rows.Count, 1).End(xlUp).row)
tws.Range(cel(1, 1).Address) = cel
Next cel
End Sub
The above script just replicates the same information in Sheet1 how they are in Sheet2.
Data in Sheet2:
How I like to arrange them in Sheet1:
How can I arrange those information in sheet1?
we can use some math to get the correct columns and rows:
Sub ArrangeInformation()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet2")
Dim tws As Worksheet
Set tws = ThisWorkbook.Sheets("Sheet1")
Dim i As Long
i = 0
Dim j As Long
j = 0
Dim cel As Range
For Each cel In ws.Range("A1:A" & ws.Cells(ws.Rows.Count, 1).End(xlUp).Row)
If cel <> "" Then
tws.Cells(Int(i / 4) + 1, ((j) Mod 4) + 1) = cel
i = i + 1
j = j + 1
End If
Next cel
End Sub
In the math the 4s are the number of items in each pattern
The INT will increase by 1 every four rounds and the MOD will repeat 1,2,3,4 every 4 rounds.
Just because:
this can be done with a formula:
=INDEX(Sheet2!$A:$A,INT(ROW(1:1)-1)/5+MOD((COLUMN(A:A)-1),5)+1)
where the 2 5s are the pattern and the +1 is the starting row of the data.
Put that in sheet1 A1 and copy over and down.
Maybe use Resize to transfer your data:
Sub Test()
Dim lr As Long, x As Long, y As Long
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Sheets("Sheet2")
y = 1
lr = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
For x = 1 To lr Step 5
ws2.Cells(y, 1).Resize(, 4) = Application.Transpose(ws1.Cells(x, 1).Resize(4))
y = y + 1
Next x
End Sub
And propbably faster, you could assign your range to an array:
Sub Test()
Dim arr As Variant
Dim lr As Long, x As Long, y As Long
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Sheets("Sheet2")
y = 1
lr = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
arr = ws1.Range("A1:A" & lr)
For x = LBound(arr) To UBound(arr) Step 5
ws2.Cells(y, 1).Resize(, 4) = Array(arr(x, 1), arr(x + 1, 1), arr(x + 2, 1), arr(x + 3, 1))
y = y + 1
Next x
End Sub
You'll need to manage which rows and columns you write to inside your loop. Something like:
Sub ArrangeInformation()
Dim ws As Worksheet, cel As Range
'New variables to manage rows and columns to write to
Dim writecol as integer, writeRow as integer
Set ws = ThisWorkbook.Sheets("Sheet2")
Set tws = ThisWorkbook.Sheets("Sheet1")
'Start in Row 1, Column 1
writeRow = 1
writeCol = 1
For Each cel In ws.Range("A1:A" & ws.Cells(Rows.Count, 1).End(xlUp).row)
tws.Range(writeRow, writeCol) = cel
'Next Column, or reset to 1 and iterate rows
If writeCol = 4 Then
writeCol = 1
writeRow = writeRow + 1
Else
writeCol = writeCol + 1
End If
Next cel
End Sub
I want to retrieve data in a row with the name and the header.
I really appreciate your help
NAME AUG 1, 2019 AUG 2, 2019 AUG 3, 2019
Zoldyk,Hunter 5 7
Luffy,One 1 2 3
Sub Button1_Click()
Dim rngCopy As Range, rngTemp As Range, rngTarget As Range
Dim intMultiple As Integer, i As Integer, intRow As Integer
Dim objSheet As Worksheet
Set objSheet = Sheets(1)
Dim intLastCellIndexInRow As Integer
intLastCellIndexInRow = ActiveCell.SpecialCells(xlLastCell).Column
Dim strRowValue As String
Dim j As Integer
Set rngCopy = Sheet1.Range("A2", Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp)) 'Set range including names
Set rngTarget = Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp).Offset(1, 0) 'Set target range to next available row in Sheet2
`For intRow = rngCopy.Rows.Count To 1 Step -1
Set rngTemp = rngCopy.Cells(intRow)
intMultiple = rngTemp.Offset(0, 1) 'Find how many times to copy the name
For i = 1 To intMultiple
For j = 3 To intLastCellIndexInRow
rngTarget.Value = rngTemp.Value 'Copy name
rngTarget.Next.Value = objSheet.Cells(ActiveCell.Row, j) 'Copy ID
Set rngTarget = rngTarget.Offset(1, 0) 'Move target range to next row
Next
Next
Next
End Sub
Zoldyk,hunter|5|aug 1,2019
Zoldyk,hunter| |aug 2,2019
Zoldyk,hunter|7|aug 3,2019
Luffy,One |1|aug 1,2019
Luffy,One |2|aug 2,2019
Luffy,One |3|aug 3,2019
Notes:
Didn't understand your loop,so I have changed it completely
Try and remove the extra declarations that are left in the code.
You can manipulate it to print on other sheet.
You can also use Pivot for this.
Use the Below code :
Sub Button1_Click()
Dim rngCopy As Range, rngTemp As Range, rngTarget As Range
Dim intMultiple As Integer, i As Integer, intRow As Integer
Dim objSheet As Worksheet
Set objSheet = Sheets(1)
Dim strRowValue As String
Dim j As Integer
Dim cl As Integer
Set rngCopy = Sheet1.Range("A2", Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp)) 'Set range including names
Set rngTarget = Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp).Offset(1, 0) 'Set target range to next available row in Sheet2\
cl = Sheet1.Range("A1").End(xlToRight).Column
i = rngTarget.row
For Each cel In rngCopy.Cells
For j = 2 To cl
With Sheet1
.Range("A" & i).Value = cel.Value
.Range("B" & i).Value = .Cells(cel.row, j).Value
.Range("C" & i).Value = .Cells(1, j).Value
i = i + 1
End With
Next
Next
End Sub
Demo:
I have this code but can't seems to solve the problem,
Sub IndMat()
Dim wh1 As Worksheet
Dim wh2 As Worksheet
Set wh1 = Sheets("SAS")
Set wh2 = Sheets("Sheet1")
Dim y As VariantDim x As LongDim lr1 As Long
Dim lr2 As Long
Dim rng1 As Range
Dim rng2 As Range
lr1 = wh1.Cells(Rows.Count, 5).End(xlUp).Row
lr2 = wh2.Cells(Rows.Count, 2).End(xlUp).Row
Set rng1 = wh2.Range("a2:a25")
Set rng2 = wh2.Range("b2:b25")
For i = 2 To lr1
y = application.Index(rng1, Application.Match(wh1.Cells(i, 5), rng2, 0))
Next i
End Sub
The error exposes when running
y = application.Index(rng1, Application.Match(wh1.Cells(i, 5), rng2, 0))
How do I transpose the output in the code below?
Dim lastRow As Range, rng1 As Range
Set rng1 = Worksheets(1).Range("I80:I83")
Set lastRow = ThisWorkbook.Worksheets("Sheet1").Cells(ThisWorkbook.Worksheets("Sheet1").Rows.Count, "B").End(xlUp)
lastRow.Offset(1, 0).Resize(rng1.Rows.Count, rng1.Columns.Count) = rng1.Value
It should work. Consider the following example: (can't fit to comment)
With Sheet1 '/* or what ever your sheet object is */
.Range("A1") = 1
.Range("A2") = 2
.Range("A3") = 3
.Range("C1:E1") = Application.Transpose(.Range("A1:A3"))
End With
Applying to your code:
Dim lastRow As Range, rng1 As Range
With Thisworkbook.Sheets(1)
Set rng1 = .Range("I80:I83")
Set lastrow = .Range("B" & .Rows.Count).End(xlUp)
lastrow.Offset(1, 0).Resize(rng1.Columns.Count, rng1.Rows.Count) = rng1.Value
End With