VBA Copy rows to a newly created sheet if multiple criteria met - vba

I would like to search a column, "C", and if the first letter of the word does not start with A or M, then I would like to copy the entire row and paste it in a newly created worksheet, with the same formatting. I would also like to copy the remaining rows into another new worksheet.
This is the code that I have used and have referred to several sources but I can't get the desired results. So far, I am only able to create the new worksheets, and copy into the worksheet "Rejected", however it copies everything and the criteria does not seem to work.
Sub sortfunds()
Worksheets.Add(Before:=Worksheets(Worksheets.Count)).Name = "Rejected"
Worksheets.Add(Before:=Worksheets(Worksheets.Count)).Name = "Accepted"
Dim wRejected As Worksheet
Dim wAccepted As Worksheet
Dim ws As Worksheet
Dim LastRow As Long
Dim i As Long
Dim j As Long
*'j is for 'Accepted' worksheet which I have not worked on yet*
Set ws = ActiveSheet
Set wRejected = ThisWorkbook.Sheets("Rejected")
Set wAccepted = ThisWorkbook.Sheets("Accepted")
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
LastRow = Range("C" & Rows.Count).End(xlUp).Row
With ws
For i = LastRow To 1 Step -1
If Left(Range("C" & LastRow), 1) <> "A" And Left(Range("C" & LastRow), 1) <> "M" Then Rows(i).Copy wRejected.Rows(wRejected.Cells(wRejected.Rows.Count, 3).End(xlUp).Row + 1)
Next i
End With
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
End Sub

You are always checking the values in the last row instead of working through each row in turn.
Change:
If Left(Range("C" & LastRow), 1) <> "A" And Left(Range("C" & LastRow), 1) <> "M"
to:
If Left(Range("C" & i), 1) <> "A" And Left(Range("C" & i), 1) <> "M"

Related

VBA: copying data into a new sheet while keeping it relative

I have two sheets in my excel file - one consists of Backend Data on clients (date, quantity, rate, etc) and the other is a Summary sheet which only lists this information if the transaction is 'OPEN'. So the Backend Data sheet has a column saying whether the transaction is OPEN and if it is, it is copied to the Summary sheet. So basically the Summary sheet has a changing number of rows. This is the code I have for that (PS. it works). This code basically copy pastes the info if the transaction is OPEN and deletes the info if the transaction is no longer OPEN and then deletes any blank rows.
My main issue is that:
I want this code to be relative such that I can insert rows above and below in the Summary Sheet w/o affecting the data.
If data exists outside the Summary Sheet, I don't want it to be erased. Basically, I want the code to work only within a specific range of cells (will a Named Range help?)
Option Explicit
Sub Main()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim Last_Row2 As Long, i As Integer
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
Last_Row2 = ws2.Range("A" & Rows.Count).End(xlUp).Row
Application.ScreenUpdating = False
With ws2
For i = 1 To Last_Row2 Step 1
If .Range("F" & i).Value = "OPEN" Then
' copy pastes the info if the transaction is OPEN
ws2.Range("B" & i, "E" & i).Copy
ws1.Range("A" & i, "D" & i).PasteSpecial
ElseIf .Range("F" & i).Value = "" Then
' deletes the info if the transaction is no longer OPEN
ws1.Range("A" & i, "D" & i).ClearContents
End If
Next i
End With
Application.ScreenUpdating = True
' deletes blank rows in Summary Sheet
Dim iCounter As Long
Worksheets("Sheet1").Range("A3:D50").Select
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
For iCounter = Selection.Rows.Count To 1 Step -1
If WorksheetFunction.CountA(Selection.Rows(iCounter)) = 0 Then
Selection.Rows(iCounter).EntireRow.Delete
End If
Next iCounter
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
ws1.Cells(1, 1).Select
End Sub

Vba find duplicates and copy if none found

