I'm trying to compare the dates that I choose. I mean I'm trying to take the some items which has a date earlier. So I wrote this on VBA. But I noticed that when I run this code the output was the same as input. So it tries to find the earlier items but it couldn't compare so all items are copied.
Private Sub Macro1()
a = Worksheets("SVS").Cells(Rows.Count, 1).End(xlUp).Row
For i = 3 To a
If Worksheets("SVS").Cells(i, 22).Value < CDate("28/02/2023") Then
Worksheets("SVS").Rows(i).Copy
Worksheets("Summary").Activate
b = Worksheets("Summary").Cells(Rows.Count, 1).End(xlUp).Row
Worksheets("Summary").Cells(b + 1, 1).Select
ActiveSheet.Paste
Worksheets("SVS").Activate
End If
Next i
Application.CutCopyMode = False
ThisWorkbook.Worksheets("SVS").Cells(1, 1).Select
End Sub
What is missing in the code? I wanna learn.
Check you have a valid date to compare with.
Option Explicit
Private Sub Macro1()
Dim wb As Workbook, ws As Worksheet, v
Dim lastrow As Long, i As Long, b As Long, n As Long
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Summary")
b = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
With wb.Sheets("SVS")
lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
For i = 3 To lastrow
v = .Cells(i, 22) ' col V
If IsDate(v) Then
If CDbl(v) < DateSerial(2023, 2, 28) Then
b = b + 1
.Rows(i).Copy ws.Cells(b, 1)
n = n + 1
End If
End If
Next i
End With
MsgBox n & " rows copied to Summary", vbInformation, lastrow - 2 & " rows checked"
End Sub
Append If Earlier Date
Option Explicit
Sub AppendEarlierDate()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sws As Worksheet: Set sws = wb.Sheets("SVS")
Dim srg As Range
Set srg = sws.Range("V3", sws.Cells(sws.Rows.Count, "V").End(xlUp))
Dim surg As Range, sCell As Range, sValue
For Each sCell In srg.Cells
sValue = sCell.Value
If IsDate(sValue) Then
If sValue < DateSerial(2023, 2, 28) Then
If surg Is Nothing Then
Set surg = sCell
Else
Set surg = Union(surg, sCell)
End If
End If
End If
Next sCell
If surg Is Nothing Then Exit Sub
Dim dws As Worksheet: Set dws = wb.Sheets("Summary")
If dws.FilterMode Then dws.ShowAllData
Dim dlCell As Range, dfCell As Range
Set dlCell = dws.Cells.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If dlCell Is Nothing Then
Set dfCell = dws.Range("A1")
Else
Set dfCell = dws.Cells(dlCell.Row + 1, "A")
End If
surg.EntireRow.Copy dfCell
End Sub
Related
I want to copy and paste columns from Sheet W2W to Sheet OTD Analysis when column F value doesn’t exist in OTD Analysis.
This code copied column F:AU instead of A:AU.
Sub Transfer()
Application.ScreenUpdating = False
Dim LastRow As Long
LastRow = Sheets("W2W").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Dim rng As Range
Dim foundVal As Range
For Each rng In Sheets("W2W").Range("F2:F" & LastRow)
Set foundVal = Sheets("OTD Analysis").Range("F:F").Find(rng, LookIn:=xlValues, lookat:=xlWhole)
If foundVal Is Nothing Then
rng.Columns("A:AU").Copy
Sheets("OTD Analysis").Activate
b = Sheets("OTD Analysis").Cells(Rows.Count,1).End(xlUp).Row
Sheets("OTD Analysis").Cells(b + 1, 1).Select
ActiveSheet.Paste
End If
Next rng
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
You want Columns("A:AU") in reference to the entire row.
rng.EntireRow.Columns("A:AU").Copy
Transfer New Entries
Let's assume that rng is cell F2. Then
rng.Columns("A:AU") refers to the range F2:AZ2,
rng.EntireRow refers to the range A2:XFD2,
rng.EntireRow.Columns("A:AU") refers to the range A2:AU2.
Option Explicit
Sub TransferNewEntries()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Source - to be read (copied) from
Dim sws As Worksheet: Set sws = wb.Worksheets("W2W")
Dim slRow As Long
slRow = sws.UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious).Row
Dim srg As Range: Set srg = sws.Range("A2", sws.Cells(slRow, "AU"))
Dim scrg As Range: Set scrg = sws.Range("F2", sws.Cells(slRow, "F"))
' or e.g. just 'Set scrg = srg.Columns(6)'
' Destination - to be written (pasted) to
Dim dws As Worksheet: Set dws = wb.Worksheets("OTD Analysis")
Dim dlRow As Long
dlRow = dws.UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious).Row
Dim dcrg As Range: Set dcrg = dws.Range("F2", dws.Cells(dlRow, "F"))
Dim surg As Range
Dim sCell As Range
Dim sr As Long
Dim drIndex As Variant
Dim drCount As Long
For Each sCell In scrg.Cells
sr = sr + 1 ' the n-th cell of the source column range...
' ... more importantly, the n-th row of the source range
drIndex = Application.Match(sCell.Value, dcrg, 0)
If IsError(drIndex) Then ' source value was not found
drCount = drCount + 1 ' count the rows to be copied
If surg Is Nothing Then ' combine the rows into a range...
Set surg = srg.Rows(sr)
Else
Set surg = Union(surg, srg.Rows(sr))
End If
'Else ' source value was found; do nothing
End If
Next sCell
If surg Is Nothing Then
MsgBox "No new entries (no action taken).", vbExclamation
Exit Sub
End If
Dim dfCell As Range: Set dfCell = dws.Cells(dlRow + 1, "A")
surg.Copy dfCell ' ... to be copied in one go
MsgBox "New entries copied: " & drCount, vbInformation
End Sub
Below code match the string in the specific range (this range contains Headers) if finds then copy the whole column and paste into Sheet2.
I want to add two more condition in below code that are:
Dim FindValue2 As String
Dim FindValue3 As String
FindValue2 = shSummary.Range("A2").Value
FindValue3 = shSummary.Range("B2").Value
and match in Sheet1 Column A for FindValue3 and Column F for FindValue2 after matching these 3 criteria then copy and paste the data.
Your help will be much appreciated.
Sub find()
Dim foundRng As Range
Dim FindValue As String
Dim lastRow As Long
Set shData = Worksheets("Sheet1")
Set shSummary = Worksheets("Sheet2")
FindValue = shSummary.Range("C2")
Set foundRng = shData.Range("G1:Z1").find(FindValue)
With shData
lastRow = .Cells(.Rows.Count, foundRng.Column).End(xlUp).Row
End With
shData.Rows("2:" & lastRow).Columns(foundRng.Column).Copy shSummary.Range("I3")
End Sub
Apply a filter to columns A and F then copy the visible cells.
Option Explicit
Sub Find3()
Dim wb As Workbook, wsData As Worksheet, wsSummary As Worksheet
Dim rngFound As Range, rngData As Range, rngCopy As Range
Dim FindValue As String, FilterA As String, FilterF As String
Dim lastRow As Long, c As Long
Set wb = ThisWorkbook
Set wsData = wb.Worksheets("Sheet1")
wsData.AutoFilterMode = False
Set wsSummary = wb.Worksheets("Sheet2")
With wsSummary
FindValue = .Range("B2")
FilterA = .Range("C2")
FilterF = .Range("A2")
End With
Set rngFound = wsData.Range("G1:Z1").find(FindValue)
If rngFound Is Nothing Then
MsgBox "'" & FindValue & "' not found", vbCritical
Exit Sub
End If
' column matching FindValue
c = rngFound.Column
lastRow = wsData.Cells(Rows.Count, c).End(xlUp).Row
If lastRow = 1 Then
MsgBox "No data in column " & c, vbCritical
Exit Sub
End If
' filter data on colA and F
With wsData
Set rngData = .Cells(2, c).Resize(lastRow - 1)
.UsedRange.AutoFilter
.UsedRange.AutoFilter Field:=1, Criteria1:=FilterA
.UsedRange.AutoFilter Field:=6, Criteria1:=FilterF
' data to copy
On Error Resume Next
Set rngCopy = rngData.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
' copy data
If rngCopy Is Nothing Then
MsgBox "No data to copy from column " & c, vbCritical
.AutoFilterMode = False
Exit Sub
Else
rngCopy.Copy wsSummary.Range("I3")
End If
.AutoFilterMode = False
End With
MsgBox "Done"
End Sub
Copy Data Columns to Another Worksheet
Adjust the values in the constants section.
Delete (out-comment) the Debug.Print lines when done testing.
Option Explicit
Sub ExportDataColumns()
Const sName As String = "Sheet1"
Const sHeadersAddress As String = "G1:Z1"
Const dName As String = "Sheet2"
Const dReadList As String = "A2,B2,C2"
Const dWriteList As String = "F3,A3,I3"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim wsrCount As Long: wsrCount = sws.Rows.Count
Dim shrg As Range: Set shrg = sws.Range(sHeadersAddress)
Debug.Print "Source Header Range: " & shrg.Address(0, 0)
Dim sfRow As Long: sfRow = shrg.Row + 1 ' first row below the headers
Debug.Print "Source First Row: " & sfRow
If sfRow >= wsrCount Then Exit Sub
Dim slRow As Long: slRow = GetLastRow(shrg)
Debug.Print "Source Last Row: " & slRow
If slRow < sfRow Then Exit Sub
Dim sdrg As Range
Set sdrg = shrg.Resize(slRow - sfRow + 1).Offset(1)
Debug.Print "Source Data Range: " & sdrg.Address(0, 0)
Dim dRead() As String: dRead = Split(dReadList, ",")
Dim dWrite() As String: dWrite = Split(dWriteList, ",")
Dim dUpper As Long: dUpper = UBound(dRead)
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim srg As Range
Dim drg As Range
Dim dcrg As Range
Dim srCount As Long
Dim n As Long
For n = 0 To dUpper
Debug.Print "Item " & n + 1
Dim scIndex As Variant
scIndex = Application.Match(dws.Range(dRead(n)).Value, shrg, 0)
If IsNumeric(scIndex) Then
Set srg = sdrg.Columns(scIndex)
Debug.Print "Source Range: " & srg.Address(0, 0)
srCount = srg.Rows.Count
Set drg = dws.Range(dWrite(n)).Resize(srCount)
Debug.Print "Destination Range: " & drg.Address(0, 0)
drg.Value = srg.Value
Set dcrg = drg.Resize(wsrCount - drg.Row - srCount + 1) _
.Offset(srCount)
Debug.Print "Destination Clear Range: " & dcrg.Address(0, 0)
dcrg.ClearContents
End If
Next n
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns the worksheet row number of the last non-empty row
' in the range from the first row of a range ('rg')
' through the same sized bottom-most row of the worksheet.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function GetLastRow( _
ByVal rg As Range) _
As Long
If rg Is Nothing Then Exit Function
Dim lCell As Range
With rg.Rows(1)
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , xlByRows, xlPrevious)
End With
If lCell Is Nothing Then Exit Function
GetLastRow = lCell.Row
End Function
Thought it would be as simple as, but somewhere i am wrong please help! So I am trying to find the values from rng1 in rng2 and have the output next to rng1
Thanks in advance
Sub FindValuestest()
Dim wb As Workbook, wks1, wks2 As Worksheet, rng1, rng2 As Range
Dim lRow1, lRow2 As Long
Dim v, n, r As Variant
On Error Resume Next
Set wb = ThisWorkbook
Set wks1 = wb.Worksheets("FEPR")
Set wks2 = wb.Worksheets("EQUIP")
lRow1 = wks1.Cells(wks1.Rows.Count, "B").End(xlUp).Row
lRow2 = wks2.Cells(wks2.Rows.Count, "A").End(xlUp).Row
Set rng1 = wks1.Range("B2", Cells(Rows.Count, "B").End(xlUp))
Set rng2 = wks2.Range("A1", Cells(Rows.Count, "A").End(xlUp))
lRow1 = lRow1 - 1
For v = 1 To lRow1
For n = 1 To lRow1
If n = rng2.Find(n, , xlValues, xlWhole, , , False) And rng2.Cells(n, 2) = "Commodity Tracking Bag Scanner" Then
'Debug.Print n
rng1.Cells(n, 2) = rng1.Cells(n) & " Scanner OK"
End If
Next
Next
For v = 1 To lRow1
For n = 1 To lRow1
If n = rng2.Find(n, , xlValues, xlWhole, , , False) And rng2.Cells(, 2) = "Radio" Then
rng1.Cells(n, 3) = rng1.Cells(n) & " Radio OK"
End If
Next
Next
End Sub
Match Values
Option Explicit
Sub FindValuestest()
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook
' Source
Dim sws As Worksheet: Set sws = wb.Worksheets("EQUIP")
Dim sLast As Long: sLast = sws.Cells(sws.Rows.Count, "A").End(xlUp).Row
Dim srg As Range: Set srg = sws.Range("A1:A" & sLast)
' Destination
Dim dws As Worksheet: Set dws = wb.Worksheets("FEPR")
Dim dLast As Long: dLast = dws.Cells(dws.Rows.Count, "B").End(xlUp).Row
Dim drg As Range: Set drg = dws.Range("B2:B" & dLast)
' Additional Variables
Dim cIndex As Variant
Dim i As Long
' Write
Application.ScreenUpdating = False
For i = 1 To dLast
cIndex = Application.Match(drg.Cells(i).Value, srg, 0)
If IsNumeric(cIndex) Then
If srg.Cells(cIndex).Offset(, 1) _
= "Commodity Tracking Bag Scanner" Then
drg.Cells(i).Offset(, 1).Value = drg.Cells(i) & " Scanner OK"
ElseIf srg.Cells(cIndex).Offset(, 1) = "Radio" Then
drg.Cells(i).Offset(, 2).Value = drg.Cells(i) & " Radio OK"
End If
End If
Next i
Application.ScreenUpdating = True
End Sub
I'm writing some VBA to check if a value exists in a column.
lRowStatic = Worksheets("GLMapping_Static").Cells(Rows.Count, 1).End(xlUp).Row
lRow = Worksheets("GLMapping").Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lRow
If IsError(Application.Match(Worksheets("GLMapping").Cells(i, 1).Value, Worksheets("GLMapping_Static").Range(Cells(1, 1), Cells(lRowStatic, 1)), 0)) Then
MsgBox "Its not in the range"
Else
MsgBox "Its in the range"
End If
Next i
I'm confused because this code appears to work well if the "GLMapping_Static" worksheet is currently activated. If the "GLMapping" worksheet is currently activated, then I get a 1004 error.
Any idea what is causing this? I assumed there was a cell reference that didn't include a worksheet name, but I'm not seeing one.
Thanks
Qualifying Objects
The critical part is the expression
Worksheets("GLMapping_Static").Range(Cells(1, 1), Cells(lRowStatic, 1))
where Cells are not qualified so when you choose a different worksheet than GLMapping_Static, Cells will refer to the wrong worksheet resulting in a run-time error.
The first example is illustrating how to fully qualify objects (wb-ws-rg). To simplify, one could say that .Range, .Cells, .Rows, and .Columns belong to a worksheet (object), each .Worksheets belongs to a workbook (object), and each .Workbooks belongs to the Application (object).
The other examples are just showing the benefits of using variables and some possible improvements on other accounts.
The Code
Option Explicit
Sub Humongous()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim lRowStatic As Long
lRowStatic = wb.Worksheets("GLMapping_Static") _
.Cells(wb.Worksheets("GLMapping_Static").Rows.Count, 1).End(xlUp).Row
Dim lRow As Long
lRow = wb.Worksheets("GLMapping") _
.Cells(wb.Worksheets("GLMapping").Rows.Count, 1).End(xlUp).Row
Dim i As Long
For i = 1 To lRow
If IsError(Application.Match(wb.Worksheets("GLMapping").Cells(i, 1) _
.Value, wb.Worksheets("GLMapping_Static") _
.Range(wb.Worksheets("GLMapping_Static") _
.Cells(1, 1), wb.Worksheets("GLMapping_Static") _
.Cells(lRowStatic, 1)), 0)) Then
MsgBox "Its not in the range"
Else
MsgBox "Its in the range"
End If
Next i
End Sub
Sub Sheeted()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets("GLMapping_Static")
Dim sLast As Long: sLast = sws.Cells(sws.Rows.Count, 1).End(xlUp).Row
Dim srg As Range: Set srg = sws.Range(sws.Cells(1, 1), sws.Cells(sLast, 1))
Dim dws As Worksheet: Set dws = wb.Worksheets("GLMapping")
Dim dLast As Long: dLast = dws.Cells(dws.Rows.Count, 1).End(xlUp).Row
Dim i As Long
For i = 1 To dLast
If IsError(Application.Match(dws.Cells(i, 1).Value, srg, 0)) Then
MsgBox "Its not in the range"
Else
MsgBox "Its in the range"
End If
Next i
End Sub
Sub Ranged()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim srg As Range
Dim sLast As Long
With wb.Worksheets("GLMapping_Static")
sLast = .Cells(.Rows.Count, 1).End(xlUp).Row
Set srg = .Range(.Cells(1, 1), .Cells(sLast, 1))
End With
Dim drg As Range
Dim dLast As Long
With wb.Worksheets("GLMapping")
dLast = .Cells(.Rows.Count, 1).End(xlUp).Row
Set drg = .Range(.Cells(1, 1), .Cells(dLast, 1))
End With
Dim dCell As Range
For Each dCell In drg.Cells
If IsNumeric(Application.Match(dCell, srg, 0)) Then
MsgBox "Its in the range"
Else
MsgBox "Its not in the range"
End If
Next i
End Sub
You can do something like this.
Sub TryMe()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
Set ws1 = Sheets("GLMapping_Static")
Set ws2 = Sheets("GLMapping")
wb.Activate
ws1.Select
lRowStatic = ws1.Cells(Rows.Count, 1).End(xlUp).Row
lRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lRow
If IsError(Application.Match(ws2.Cells(i, 1).Value, ws1.Range(Cells(1, 1), Cells(lRowStatic, 1)), 0)) Then
MsgBox "Its not in the range"
Else
MsgBox "Its in the range"
End If
Next i
End Sub
I have two worksheets
Source(ThisWorkbook) - contains multiple worksheets
Destination(WBD) - contains 1 worksheet
This is the process:
Compare each cell from a range in WBD (B2:B6) to all worksheet names in ThisWorkbook
If a match is found, from a range in WBD (C2:C7) and look for it in the matched worksheet
(this is where I'm having troubles)How do I get the value of the avg price cell? Do I need another loop?
*the distance between type and price is consistent.
Here's what I got so far:
For Each cel In WBD.Worksheets(1).Range("B2:B6")
For Each ws In ThisWorkbook.Worksheets
ws.Activate
If ws.Name = cel.Value Then
'find C2:C7 , offset, copy avg price, paste
Next ws
Next cel
Source - ThisWorkbook
Destination - WBD
A Lookup by Worksheets
An Application.Match Approach
Option Explicit
Sub lookupValues()
Const dFirst As Long = 2
Const sFirst As Long = 2
Dim swb As Workbook: Set swb = ThisWorkbook
'Dim WBD As Workbook: Set WBD = ThisWorkbook
Dim drg As Range
Dim dLast As Long
With WBD.Worksheets(1)
dLast = .Cells(.Rows.Count, "C").End(xlUp).Row ' because merged in 'B'
Set drg = .Cells(dFirst, "B").Resize(dLast - dFirst + 1)
End With
Dim src As Worksheet
Dim srg As Range
Dim cel As Range
Dim dMatch As Variant
Dim sMatch As Variant
Dim sLast As Long
For Each src In swb.Worksheets
sLast = src.Cells(src.Rows.Count, "C").End(xlUp).Row
Set srg = Nothing
On Error Resume Next
Set srg = src.Cells(sFirst, "B").Resize(sLast - sFirst + 1)
On Error GoTo 0
If Not srg Is Nothing Then
dMatch = Application.Match(src.Name, drg, 0)
If IsNumeric(dMatch) Then
Set cel = drg.Cells(dMatch)
Do
sMatch = Application.Match(cel.Offset(, 1).Value, srg, 0)
If IsNumeric(sMatch) Then
cel.Offset(, 2).Value _
= srg.Cells(sMatch).Offset(3, 2).Value
End If
Set cel = cel.Offset(, 1).Offset(1, -1) ' because merged
Loop Until Len(cel.Value) > 0 Or cel.Row > dLast
End If
End If
Next src
'WBD.Save
'swb.Close SaveChanges:=False
End Sub
Sub m1()
For Each cel In ThisWorkbook.Worksheets(1).Range("B2:B6")
If cel.MergeCells Then
shname = cel.MergeArea.Cells(1, 1).Value ' if cells merged, only first cell contains value
Else
shname = cel.Value
End If
For Each ws In ThisWorkbook.Worksheets
If ws.Name = shname Then
Set f = ws.Columns("B").Find(cel.Offset(0, 1).Value, lookat:=xlWhole)
If Not f Is Nothing Then ' its found
Set f = ws.Cells.Find("avg price", after:=f.Offset(0, 1))
If Not f Is Nothing Then ' its found
cel.Offset(0, 2).Value = f.Offset(0, 1).Value
End If
End If
End If
Next ws
Next cel
End Sub