VBA: Copy entire row with the condition TRUE to TempSheet2 - vba

Can someone help me with an VBA script that copy entire rows with the condition TRUE from column U in TempSheet over to TempSheet2.

use something like this:
Sub test()
Dim i&, z&, oCell As Range
Application.ScreenUpdating = 0
z = 1: i = Sheets("TempSheet").Cells(Rows.Count, "U").End(xlUp).Row
For Each oCell In Sheets("TempSheet").Range("U1:U" & i)
If oCell.Value = True Then
oCell.EntireRow.Copy Sheets("TempSheet2").Rows(z)
z = z + 1
End If
Next
Application.ScreenUpdating = 1
End Sub

This macro checks each row for the value "True" in the U column.
The columns with true value in column U as then copied to the other sheet.
Option Explicit
Sub CopyRow()
Dim Row As Integer
Dim sRow As String
Dim i As Long
Application.ScreenUpdating = False
i = 1 'To ensure each time the macro is run it starts at row 1
For i = 1 To 1048576 'for each row in the sheet
If Range("U" & i).Value = True Then 'If the U value is true then copy it
Row = i
sRow = CStr(Row) 'convert row number to string
Rows(sRow & ":" & sRow).Select
Selection.Copy
Sheets("Sheet2").Select
Rows(sRow & ":" & sRow).Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Application.CutCopyMode = False
End If
Next i
Range("A1").Select
Application.ScreenUpdating = True
End Sub
I am uncertain as to how you want the macro triggered but a worksheet change may suit.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
' The variable KeyCells contains the cells that will
' trigger the macro if they are changed
Set KeyCells = Range("U:U")
Call CopyRow
End If
End Sub
Note: Worksheet_Change goes in the code for sheet1 and the macro goes in a module

Related

Copy cell above if 2 criteria from separate columns are met

Looking for VBA to copy cell above (in column E) if cell in E is empty and AJ is anything other than empty. Currently this is copying the cell above but is not taking into account the AJ column. Fairly new to VBA and not sure where I am going wrong. Any input is greatly appreciated.
Sub CopyFIN() 'copies FIN from account above if E is empty and AJ is anything other than empty
Dim lr As Long
Dim rcell As Range
Dim col As Range
Application.ScreenUpdating = False
lr = Cells(Rows.Count, 6).End(xlUp).Row
Set col = Range("E12:E" & lr)
Set col2 = Range("AJ12:AJ" & lr)
For Each rcell In col2
If rcell.Value <> "" Then
End If
Next
For Each rcell In col
If rcell.Value = "" Then
rcell.Offset(-1, 0).Copy rcell
End If
Next
Application.ScreenUpdating = True
End Sub
Try this. Your first loop wasn't doing anything and your second was only checking column E.
Sub CopyFIN() 'copies FIN from account above if E is empty and AJ is anything other than empty
Dim lr As Long
Dim rcell As Range
Dim col As Range
Application.ScreenUpdating = False
lr = Cells(Rows.Count, 6).End(xlUp).Row
Set col = Range("E12:E" & lr)
For Each rcell In col
If Len(rcell) = 0 And Len(Cells(rcell.Row, "AJ")) > 0 Then
rcell.Offset(-1, 0).Copy rcell
End If
Next
Application.ScreenUpdating = True
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.

Need to Delete data correctly in column F if met empty cells on G

