I would like to ask for a help. My Macro was about to populate the current date to all populated rows. At the begining it seemed to work and suddenly it started to change (overwrite) the header to the current date and put the current date in 1 cell below. Could anyone help me what should I amend to make it work properly?
Here is the macro code (reformatted):
Sub DateVerified()
Sheets("Data").Activate
Dim rngAddress As Range
Set rngAddress = Range("A1:ZZ1").Find("Verified Date").Offset(1, 0)
rngAddress.Select
Dim ac As Integer
Dim lastr As Long
Dim sh As Worksheet
Set sh = ActiveSheet
ac = ActiveCell.Column
lastr = sh.Cells(Rows.Count, ac).End(xlUp).Row
Range(Cells(2, ac), Cells(lastr, ac)).Select
Selection.ClearContents
Selection.Formula = "=TEXT(Now(),""dd/mm/yyyy"")"
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
The following might suit:
Sub DateVerified()
Dim rngAddress As Range
Dim ac As Integer
Dim lastr As Long
Dim sh As Worksheet
Sheets("Data").Activate
Set rngAddress = Range("A1:ZZ1").Find("Verified Date").Offset(1, 0)
rngAddress.Select
Set sh = ActiveSheet
lastr = sh.Cells(Rows.Count, 1).End(xlUp).Row
ac = ActiveCell.Column
Range(Cells(2, ac), Cells(lastr, ac)).Select
Selection.ClearContents
Selection.Formula = "=TEXT(Now(),""dd/mm/yyyy"")"
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
End Sub
I think that this is likely to be going wrong on the line below:
lastr = sh.Cells(Rows.Count, ac).End(xlUp).Row
This attempts to go to the final row of the spreadsheet for the active column and then do the equivalent of ctrl+up in excel to find the last row populated in that column. To test this theory add a line of code directly after this:
debug.print "lastr set to " & lastr
and see what this value is set to looking at the immediate window (use Ctrl+G to open from the VBA editor).
Related
I am unable to stop my VBA from looping within the range that I have specified, could someone please check my code and tell me where I am going wrong with it.
Option Explicit
Sub Macro()
Dim oWs As Worksheet
Dim rSearchRng As Range
Dim lEndNum As Long
Dim vFindVar As Variant
Dim loc As Range
Dim LastRow As Long
Dim LRow As Long
Dim Copy As Range
Set oWs = ActiveWorkbook.Worksheets("Sheet1")
LastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Offset(1).Row
lEndNum = oWs.Range("A2").End(xlDown).Row
Set Copy = oWs.Range("A2" & LRow)
Set rSearchRng = oWs.Range("A2:A" & CStr(lEndNum))
Set loc = rSearchRng.Cells.Find(Range("O2").Value)
If Not loc Is Nothing Then
Do Until loc Is Nothing
loc.Select
Range(ActiveCell.Offset(0, 0), ActiveCell.Offset(0, 12)).Select
Selection.Copy
Sheets("Sheet2").Select
LastRow = Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Offset(1).Row
Range("A" & LastRow).Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
ActiveSheet.Paste
Sheets("Sheet1").Select
Application.CutCopyMode = False
Set loc = rSearchRng.FindNext(loc)
Loop
End If
Set loc = Nothing
MsgBox "Complete"
End Sub
Thanks in advance
Aydos
Here is a quote from the help text on FindNext
When the search reaches the end of the specified search range, it wraps around to the beginning of the range. To stop a search when this wraparound occurs, save the address of the first found cell, and then test each successive found-cell address against this saved address.
I think that applies to your situation
it's because Find() method keeps on going inside the range
so you have to stop it when it wraps back to the first found cell by monitoring its address, as follows (along with some other refactoring):
Sub Macro()
Dim oWs As Worksheet
Dim rSearchRng As Range
Dim lEndNum As Long
Dim vFindVar As Variant
Dim loc As Range
Dim LastRow As Long
Dim LRow As Long
Dim Copy As Range
Set oWs = ActiveWorkbook.Worksheets("Sheet1")
LastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Offset(1).Row
lEndNum = oWs.Range("A2").End(xlDown).Row
Set Copy = oWs.Range("A2" & LRow)
Set rSearchRng = oWs.Range("A2:A" & CStr(lEndNum))
Dim locFirstAddress As String
Set loc = rSearchRng.Cells.Find(Range("O2").value)
If Not loc Is Nothing Then
locFirstAddress = loc.Address
Do
Range(ActiveCell.Offset(0, 0), ActiveCell.Offset(0, 12)).Copy
With Sheets("Sheet2")
.Range("A" & .Cells(.Rows.Count, 1).End(xlUp).Offset(1).Row).PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
.Paste
End With
Application.CutCopyMode = False
Set loc = rSearchRng.FindNext(loc)
Loop While loc.Address <> locFirstAddress
End If
Set loc = Nothing
MsgBox "Complete"
End Sub
I'm trying to copy some rows from a sheet and then paste in other sheet that will contain the data. Later on I will erase the data form the original sheet to be fulfill again and repeat process.
My problem is that, it looks like I'm coping as well the empty cells from the original sheet so when paste for any reason excel consider this empty cell as the last one. More than sure I'm doing something wrong, the macro is this:
Sub CopyTable()
'
' CopyTable Macro
'
'
' Variables
Dim sht As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
Set sht = Worksheets("Form")
Set StartCell = Range("A9")
'Refresh UsedRange
Worksheets("Form").UsedRange
'Find Last Row and Column
LastRow = StartCell.SpecialCells(xlCellTypeLastCell).Row
LastColumn = StartCell.SpecialCells(xlCellTypeLastCell).Column
'Select Range
sht.Range(StartCell, sht.Cells(LastRow, LastColumn)).Select
' Copy range and move to Data sheet
Selection.Copy
Sheets("Data").Select
' Place pointer on cell A1 and search for next empty cell
Range("A1").Select
Do While Not IsEmpty(ActiveCell)
ActiveCell.Offset(1, 0).Select
Loop
' Once find, go back once to place on last empty and paste data from Form sheet no formating
ActiveCell.Offset(0, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A1").Select
End Sub
I assume that the data from the form always has an entry in column A - that there are no entries where A is blank but other cells on the row are not blank:
Sub CopyTable()
Dim sourcesheet As Worksheet
Dim DestSheet As Worksheet
Dim Source As Range
Dim dest As Range
Dim Startcell As Range
Set sourcesheet = ThisWorkbook.Worksheets("Form")
Set Startcell = sourcesheet.Range("A9")
Set Source = sourcesheet.Range(Startcell, Startcell.SpecialCells(xlCellTypeLastCell))
Set DestSheet = ThisWorkbook.Worksheets("Data")
Set dest = DestSheet.Cells(DestSheet.Rows.Count, 1).End(xlUp).Offset(1, 0)
'set dest to next blank row
Source.Copy dest
Set dest = DestSheet.Range(dest, dest.SpecialCells(xlCellTypeLastCell))
dest.Sort key1:=dest.Cells(1, 1)
'sort to shift blanks to bottom
End Sub
finally surfing in stackoverflow I found a pice of code that do exactly want I need, so final macro looks like this:
Sub CopyTable()
Dim lastVal As Range, sht As Worksheet
Set sht = Sheets("Form")
Set lastVal = sht.Columns(2).Find("*", sht.Cells(1, 2), xlValues, _
xlPart, xlByColumns, xlPrevious)
Debug.Print lastVal.Address
sht.Range("A9", lastVal).Resize(, 26).Select 'select B:Ag
Selection.Copy
Sheets("Data").Select
Range("A1").Select
Do While Not IsEmpty(ActiveCell)
ActiveCell.Offset(1, 0).Select
Loop
ActiveCell.Offset(0, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A1").Select
End Sub
The following is my VBA code, for some reason the code will run but not actually paste in the range I need it to paste. Anybody have any ideas why it won't paste my values?
The programs goes to my selected cell that I'm looking for, but now the activecell becomes my range and I'm trying to paste the it there. Any information will help, it just doesn't want to paste the values in the range I selected.
Sub Macro1()
Dim Form1033 As Worksheet
Dim CleaningSchedule As Worksheet
Set Form1033 = Worksheets("Form1033andForm1034")
Set CleaningSchedule = Worksheets("CleaningSchedule")
Dim Day As Range
Set Day = Form1033.Range("$J$3")
With Form1033
Range("$G$5:$G$18").Select
Selection.Copy
End With
With CleaningSchedule
Dim i As Integer
For i = 6 To 37
If Cells(4, i).Value = Day.Value Then
Cells(5, i).Select
Range(ActiveCell, Cells(ActiveCell.Rows + 13, ActiveCell.Column)).Select
Selection.PasteSpecial Paste:=xlPasteFormulas, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
End If
Next i
End With
Form1033.Select
Application.CutCopyMode = False
Range("$G$5:$G$18").ClearContents
MsgBox "Scoresheet Updated"
End Sub
I fixed the code here, but please read the link I provided in my comment, and you will not have these errors in the future.
I also commented the refactors I did to the code. Also, notice that I assigned the Cells and Ranges to the parent worksheet with .. (See #BruceWayne's link in his comment to your original question)
Sub Macro1()
Dim Form1033 As Worksheet
Dim CleaningSchedule As Worksheet
Set Form1033 = Worksheets("Form1033andForm1034")
Set CleaningSchedule = Worksheets("CleaningSchedule")
Dim Day As Range
Set Day = Form1033.Range("$J$3")
'copy the range directly
Form1033.Range("$G$5:$G$18").Copy
With CleaningSchedule
Dim i As Integer
For i = 6 To 37
If .Cells(4, i).Value = Day.Value Then
'paste directly to range and i also combined 13 rows plus row 5, since you are always using the same row
Range(.Cells(5,i), Cells(18,i)).PasteSpecial Paste:=xlPasteFormulas, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
End If
Next i
End With
'clear contenst directly
Form1033.Range("$G$5:$G$18").ClearContents
MsgBox "Scoresheet Updated"
End Sub
Since you are using "With" statement, you need to add a "." in front of "cells" and "range" and any other references you make. For example:
With myWorksheet
.range("A1").copy
End with
So, the problem in this case is that you still remain on the same worksheet and clear the contents of the cells you had pasted.
I am trying to copy the last row and paste special at the next row. When I try the following code for an individual worksheet it works fine:
Sub Macro1()
Dim LR As Long
LR = Range("E" & Rows.Count).End(xlUp).Row
Rows(LR).Select
Selection.Copy
Rows(LR + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
But when I am trying to loop through all worksheets, it is only pasting special in one of the worksheets the same copied row number of times instead of repeating to each worksheet. Could you please advise what I am doing wrong on the following for loop?
Sub Macro1()
Dim ws As Worksheet
Dim wb As Workbook
Dim LR As Long
Set wb = ActiveWorkbook
For Each ws In wb.Worksheets
If ws3.Name Like "*.plt" Then
LR = Range("E" & Rows.Count).End(xlUp).Row
Rows(LR).Select
Selection.Copy
Rows(LR + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
Next ws
End Sub
Thanks in advance!
To save some overhead, you should first refrain from using .Select and .Selection.*. If you anyways want to copy just the value you should do so via the .Value property of the cell. Secondly, you should use the With statement to make sure that you are referencing the target sheet. Finally, you should set unused objects to Nothing in the end. The following code should do the trick.
Code
Sub Macro1()
Dim ws As Worksheet
Dim wb As Workbook
Dim rng As Range
Set wb = ActiveWorkbook
For Each ws In wb.Worksheets
With ws
If .Name Like "*.plt" Then
Set rng = .Range("E" & Rows.Count).End(xlUp).EntireRow
rng.Offset(1).Value = rng.Value
End If
End With
Next ws
Set ws = Nothing
Set rng = Nothing
Set wb = Nothing
End Sub
I think that this
If ws3.Name Like "*.plt" Then
might be your issue. You need to enable Option Explicit so that you do not use undefined names.
Also, make
Set wb = ActiveWorkbook
to
Set wb = ThisWorkbook
I have the following VBA code that takes a single row from Sheet "Tabled data", copies the data, then pastes the data into the next available row in Sheet "Running list". However the original row has formulas and I need the values to paste, not the formulas. I've seen numerous ways to do it with Range.PasteSpecial but this code didn't use Range and I'm not sure how to incorporate it.
Note: I modified this code from here: http://msdn.microsoft.com/en-us/library/office/ff837760(v=office.15).aspx. It originally had an IF statement to match content in a cell then paste it in a certain sheet according to the content in the cell. I only had one sheet to copy to and didn't need the IF. I don't really need to find the last row of data to copy either as it will only ever be one row with range of A2:N2. But if I take out the FinalRow section and the For and replace with Range("A2:N2") it doesn't work so I left those in.
Any guidance on how to add in the PasteValues property without making this more complicated? I'm also open to simplification of the For or FinalRow variable such as using Range. I'm only sort of familiar with VBA, having done a few things with it, but usually after much searching and modifying code.
Public Sub CopyData()
Sheets("Tabled data").Select
' Find the last row of data
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
' Loop through each row
For x = 2 To FinalRow
ThisValue = Cells(x, 1).Value
Cells(x, 1).Resize(1, 14).Copy
Sheets("Running list").Select
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
Cells(NextRow, 1).Select
ActiveSheet.Paste
Sheets("Tabled data").Select
Next x
End Sub
Hopefully we can actually make this more simple.
Public Sub CopyRows()
Sheets("Sheet1").UsedRange.Copy
lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
'check if the last cell found is empty
If IsEmpty(ActiveSheet.Cells(lastrow, 1)) = True Then
'if it is empty, then we should fill it
nextrow = lastrow
Else
'if it is not empty, then we should not overwrite it
nextrow = lastrow + 1
End If
ActiveSheet.Cells(nextrow, 1).Select
ActiveSheet.Paste
End Sub
edit: I expanded it a little so that there won't be a blank line at the top
I found a working solution. I recorded a macro to get the paste special in there and added the extra code to find the next empty row:
Sub Save_Results()
' Save_Results Macro
Sheets("Summary").Select 'renamed sheets for clarification, this was 'Tabled data'
'copy the row
Range("Table1[Dataset Name]").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
' paste values into the next empty row
Sheets("Assessment Results").Select
Range("A2").Select
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
Cells(NextRow, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' Return to main sheet
Sheets("Data Assessment Tool").Select
End Sub
Just copy the data all at once, no need to do it a row at a time.
Sub CopyData()
With ThisWorkbook.Sheets("Tabled data")
Dim sourceRange As Range
Set sourceRange = .Range(.Cells(2, 1), .Cells(getLastRow(.Range("A1").Parent), 14))
End With
With ThisWorkbook.Sheets("Running list")
Dim pasteRow As Long
Dim pasteRange As Range
pasteRow = getLastRow(.Range("A1").Parent) + 1
Set pasteRange = .Range(.Cells(pasteRow, 1), .Cells(pasteRow + sourceRange.Rows.Count, 14))
End With
pasteRange.Value = sourceRange.Value
End Sub
Function getLastRow(ws As Worksheet, Optional colNum As Long = 1) As Long
getLastRow = ws.Cells(ws.Rows.Count, colNum).End(xlUp).Row
End Function
Private Sub Load_Click()
Call ImportInfo
End Sub
Sub ImportInfo()
Dim FileName As String
Dim WS1 As Worksheet
Dim WS2 As Worksheet
Dim ActiveListWB As Workbook
Dim check As Integer
'Application.ScreenUpdating = False
Set WS2 = ActiveWorkbook.Sheets("KE_RAW")
confirm = MsgBox("Select (.xlsx) Excel file for Data transfer." & vbNewLine & "Please ensure the sheets are named Sort List, Second and Third.", vbOKCancel)
If confirm = 1 Then
FileName = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xls*", _
Title:="Select Active List to Import", MultiSelect:=False)
If FileName = "False" Then
MsgBox "Import procedure was canceled"
Exit Sub
Else
Call CleanRaw
Set ActiveListWB = Workbooks.Open(FileName)
End If
Set WS1 = ActiveListWB.Sheets("Sort List")
WS1.UsedRange.Copy 'WS2.Range("A1")
' WS2.Range("A1").Select
WS2.UsedRange.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'WS2.Range ("A1")
ActiveWorkbook.Close False
'Call ClearFormulas
' Call RefreshAllPivotTables
Sheets("Key Entry Data").Select
'Sheets("Raw").Visible = False
'Application.ScreenUpdating = True
MsgBox "Data has been imported to workbook"
Else
MsgBox "Import procedure was canceled"
End If
Application.ScreenUpdating = True
End Sub
Sub CleanRaw()
Sheets("KE_RAW").Visible = True
Sheets("KE_RAW").Activate
ActiveSheet.Cells.Select
Selection.ClearContents
End Sub