I'm trying to add a vba code that looks in a column on sheet YTDFigures and sees if there is a duplicate in sheet EeeDetails. If there isn't then I want to copy the YTDFigures data and paste in a new sheet.
The code I've tried gets an error run time error 91 on the line FinName = Worksheets("EeeDetails").Range("A:A").Find(What:=SearchName, LookIn:=xlValues) I thought this would work as if a match isn't found the .Find function returns nothing.
Sub CheckMatch()
Application.ScreenUpdating = False
Dim SearchName As Range, SearchNames As Range
Dim Usdrws As Long
Dim row As Integer
Usdrws = Worksheets("YTDFigures").Range("A" & Rows.Count).End(xlUp).row
Set SearchNames = Worksheets("YTDFigures").Range("A2:A" & Usdrws)
For Each SearchName In SearchNames
row = Split(SearchName.Address, "$")(2)
FinName = Worksheets("EeeDetails").Range("A:A").Find(What:=SearchName, LookIn:=xlValues)
If FinName Is Nothing Then
Range("A" & row & ":S" & row).Copy
LastRow = Worksheets("Errors").Range("AA" & Rows.Count).End(xlUp).row + 1
Worksheets("Errors").Activate
Range("A" & LastRow).Select
Selection.PasteSpecial
Worksheets("EeeDetails").Activate
End If
Next
Application.ScreenUpdating = True
End Sub
You can place the raw data into an array, place the array on a temporary sheet, remove the duplicates, copy the data, then delete the temp sheet.
See below:
Sub CheckMatch()
Application.ScreenUpdating = False
Dim ws As Worksheet, tRows As Long
Set ws = ThisWorkbook.Worksheets(1)
Set RngA = ws.UsedRange.Columns("A")
tRows = ws.Rows(ws.Rows.Count).End(xlUp).row
Dim valA As Variant
valA = ws.Range(ws.Cells(1, 1), ws.Cells(tRows, 1)).Value
Dim tempWs As Worksheet
Set tempWs = ThisWorkbook.Worksheets.Add
tempWs.Name = "Temp1"
With tempWs
.Range(.Cells(1, 1), .Cells(tRows, 1)) = valA
With .UsedRange.Columns("A")
.RemoveDuplicates Columns:=1, Header:=xlYes
.Copy
End With
End With
' Do what you need to do with your copied data
Application.DisplayAlerts = False
tempWs.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Edit:
I just tested this with sample data of over 10k rows, and it works in less than a half a second. It's very fast.

Excel VBA to summarize last cell of certain column to 'summary' worksheet

