First of all thanks for your help.
I've been trying to get a dynamic list that copies values from on excel to another depending on an "IF" condition, which has worked quite fine. But I can only do it for 1 condition instead of a Range of conditions.
In excel I would usually use the COUNTIF function to see if you can find a range of values inside another range, but i am quite new to VBA and I wouldn't know how how to express this in a loop for a Range.
Example below of what has worked with one condition:
As you can see I am using "Investor" as my condition, but I need it to be for a range of values.
Thanks for your help!
LastRows = Worksheets("Data").Cells(Rows.Count, 1).End(xlUp).Row + 1
For i = 2 To LastRows
If Worksheets("Data").Range("F" & i).Value = "Investor" Then
'Instead of "Investor" I want to do something that take a list of values. Eg : If If Worksheets("Data").Range("F" & i).Value = "Range("A1:A"&LastRows) Then
Worksheets("Data").Range("A" & i).Copy
Worksheets("Email Format").Activate
LastRowEmail = Worksheets("Email Format").Cells(Rows.Count, 1).End(xlUp).Row + 1
Worksheets("Email Format").Range("A" & LastRowEmail).Select
ActiveSheet.Paste
End If
Application.Match Vs WorksheetFunction.Match
You can use one of the following Match solutions.
Option Explicit
Sub MultiCriteria1()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsD As Worksheet: Set wsD = wb.Worksheets("Data")
Dim wsE As Worksheet: Set wsE = wb.Worksheets("Email Format")
Dim LastRowD As Long: LastRowD = wsD.Cells(wsD.Rows.Count, 1).End(xlUp).Row
Dim CurrentE As Long: CurrentE = wsE.Cells(wsE.Rows.Count, 1).End(xlUp).Row
Dim i As Long
For i = 2 To LastRowD
If Not IsError(Application.Match(wsD.Range("F" & i).Value, _
wsD.Range("A1:A" & LastRowD), 0)) Then
CurrentE = CurrentE + 1
wsE.Range("A" & CurrentE).Value = wsD.Range("A" & i).Value
End If
Next i
End Sub
Sub MultiCriteria2()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsD As Worksheet: Set wsD = wb.Worksheets("Data")
Dim wsE As Worksheet: Set wsE = wb.Worksheets("Email Format")
Dim LastRowD As Long: LastRowD = wsD.Cells(wsD.Rows.Count, 1).End(xlUp).Row
Dim CurrentE As Long: CurrentE = wsE.Cells(wsE.Rows.Count, 1).End(xlUp).Row
Dim CurrVal As Long
Dim i As Long
For i = 2 To LastRowD
On Error Resume Next
CurrVal = WorksheetFunction.Match(wsD.Range("F" & i).Value, _
wsD.Range("A1:A" & LastRowD), 0)
If Err.Number = 0 Then
CurrentE = CurrentE + 1
wsE.Range("A" & CurrentE).Value = wsD.Range("A" & i).Value
End If
On Error GoTo 0
Next i
End Sub
This is just an example but should steer you in right direction.
Dim rngYourRange as Range
Set rngYourRange = Range("A1:C10")
Dim rngEachRange as Range
For each rngEachRange in rngYourRange 'or rngYourRange.Rows or rngYourRange.Columns
if rngEachRange.value = 1 then 'or whatever
'do what you need
end if
next rngEachRange
Related
This code works, but it puts the values at the bottom of Sheet2(Table2), instead of next available row in table2. Any suggestions would be appreciated. Thanks
https://drive.google.com/file/d/19fZ6GLGtVNd13I-GTgLVjnfKlzrwx05U/view?usp=sharing
Sub Macro()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet2")
Dim LastRow As Long
Dim s As Long
Dim myRow As Long
s = ws.Range("A" & Application.Rows.Count).End(xlUp).Row
LastRow = Sheets("Sheet1").Cells(Rows.Count, "I").End(xlUp).Row
For myRow = 2 To LastRow
If Sheets("Sheet1").Cells(myRow, "I") = "INACTIVE" Then
ws.Range("A" & s + 1) = Sheets("Sheet1").Cells(myRow, "A")
ws.Range("B" & s + 1) = Sheets("Sheet1").Cells(myRow, "B")
ws.Range("C" & s + 1) = Sheets("Sheet1").Cells(myRow, "C")
ws.Range("D" & s + 1) = Sheets("Sheet1").Cells(myRow, "I")
End If
Next myRow
End Sub
Copying Data From One Excel Table to Another
Dealing with Excel tables in VBA can be quite tricky. This is a simple user-friendly version. You could dive much deeper into it by using (an array of) the table headers in the loop and whatnot.
Option Explicit
Sub Macro()
Dim sws As Worksheet: Set sws = ThisWorkbook.Worksheets("Sheet1")
Dim stbl As ListObject: Set stbl = sws.ListObjects("Table1")
Dim dws As Worksheet: Set dws = ThisWorkbook.Worksheets("Sheet2")
Dim dtbl As ListObject: Set dtbl = dws.ListObjects("Table2")
Dim sCell As Range
Dim srrg As Range
Dim drrg As Range
Dim r As Long
For Each sCell In stbl.ListColumns("Status").DataBodyRange
r = r + 1
If StrComp(CStr(sCell.Value), "INACTIVE", vbTextCompare) = 0 Then
Set srrg = stbl.ListRows(r).Range
Set drrg = dtbl.ListRows.Add.Range
drrg.Cells(1).Value = srrg.Cells(1).Value
drrg.Cells(2).Value = srrg.Cells(2).Value
drrg.Cells(3).Value = srrg.Cells(3).Value
drrg.Cells(4).Value = srrg.Cells(9).Value
End If
Next sCell
End Sub
the below code should work as s variable is inside the loop.
P.S.
Updated the code to match your example.
Also, the sheet2 has table, so the last row was not detected correctly by End(xlUp).Row
The problem was also with myRow =2
Sub Macro()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet2")
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Sheet1")
Dim LastRow As Long
Dim s As Long
Dim myRow As Long
LastRow = ThisWorkbook.Sheets("Sheet1").Cells(Rows.Count, "I").End(xlUp).Row
For myRow = 1 To LastRow
s = ws.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row + 1
If ws1.Cells(myRow, "I") = "INACTIVE" Then
ws.Range("A" & s & ":C" & s) = ws1.Range("A" & myRow & ":C" & myRow).Value
ws.Range("D" & s) = "INACTIVE"
End If
Next myRow
MsgBox "OK"
End Sub
I have a task and I don't want to use vlookup because it makes the process very slow. I'm looking for a purely VBA code solution for the task.
Here I combine the values in column A and D in sheet 2. If the values in column A and B of sheet 1 are the same as that in sheet 2, then I copy the corresponding values in column G in sheet 2 to column D in sheet 1.
Application.ScreenUpdating = False
Sheets("Sending List").Select
Dim Lastrow1, Lastrow2 As Long
Dim ws1, ws2 As Worksheet
Dim tempVal, tempVal2 As String
Set ws1 = Sheets("Sending List")
Set ws2 = Sheets("P13 D-Chain Status")
Lastrow1 = ws1.Range("B" & Rows.Count).End(xlUp).Row
Lastrow2 = ws2.Range("B" & Rows.Count).End(xlUp).Row
With ws2
.Range("Q2:Q" & Lastrow2).Formula = "=A2&D2"
.Range("R2:R" & Lastrow2).Formula = "=G2"
End With
With ws1
.Range("D2:D" & Lastrow1).Formula = "=VLOOKUP(A2&B2,'P13 D-Chain Status'!Q:R,2,0)"
End With
Application.ScreenUpdating = True
End Sub
Try this one:
=INDEX('P13 D-Chain Status'!Q:R,MATCH(A2&B2,'P13 D-Chain Status'!Q:Q,0),2)
But I donĀ“t think it will work much faster.
Hope it helps
Try this. This uses array instead of formulas.
Option Explicit
Sub Sample()
Dim wsI As Worksheet
Dim wsO As Worksheet
Dim wsIAr As Variant
Dim wsOAr As Variant
Dim FinaAr As Variant
Set wsI = Sheet1 'Sheets("P13 D-Chain Status")
Set wsO = Sheet2 'Sheets("Sending List")
Dim lRowI As Long
Dim lRowO As Long
With wsI
lRowI = .Range("B" & .Rows.Count).End(xlUp).Row
wsIAr = .Range("A2:G" & lRowI).Value
End With
With wsO
lRowO = .Range("B" & .Rows.Count).End(xlUp).Row
wsOAr = .Range("A2:B" & lRowO).Value
End With
ReDim FinaAr(lRowO)
Dim searchValue As String
Dim i As Long, j As Long, k As Long
For i = LBound(wsOAr) To UBound(wsOAr)
searchValue = wsOAr(i, 1) & wsOAr(i, 2)
For j = LBound(wsIAr) To UBound(wsIAr)
If searchValue = wsIAr(j, 1) & wsIAr(j, 4) Then
FinaAr(k) = wsIAr(j, 7)
Exit For
End If
Next j
k = k + 1
Next i
wsO.Range("D2").Resize(lRowO, 1).Value = _
Application.WorksheetFunction.Transpose(FinaAr)
End Sub
Can you help me correct my VBA codes. I want to convert the values of Column U until the active row to Absolute Values meaning to remove the negative amounts.
Here is my VBA code:
Sub MakeColumnsAbsoluteValue()
Dim sht As Worksheet
Dim rngToAbs As Range
Dim LastRow As Long
Dim c As Range
Set sht = ThisWorkbook.Sheets("MJEBlackline")
LastRow = sht.Cells(sht.Rows, Count, "U").End(xlUp).Row
Set rngToAbs = Range("U5:U" & LastRow)
For Each c In rngToAbs
c.Value = Abs(c.Value)
Next c
End Sub
Problem with line LastRow = sht.Cells(sht.Rows, Count, "U").End(xlUp).Row
Use of , instead of . and not specifying the sheet reference in rngToAbs
Try:
Sub MakeColumnsAbsoluteValue()
Dim sht As Worksheet
Dim rngToAbs As Range
Dim LastRow As Long
Dim c As Range
Set sht = ThisWorkbook.Sheets("FF")
LastRow = sht.Cells(sht.Rows.count, "U").End(xlUp).row
Set rngToAbs = sht.Range("U5:U" & LastRow)
For Each c In rngToAbs
c.Value = Abs(c.Value)
Next c
End Sub
You may try:
Sub MakeColumnsAbsoluteValue()
Dim sht As Worksheet
Dim rngToAbs As Range
Dim LastRow As Long
Set sht = ThisWorkbook.Sheets("MJEBlackline")
With sht
LastRow = .Cells(.Rows.Count, "U").End(xlUp).Row
Set rngToAbs = .Range("U5:U" & LastRow)
rngToAbs.Value = .Evaluate("=abs(" & rngToAbs.Address & ")")
End With
End Sub
Or even (inspired through #GarysStudent):
Sub MakeColumnsAbsoluteValue()
Dim sht As Worksheet
Dim rngToAbs As Range
Dim LastRow As Long
Set sht = ThisWorkbook.Sheets("MJEBlackline")
With sht
LastRow = .Cells(.Rows.Count, "U").End(xlUp).Row
Set rngToAbs = .Range("U5:U" & LastRow)
rngToAbs.Replace what:="-", lookat:=xlPart, replacement:=""
End With
End Sub
This would both convert the whole range in one go. Assuming that's what you meant with:
"I want to convert the values of Column U until the active row..."
You could try:
Option Explicit
Sub MakeColumnsAbsoluteValue()
Dim sht As Worksheet
Dim rngToAbs As Range, c As Range
Dim LastRow As Long, x As Long
Dim arr() As Variant
Set sht = ThisWorkbook.Sheets("MJEBlackline")
x = 0
With sht
LastRow = .Cells(.Rows.Count, "U").End(xlUp).Row
Set rngToAbs = .Range("U5:U" & LastRow)
'Loop range and create an array including all abs values
For Each c In rngToAbs
ReDim Preserve arr(x)
arr(x) = Abs(c.Value)
x = x + 1
Next c
'Paste the values of the array at once instead of pasting values one by one
.Range("U5:U" & LastRow).Value = Application.WorksheetFunction.Transpose(arr)
End With
End Sub
I'm trying to write VBA code to cut/copy paste rows in one worksheet to a new worksheet as long as column H contains any of the values I dictate.
The current code I have works when I only set one value, but I would like the code to execute as long as any of the values I dictate are in the cell. Please advise, thanks.
Sub CutPastebyAM()
Dim sht1 As Worksheet, sht2 As Worksheet
Dim i As Long
Set sht1 = ThisWorkbook.Worksheets("Data")
Set sht2 = ThisWorkbook.Worksheets("Sheet1")
For i = 2 To sht1.Cells(sht1.Rows.Count, "H").End(xlUp).Row
If sht1.Range("H" & i).Value = "Laine Sikula" Or "Kim Gotti" Then
sht1.Range("A" & i).EntireRow.Cut sht2.Range("A" & sht2.Cells(sht2.Rows.Count, "H").End(xlUp).Row + 1)
End If
Next i
End Sub
Almost there:
EDIT - copying to different sheets
Sub CutPastebyAM()
Dim sht1 As Worksheet
Dim i As Long, v, SheetName
Set sht1 = ThisWorkbook.Worksheets("Data")
For i = 2 To sht1.Cells(sht1.Rows.Count, "H").End(xlUp).Row
Select Case sht1.Range("H" & i).Value
Case "Laine Sikula": SheetName = "Sheet1"
Case "Kim Gotti": SheetName = "Sheet2"
Case Else: SheetName = ""
End Select
If Len(SheetName) > 0 Then
With Sheets(SheetName)
sht1.Range("A" & i).EntireRow.Cut _
.Range("A" & .Cells(.Rows.Count, "H").End(xlUp).Row + 1)
End With
End If
Next i
End Sub
The following script seems like it should work, but I'm getting an "Object defined" error on the lines marked below. I can't find what's causing this at all...
Sub MailMerge()
Sheets.Add.Name = "MailMerge"
Dim MailMerge As Worksheet
Set MailMerge = Sheets("MailMerge")
Dim Rng As Range
Dim i, index, lastrow As Long
Dim Abstracts As Worksheet
Set Abstracts = Sheets("Abstracts")
lastrow = Abstracts.Cells(Rows.Count, 1).End(xlUp).row
For i = 1 To lastrow
Set Rng = Abstracts.Range("O" & i)
If WorksheetFunction.CountA(Rng) >= 1 Then
Abstracts.Range("A" & i).Resize(0, 14).Copy _
Destination:=MailMerge.Range("A" & i).Resize(0, 14)
'this is where the error is occuring
End If
Next
End Sub
Any suggestions?
Resize is not like OFFSET. It will set the size of the range to the size dictated. So you are setting the range size to 0 rows. It should be 1:
Sub MailMerge()
Sheets.Add.Name = "MailMerge"
Dim MailMerge As Worksheet
Set MailMerge = Sheets("MailMerge")
Dim Rng As Range
Dim i, index, lastrow As Long
Dim Abstracts As Worksheet
Set Abstracts = Sheets("Abstracts")
lastrow = Abstracts.Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lastrow
Set Rng = Abstracts.Range("O" & i)
If WorksheetFunction.CountA(Rng) >= 1 Then
Abstracts.Range("A" & i).Resize(1, 14).Copy _
Destination:=MailMerge.Range("A" & i).Resize(1, 14)
'this is where the error is occuring
End If
Next
End Sub