My code is limited to work fine only with first empty cell found, the problem starts is that if finds the next two or more empty cells because it loops a bit (I can handle with that), but if it finds empty cells and next finds cells with data again, it totally fails.
Private Sub Worksheet_Change(ByVal Target As Range)
firstRow = 7
lastrow = Sheets("Datos del Proyecto").Range("F" & Rows.Count).End(xlUp).row
i = firstRow
Do Until i > lastrow
If Sheets("Datos del Proyecto").Range("G" & i).Value Like "" Then
Sheets("Datos del Proyecto").Range("F" & i).ClearContents
End If
i = i + 1
Loop
Screenshot:
Since the code is placed inside "Datos del Proyecto" sheet, in Worksheet_Change event, there is no need to reference it in the code all the time, as it is the default sheet.
Using Application.EnableEvents = False will prevent the code to exit and re-enter the Sub as you ClearContents each iteration inside the For loop.
Code
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim LastRow As Long, i As Long
' disable worksheet events >> will prevent the endless loop you got
Application.EnableEvents = False
' find last row in Column F
LastRow = Cells(Rows.Count, "F").End(xlUp).Row
' loop through all rows from row 7 until last row
For i = 7 To LastRow
If IsEmpty(Range("G" & i)) Or Range("G" & i).Value = "" Then
Range("F" & i).ClearContents
End If
Next i
Application.EnableEvents = True
End Sub
You can ass an option to your Sub , to make it run only if the change occurred in certain Range by adding these 3 lines in the beginning of the code:
Dim WatchRange As Range
' check only if cells changed are in Column G
Set WatchRange = Columns("G:G")
If Not Intersect(Target, WatchRange) Is Nothing Then
#Shai_Rado answer:
'Option Explicit <-- I needed to disable to make it work.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim LastRow As Long, i As Long
'Dim WatchRange As Range <-- I needed to disable to make it work.
'Set WatchRange = Columns("G:G") <-- I needed to disable to make it work.
'If Not Intersect(Target, WatchRange) Is Nothing Then <-- I needed to disable to make it work.
Application.EnableEvents = False
LastRow = Cells(Rows.Count, "F").End(xlUp).row
For i = 7 To LastRow
If IsEmpty(Range("G" & i)) Or Range("G" & i).Value = "" Then
Range("F" & i).ClearContents
End If
Next i
Application.EnableEvents = True
End Sub
The one I proposed with the help lines:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Long
Application.EnableEvents = False
firstRow = 7
lastrow = Sheets("Datos del Proyecto").Range("F" & Rows.Count).End(xlUp).row
i = firstRow
Do Until i > lastrow
If Sheets("Datos del Proyecto").Range("G" & i).Value Like "" Then
Sheets("Datos del Proyecto").Range("F" & i).ClearContents
End If
i = i + 1
Loop
Application.EnableEvents = True
End Sub

Copy worksheets names in a column (From a loop code)