I am trying to summarize worksheets (invoices) into "Summary-Sheet" using below code that I found Internet. I am unsuccessfully trying to modify it to select last cell in column F (total amount) which represents total of each invoice.
Total in column F has varying row number based on items sold.
Please help me in updating code to it select total amount from last cell having value in column F.
Thank you!
Sub Summary_All_Worksheets_With_Formulas()
Dim Sh As Worksheet
Dim Newsh As Worksheet
Dim myCell As Range
Dim ColNum As Integer
Dim RwNum As Long
Dim Basebook As Workbook
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
'Delete the sheet "Summary-Sheet" if it exist
Application.DisplayAlerts = False
On Error Resume Next
ThisWorkbook.Worksheets("Summary-Sheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a worksheet with the name "Summary-Sheet"
Set Basebook = ThisWorkbook
Set Newsh = Basebook.Worksheets.Add
Newsh.Name = "Summary-Sheet"
'The links to the first sheet will start in row 2
RwNum = 1
For Each Sh In Basebook.Worksheets
If Sh.Name <> Newsh.Name And Sh.Visible Then
ColNum = 1
RwNum = RwNum + 1
'Copy the sheet name in the A column
Newsh.Cells(RwNum, 1).Value = Sh.Name
For Each myCell In Sh.Range("A1,A2,C3,E3,C4,E4,C5,E5") '<--Change the range
ColNum = ColNum + 1
Newsh.Cells(RwNum, ColNum).Formula = _
"='" & Sh.Name & "'!" & myCell.Address(False, False)
Next myCell
End If
Next Sh
Newsh.UsedRange.Columns.AutoFit
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
End Sub
You do not need to loop through the cells to find your "total amount". I modified part of your code as follows:
If Sh.Name <> Newsh.Name And Sh.Visible Then
ColNum = 1
RwNum = RwNum + 1
'Copy the sheet name in the A column
Newsh.Cells(RwNum, 1).Value = Sh.Name
'put this declaration on top
Dim CellsArray() As String
Dim RangeString As String
Dim intCount As Integer
'your collection of ranges
RangeString = "A1,A2,C3,E3,C4,E4,C5,E5"
'split them into array
CellsArray = Split(RangeString, ",")
'loop through your array
For intCount = LBound(CellsArray) To UBound(CellsArray)
ColNum = ColNum + 1
Newsh.Cells(RwNum, ColNum).Formula = _
"='" & Sh.Name & "'!" & CellsArray(intCount) '<- access each range in array
Next intCount
'Find last row in the column: "Total Amount"
LastRow = Sh.Cells(Sh.Rows.Count, "F").End(xlUp).Row
'Assign that cell to myCell
Set myCell = Sh.Range("F" & LastRow)
'total
ColNum = ColNum + 1
Newsh.Cells(RwNum, ColNum).Formula = _
"='" & Sh.Name & "'!" & myCell.Address(False, False)
End If
Edit: I added the loop cycle in the middle as requested

Lock Entire Row Based On Date

I have Cell A1 with Month mentioned. I am trying to compare date in A2:last cell and wherever date > A1, I want the row to be unlocked, otherwise locked. The below code doesn't work"
Sub Lockrow()
Dim DestSh As Worksheet
Dim lastrow As Long
Dim i As Integer
Set DestSh = Sheets("Consultant & Volunteer")
With DestSh
'finds the last row with data on A column
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
'parse all rows
For i = 6 To lastrow
'if your conditions are met
If Month(.Cells(i, 26)) > Month(.Cells(1, 1)) Then
.Range("A" & i).EntireRow.Cells.Locked = True 'lock the row
End If
Next i
End With
End Sub
This can be done simply with below, but you have to be careful that Year doesn't change... Also the lastrow should be on Column Z.
Also, if the worksheet isn't Protected, there is no effect.
Option Explicit
Sub Lockrow()
Dim DestSh As Worksheet
Dim lastrow As Long
Dim i As Long ' Integer
Set DestSh = Sheets("Consultant & Volunteer")
With DestSh
'finds the last row with data on A column
lastrow = .Range("Z" & .Rows.Count).End(xlUp).Row ' <-- EDIT
'parse all rows
For i = 6 To lastrow
'if your conditions are met
.Rows(i).Locked = Not (Month(.Cells(i, "Z")) > Month(.Range("A1")))
' If Month(.Cells(i, 26)) > Month(.Cells(1, 1)) Then
' .Range("A" & i).EntireRow.Cells.Locked = True 'lock the row
' End If
Next i
.Protect UserInterfaceOnly:=True
End With
Set DestSh = Nothing
End Sub
Alternative to loop.
Dim r As Range, DestSh As Worksheet, lastrow As Long
Set DestSh = Sheets("Consultant & Volunteer")
With DestSh
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
Set r = .Range("A1:A" & lastrow)
r.EntireRow.Locked = False
r.AutoFilter 1, ">" & .Range("A1").Value2
r.SpecialCells(xlCellTypeVisible).EntireRow.Locked = True
.AutoFilterMode = False
.Protect UserInterfaceOnly:=True
End With

Excel 2010 - When I paste a copied cell, why is it in quotations and missing the line breaks?

I have a strange issue whereby when I paste data from copied cells from excel in to NotePad++, it puts the data inside quotations and misses the line breaks that are in the cell.
I am creating the copy range (although I have tried manually copying one cell) form a VBA script that also adds the data to the cells.
Here is the code incase it helps:
Sub Ready_For_Infra()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim cell As Range
Dim i As Long, lastrow As Long, lastcol As Long, g As Long
Dim str1 As String
Set ws1 = Worksheets("InfraData")
Set ws2 = Worksheets("ActionPlan")
ws1.Cells.Clear
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
With ws2
lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
lastcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
For i = lastrow To 2 Step -1
str1 = ""
For Each cell In .Range(.Cells(i, 6), .Cells(i, lastcol))
g = i - 1
If cell.Column <> 4 And cell.Column <> 5 And cell.Value <> "" And cell.Value <> "NEW ACTION" Then str1 = str1 & cell.Value & Chr(10) & "(" & cell.Offset(-g, 0).Value & ")" & Chr(10)
Next cell
ws1.Range("A" & 2 + lastrow - i).Value = ws2.Cells(i, 1).Value & Chr(10) & Chr(10) & ws2.Cells(i, 2).Value & Chr(10) & Chr(10) & str1
Next i
End With
ws1.Range("A2", "A" & lastrow).Copy
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
MsgBox "Done"
End Sub
The pasted data should look like this:
1
Testing1
Another Day of testing
(05/03/2014)
But instead looks like this:
"1Testing1AnotherDayoftesting(05/03/2014)"
However, when I paste it in to here, it appeared to include the line breaks and spaces but still include the quotations. (See Below)
"1
Testing1
Another Day of testing
(05/03/2014)
"
To get around leaving the quotes out when pasting from Excel to Notepad or others, I use the code below to put stuff in the clipboard:
Dim obj As New DataObject
obj.SetText NameofYourVariable
obj.PutInClipboard
It then pastes nicely without any double quotes.