I have code to copy a Worksheet A, columns A:C (no set row quantities, this will be re-used and the quantities will change) and paste to the first blank row in the same workbook, different sheet, Worksheet B (this also has no set row quantities and will change).
Worksheet B has a formula in the same columns that I want to paste to that returns "" if there is no data. I think VBA is seeing the "" and assuming there is data there; however, it is not pasting even to lines without said formula.
Sub Copy_Created_Fringe_Accounts()
Dim SourceRange As Range
Dim DestRange As Range
Dim DestSheet As Worksheet
Dim LastRow As Long
'Source sheet and range
Set SourceRange = Sheets("CREATED FRINGE ACCTS").Range("A2:C500")
'Destination sheet and range
Set DestSheet = Sheets("99 BUDGET WORKSHEET")
'Last Row
LastRow = DestSheet.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'Copy and paste to destination
Set DestRange = DestSheet.Range("A" & LastRow + 1)
SourceRange.Copy DestRange
End Sub
Nothing happens when I run it. I expect to see the data from Worksheet A copied to Worksheet B, starting at the first available empty row.
I am fairly new to VBA so any help/understanding is appreciated.
Finding the last row
Try using UsedRange to find the last used row as this is safer than using Find.
LastRow = DestSheet.UsedRange.Rows.Count
A side note
If your code resides in the same place as these worksheets then I would recommend using their code name. This will protect you from running into an error if the sheet doesn't exist.
Related
I have a workbook that serves as a database with an Input page. I want to make Column A dynamic, which will update header rows on all pages of the worksheet. I have created a macro that copies these header names from Column A on the Input Sheet, and pastes these values as headers on the next sheet. Once these header rows are labeled they are copied on Sheet 2 a second time so they can be pasted as additional header rows to the right of the previously pasted values. The reason is because they are values monitored at Start and Stop times, which will have different data stored at each time. Also, I would like these header rows to have medium weight borders around them. I have drafted the following code, but it only works partially correct by copying the first set as expected, however the second copy part does not work as well. I was hoping to create a template sheet in the document, which would have Date, Start Time, Space, End time. This would mean the copy rows would need to be inserted after Start Time and again after End time in a dynamic manner so this list could grow. Please see my attached code and thank you so much for any help.
Sub CopyData2()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim wb As Workbook
Dim lRow As Long
Dim lCol1 As Long
Dim lCol2 As Long
Dim cRange As Range
Dim iCell As Range
Dim iRange As Range
Set wb = ThisWorkbook
Set ws1 = wb.Sheets(1)
Set ws2 = wb.Sheets(2)
lRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
lCol1 = ws2.Cells(12, Columns.Count).End(xlToLeft).Column
lCol2 = ws2.Cells(3, Columns.Count).End(xlToLeft).Column
ws1.Range("A13:A" & lRow).Copy
ws2.Range("C3").PasteSpecial xlPasteValues, Transpose:=True
Set cRange = ws2.Range(("C3"), ws2.Range("C3").End(xlToRight))
cRange.Select
cRange.Copy
ws2.Cells(3, lCol2).PasteSpecial xlPasteValues
End Sub
I'd suggest replacing the last 4 lines with those below
With ws2.Range(("C3"), ws2.Range("C3").End(xlToRight))
ws2.Cells(3, lCol2).Resize(.Rows.Count,.Columns.Count).Value2 = .Value2
End With
in order to avoid both the Select, and redundant use of the clipboard.
I don't understand what you're trying to do with the Start/Stop times but the try removing cRange.Select to fix the 2nd Copy/Paste
I want to make variable C into the selection cell
like this
Dim c= selection area
I tried this code:
ActiveCell.Value
but doesnt' working..
Selcetion cell is always change.. so can't use range(null:null)
Sub noname1()
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim lCopyLastRow As Long
Dim lDestLastRow As Long
Dim B As String
Dim C
B = Cells(20, 87).Value
C = Selection
'Set variables for copy and destination sheets
Set wsCopy = Workbooks("source.xlsx").Worksheets("5.588")
Set wsDest = Workbooks("dest.xlsx").Worksheets(B)
lCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "A").End(xlUp).Row
'Offset property moves down 1 row
lDestLastRow = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Offset(1).Row
wsCopy.Range(C).Copy _
wsDest.Range("A" & lDestLastRow)
'Optional - Select the destination sheet
wsDest.Activate
End Sub
A "Range" can be a single cell or any number of cells together. Since all cells are on one sheet or another every range is on a sheet as well. A range can't include cells from more than one sheet.
All sheets are in workbooks. No sheet can be in more than one workbook. Therefore no range can be spread over more than one workbook.
To specify a range you need to tell the workbook, the worksheet, its first cell and its last cell. If you don't specify the workbook the ActiveWorkbook will be presumed. If you don't specify the worksheet, the ActiveSheet will be presumed. Therefore
Range("B5:D15")
' is the same as
Activeworkbook.ActiveSheet.Range("B5:D15")
You don't need to select a range in order to copy, clear, delete or modify it. VBA's Selection object supports the user's selection on the screen but otherwise largely mirrors the Range object which disregards the screen. Therefore, if you select B5:D15 and enter ? Selection.Address(0,0) in the Immediate pane the answer will be "B5:D15". You will get the same reply if you enter ? Range("B5:D15").Address(0,0).
In my example, B5 and D15 are the first and last cells of the range. Excel creates a range name from these coordinates which is presented in inverted commas because it's a string. However, you can also specify the same cells as members of the Cells collection (all cells in a range - by default the entire sheet).
Debug.Print Range("B5:D15").Address
Debug.Print Range(Cells(5, 2), Cells(15, 4)).Address
The two lines of code print the same response but the second one is much easier to create using variables, such as changing row or column numbers.
So, now you can see what the code below would do.
Range(Cells(5, 2), Cells(15, 4)).Copy Destination:=Sheet2.Cells(1, 1)
Hi I have the following code, the first part of which works fine, but I cannot get the destination bit for rng2 to work - keep getting a "application-defined or object-defined error". Wondered if anyone could help with where I am going wrong as I've tried a few different methods (destination being the neatest I know a little about).
Sub Assign_TN()
' Assign_TN Macro
Dim ws As Worksheet
Dim wbk2 As Workbook
Dim ws2 As Worksheet
Dim Rng As Range
Dim rng2 As Range
Set ws = ThisWorkbook.Worksheets("Check sheet")
Set wbk2 = Workbooks.Open("A Location\TNG Register ongoing.xlsx")
Set ws2 = wbk2.Worksheets("TNG")
'This clears the TN has failed comment in the event the cannot generate Tn macro has been run
ws.Range("A83").ClearContents
' Copy the first set of data from the checksheet and paste into the first blank row of the TNG register
Set Rng = ws.Range("B93:M93")
Rng.Copy Destination:=ws2.Cells(Rows.Count, 2).End(xlUp).Offset(1)
'copy second set of data from checksheet and paste into first blank cell in column 22
Set rng2 = ws.Range("Q93:AM93")
rng2.Copy
Destination = ws2.Cells(Rows.Count, 22).End(x1Up).Offset(0)
All I need this to do is copy two ranges data into two separate area's of the first unpopulated row in a second sheet. This in effect generates an acceptance number which is subsequently copied and pasted into the first sheet (this bit of code hasn't been added and works well).
I am writing a macro that loops through a "source" sheet and for each value in column A, copy a range from template sheet to a destination sheet. After the template range is copied, I need to change a few values in destination sheet based on the source sheet value. Right now I am trying to get the copy working. The copy is failing with error 1004 'The information cannot be pasted because the Copy area and the paste area are not the same size.'
Sub CopyRangeFromOneSheetToAnother()
Dim iLastRow As Long
Dim wb As Workbook
Dim shtSource As Worksheet
Dim shtTemplate As Worksheet
Dim shtDest As Worksheet
Dim sResourceName
Dim rngCalcTemplate As Range
Set wb = ThisWorkbook
Set shtSource = wb.Sheets(1)
Set shtTemplate = wb.Sheets("res_tpl")
Set shtDest = wb.Sheets.Add
'--set range for copying. Hard-coded for now would be nice if it would auto shrink/expand
Set rngCalcTemplate = shtTemplate.Range("A2:M7")
'Find the last row (in column A) with data.
iLastRow = shtSource.Range("A:A").Find("*", searchdirection:=xlPrevious).Row
'--loop through source sheet and copy template range to dest for each
For iSourceSheetRow = 2 To iLastRow
sResourceName = shtSource.Cells(iSourceSheetRow, 1)
rngCalcTemplate.Copy shtDest.Range("A" & Rows.Count).End(xlDown)
Next
End Sub
The problem is with the following line of your code:
rngCalcTemplate.Copy shtDest.Range("A" & Rows.Count).End(xlDown)
If you place your cursor at the very last cell in column A (i.e. at "A" & Rows.Count, possibly A1048576) and then press Ctrl-Down, you are still at the very last cell in column A.
If you then try to paste 6 rows of information starting at that cell, there won't be room to do so - there is only one row of "pastable" area to use.
You are probably wanting to find the row following the last used cell in that column, so your code should be:
rngCalcTemplate.Copy shtDest.Range("A" & shtDest.Rows.Count).End(xlUp).Offset(1, 0)
I have a spreadsheet I'm using to compile text that changes all the time.
In column AD, Row 4(AD4) I put the contents of text, and it can have data going 1000 to 4000 rows down. It changes every time, so there is no static range name. I need a macro that
finds the final piece of data in that column,
then automatically "drags a box" from that spot two columns to the left (AB4)
and copies it... (A 3000 row piece of text would be AB4:AD3004) (Macro stops there, with text to be copied highlighted)
The current version finds the bottom cell correctly, but if I run the macro a 2nd time, with new data, it keeps trying to copy the same range. (I used the Formula Define.Name method, to name the cell, and then selected AB4:LastRow) but it is ALWAYS 3160 whether data goes to row 4000 or not.....
Sub Last_row()
Cells(Application.Rows.Count, 30).End(xlUp).Select
' following lines of code are useless
Range("AB4:AD3160").Select
Range("AD3160").Activate
Selection.Copy
End Sub
To answer your question directly:
With Sheet1
.Range("AB4", .Cells(Rows.Count, "AD").End(xlUp)).Copy
End With
Copy to specific location WITHOUT using clipboard:
With Sheet1
.Range("AB4", .Cells(Rows.Count, "AD").End(xlUp)).Copy Sheet2.[A1]
End With
Copy and exclude formatting:
With Sheet1
With .Range("AB4", .Cells(Rows.Count, "AD").End(xlUp))
Sheet2.Cells(1, "A").Resize(.Rows.Count, .Columns.Count).Value = .Value
End With
End With
Note: Replace all sheet codenames (sheet1, Sheet2) above with your actual sheet codenames.
Your current code hard-codes the range of interest with
Range("AB4:AD3160").Select
This code will define a dynamic range starting from AB4 to the last non-empty cell in column AD
You can then use this range (without selecting) for changing values elsewhere (note that you may not need to actually copy rng1, it is possible to dump these values to a separate range directly without a copy and paste.
Sub Last_row()
Dim rng1 As Range
Set rng1 = Range([ab4], Cells(Rows.Count, 30).End(xlUp))
rng1.Copy
End Sub
Update: Example of how to copy a dynamic sized range from one sheet to another without a copy and paste:
Sub Last_row2()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim rng1 As Range
Set ws1 = Sheets(1)
Set ws2 = Sheets(2)
Set rng1 = ws1.Range(ws1.[ab4], ws1.Cells(Rows.Count, 30).End(xlUp))
ws2.[a1].Resize(rng1.Rows.Count, rng1.Columns.Count).Value = rng1.Value
End Sub