Someone can help me.
Have the following code to stack information from multiples worksheets into one ("database") - (Loop)
The only thing it is not working is the last action to copy the names of the workweeks in the "Database" Column "Aw".
Macro does not bring any error but the sheet names don't appear in the column "AW"
Any suggestion?
Sub Update()
' Update Templates
Dim All As Worksheet
Dim J As Integer
Dim Last As Long
Dim CopyRng As Range
Application.ScreenUpdating = False
' Update Consol
On Error Resume Next
Sheets("Database").Select
Range("A2:AL1048576").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Clear
For J = 6 To Sheets.Count
Sheets(J).Activate
Range("A2:AL2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
With Sheets("Database").Range("A1048576").End(xlUp)(2)
.PasteSpecial xlPasteValues
Database.Cells(Last + 1, "AW").Resize(CopyRng.Rows.Count).Value = All.Name
End With
Next
End Sub
Try this (I removed all selections, because they didn't seem necessary):
Sub Update()
'Update Templates
Dim All As String
Dim j As Integer
Dim Last As Long 'Missing value
Dim CopyRng As Long 'No need for Range in this Sub
Application.ScreenUpdating = False
' Update Consol
On Error Resume Next
With ActiveWorkbook 'modify
For j = 6 To .Sheets.Count
.Sheets(j).Range("A2:AL" & _
.Sheets(j).Range("A2:AL2").End(xlDown).Row).Copy
CopyRng = .Sheets(j).Range("A2:AL2").End(xlDown).Row - 1
All = .Sheets(j).Name
End With
With .Sheets("Database").Range("A1048576").End(xlUp)(2)
.PasteSpecial xlPasteValues
'EDIT:
debug.print All 'check immediate window for correct string
.Sheets("Database").Cells(Last + 1, _
"AW").Value = All
' .Sheets("Database").Cells(Last + 1, _
' "AW").Resize(CopyRng).Value = All
End With
Next
End Sub
Didn't know what 'Last' var is for, so don't forget to address it before running the code. Hope this helps.

Automatically creating worksheets based on a list in excel

I am trying to achieve the following.
When I enter a value on 'Master' worksheet in the Range A5:A50, a macro is run which creates a new worksheet with the same name as the value and then copies the template onto the new sheet.
In addition to this I would also like to copy the value adjacent to the value enter on Master worksheet to this new worksheet so it does calculations automatically.
For example I enter '1' in A5 and '2' in B5. I would like to create a new worksheet with name '1', copy the template from 'Template' worksheet and copy the value of B5 on to the new worksheet named '1'.
I have following code but it also tries to copy Template worksheet with macro is run which results in an error because a worksheet with name 'Template' already exists.
Sub CreateAndNameWorksheets()
Dim c As Range
Application.ScreenUpdating = False
For Each c In Sheets("Master").Range("A5:A50")
Sheets("Template").Copy After:=Sheets(Sheets.Count)
With c
ActiveSheet.Name = .Value
.Parent.Hyperlinks.Add Anchor:=c, Address:="", SubAddress:= _
"'" & .Text & "'!A1", TextToDisplay:=.Text
End With
Next c
Application.ScreenUpdating = True
End Sub
Right-click the Master worksheet's name tab and select View Code. When the VBE opens up, paste the following into the window titled something like Book1 - Master (Code).
Private Sub Worksheet_Change(ByVal target As Range)
If Not Intersect(target, Rows("5:50"), Columns("A:B")) Is Nothing Then
On Error GoTo bm_Safe_Exit
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual
Dim r As Long, rw As Long, w As Long
For r = 1 To Intersect(target, Rows("5:50"), Columns("A:B")).Rows.Count
rw = Intersect(target, Rows("5:50"), Columns("A:B")).Rows(r).Row
If Application.CountA(Cells(rw, 1).Resize(1, 2)) = 2 Then
For w = 1 To Worksheets.Count
If LCase(Worksheets(w).Name) = LCase(Cells(rw, 1).Value2) Then Exit For
Next w
If w > Worksheets.Count Then
Worksheets("Template").Visible = True
Worksheets("Template").Copy after:=Sheets(Sheets.Count)
With Sheets(Sheets.Count)
.Name = Cells(rw, 1).Value2
.Cells(1, 1) = Cells(rw, 2).Value
End With
End If
With Cells(rw, 1)
.Parent.Hyperlinks.Add Anchor:=Cells(rw, 1), Address:="", _
SubAddress:="'" & .Value2 & "'!A1", TextToDisplay:=.Value2
End With
End If
Next r
Me.Activate
End If
bm_Safe_Exit:
Worksheets("Template").Visible = xlVeryHidden
Me.Activate
Application.Calculation = xlCalculationAutomatic
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Note that this depends on you having a worksheet named Template in order to generate the new worksheets. It also keeps the Template worksheet xlVeryHidden which means that it will not show up if you try to unhide it. Go into the VBE and use the Properties window (e.g. F4) to set the visibility to visible.
This routine should survive pasting multiple values into A2:B50 but it will discard proposed worksheet names in column A that already exists. There must be a value i both column A and column B of any row before it will proceed.
There are currently no checks for illegal worksheet name characters. You may want to familiarize yourself with those and add some error checking.
Another example relevant to the post title but not the specific application. Code updates sheets in master list with list row number creating sheet from template if it doesn't exist.
Other reference: https://stackoverflow.com/a/18411820/9410024.
Sub UpdateTemplateSheets()
' Update sheets in list created from a template
'
' Input: List on master sheet, template sheet
' Output: Updated sheet from template for each item in list
'
Dim wsInitial As Worksheet
Dim wsMaster As Worksheet
Dim wsTemp As Worksheet
Dim lVisibility As XlSheetVisibility
Dim strSheetName As String
Dim rIndex As Long
Dim i As Long
On Error GoTo Safe_Exit
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
' Application.Calculation = xlCalculationManual
Set wsInitial = ActiveSheet
Set wsMaster = Sheets("Summary")
Set wsTemp = Sheets("Template")
lVisibility = wsTemp.Visible ' In case template sheet is hidden
wsTemp.Visible = xlSheetVisible
For rIndex = 2 To wsMaster.Cells(Rows.Count, "A").End(xlUp).Row
' Ensure valid sheet name
strSheetName = wsMaster.Cells(rIndex, "A").Text
For i = 1 To 7
strSheetName = Replace(strSheetName, Mid(":\/?*[]", i, 1), " ")
Next i
strSheetName = Trim(Left(WorksheetFunction.Trim(strSheetName), 31))
' Ensure sheet name doesn't already exist
If Not Evaluate("IsRef('" & strSheetName & "'!A1)") Then
wsTemp.Copy after:=Sheets(Sheets.Count)
With Sheets(Sheets.Count)
.Name = strSheetName
End With
End If
With Sheets(strSheetName)
.Range("B59").Value = rIndex * 16 + 1 ' Update template block option row
End With
Next rIndex
Safe_Exit:
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
'Application.Calculation = xlCalculationAutomatic
wsInitial.Activate
wsTemp.Visible = lVisibility ' Set template sheet to its original visible state
End Sub