I need to be able to copy different ranges of cells from one worksheet to another. For example A1:A4, C3:C7, D3:D6. I need the code to do the following:
Copy different data from those cells in the first worksheet (worksheet1) and paste them onto the same line but transposed on the second worksheet (worksheet2). I don't need to keep the original formatting.
When pasting the data I need it to find the last row and paste it below that row.
I can write a code which will do most of that but I only know how to get the code to do it for one cell range e.g. A1:A4.
Any help would be greatly appreciated.
OK, technically SO isn't a code-writing service but I use a code that does basically just that, so you might as well have it;
Sub CopyTransposeRange()
Dim shtCopy As Worksheet
Dim shtPaste As Worksheet
Dim rngCopy As Range
Set shtCopy = Sheets("Sheet1").Activate
Set shtPaste = Sheets("Sheet2")
Set rngCopy = Range("A1:A36")
'Put whatever's necessary in here to select the correct range
shtCopy.rngCopy.Copy
shtPaste.Activate
shtPaste.Range(Cells(shtPaste.UsedRange.Rows.Count + 1, 1), Cells(shtPaste.UsedRange.Rows.Count + 1, rngCopy.Rows.Count)).PasteSpecial _
xlPasteAll, xlPasteSpecialOperationNone, False, True
End Sub
Yes, I know activating sheets isn't best practice, but works for me ¯_(ツ)_/¯
hope it helps.
Try this code, please.
It will copy your selected range and transpose it in the roe 2 of second sheet:
Sub testCopyTransposedRanges()
Dim sh2 As Worksheet, inpRng As Range, lastCol As Long, arrTr As Variant
Set inpRng = Application.InputBox("Select range to be copied and transposed:", _
"Range Selection", Selection.Address, Type:=8)
If inpRng Is Nothing Then Exit Sub
arrTr = inpRng.value
If IsEmpty(arrTr) Then Exit Sub
Set sh2 = Worksheets("worksheet2") ' use here your sheet name!!!
lastCol = sh2.Cells(2, Cells.Columns.Count).End(xlToLeft).Column + 1
sh2.Cells(2, lastCol).Resize(, UBound(arrTr)).value = WorksheetFunction.Transpose(arrTr)
End Sub
It must be 'filterred' for 'Cancel', multi column selection etc. But this will be done only if such a solution matches your need. Otherwise, you must present the logic based on what to create an algorithm to automatically select the necessary ranges.
Related
I'm having an Excel Spreadsheet with 3 sheets inside and I need to copy certain cell range from Sheet1 and copy it to Sheet2.
And I'm trying to get the range of cells to be copied as an input in a cell that is available in Sheet 3. Like the cell would have value A4:X6 in it. But I'm unable to get the input values passed on to the Range function in my Macro code.
Below is my code and when I execute, it just enters an empty row in the Sheet 2
Sub CopyData()
Sheet3.Select
Set Range1 = Range(Cells(3, 3).Value)
Sheet1.Select
Range1.Copy
Sheet2.Select
Range("A2").Select
Range("A2").EntireRow.Insert Shift:=xlShiftDown
End Sub
I want the contents of cell denoted in Range1 to be copied from Sheet1 and pasted in Sheet2.
Thank you in advance!
John Coleman is right you can avoid using Select for the whole subroutine. But, your problem here is when you define the range it is defining it specifically for Sheet3 and not Sheet1. One alternative is you could store the address in a string that gets passed to the Range() function, but specify which sheet you want your range to reflect. The rest of the code can be handled much the same without using Select.
Sub CopyData()
Dim range1 as Range
dim strRange as String
strRange = Sheet3.Cells(3, 3).Value
Set range1 = Sheet1.Range(strRange)
range1.Copy Sheet2.Range("A2")
Sheet2.Range("A2").EntireRow.Insert Shift:=xlShiftDown
End Sub
Use Set Range1 = Sheet3.Range(Cells(3, 3).Value) instead of Set Range1 = Range(Cells(3, 3).Value) or the range get selected from sheet1 because of Sheet1.Select
when i execute, it just enters an empty row in the Sheet 2 Of course it does. Your code does exactly that. Line Range("A2").EntireRow.Insert Shift:=xlShiftDown creates the row. There is nothing in your code that pastes the content of range A4:X6 ot whatever input you got in the cell.
Actually, if you delete your code and leave it like this:
Sub CopyData()
Range("A2").EntireRow.Insert Shift:=xlShiftDown
End Sub
You will get the same, a new row inserted.
I want the contents of cell denoted in Range1 to be copied from Sheet1 and pasted in Sheet2
I guess you are trying to copy a specific range, not a whole row and paste it, you need something like this:
Sub CopyData()
Dim Range1 As Range
Set Range1 = Sheet1.Range(Sheet3.Cells(3, 3).Value)
Range1.Copy
Sheet2.Range("A2").PasteSpecial (xlPasteAll) 'this command will paste the contents
End Sub
This example shows how to insert a line above line 2, copied to the format of the line down (line 3) and from the header line
Range("2:2").Insert CopyOrigin:=xlFormatFromRightOrBelow
As you understood, .Insert will always insert blank row.
I guess that you would like to paste a range in your sheet and not insert a new row for this you should do like this :
Sheets("SheetName").Range("A2").PasteSpecial (xlPasteAll)
Also note that xlPasteAll is an XlPasteType as xlPasteFormats , xlPasteValues and so on.
xlPasteAll will paste all
xlPasteFormats will paste the source format
xlPasteValues will paste the value
So your code would be as below :
Sub CopyData()
Dim Range1 As Range
Dim Range2 As Range
Set Range1 = Sheet1.Range(Sheet3.Cells(3, 3).Value)'Will define the range you want to copy
Range1.Copy 'here you copy the range
Set Range2 = Sheet2.Range("A2") 'Set the range where you want to paste data
Range2.PasteSpecial (xlPasteValues) 'then you will paste your range
End Sub
Click here to get the list of those XlPasteType
BONUS
Sheet2.Select
Range("A2").Select
is the same as
Set Range2 = Sheet2.Range("A2")
But the last way is better because it avoid Select which can slow down your performances !
Is there a specific requirement for inserting the copied data at the top or would you be happy adding it to the end of the "list" instead? If so, you could find the last used row and add it at the bottom instead like this:
Sub CopyFromSheet1toSheet2()
Dim thisBook As Workbook: Set thisBook = ThisWorkbook
Dim sheetOne As Worksheet: Set sheetOne = thisBook.Worksheets("Sheet1")
Dim sheetTwo As Worksheet: Set sheetTwo = thisBook.Worksheets("Sheet2")
Dim copyFromRange As Range: Set copyFromRange = sheetOne.Range("A4:X6")
Dim lastRow As Long: lastRow = sheetTwo.Cells(Rows.Count, 1).End(xlUp).Row
Dim pasteToRange As Range: Set pasteToRange = sheetTwo.Range("A" & lastRow)
copyFromRange.Copy Destination:=pasteToRange
End Sub
"lastRow" returns the numeric value of the last used row in a given column. If you have data in A1:A4 then this code would add the next lot of data copied to A5 and below.
I have a worksheet which has different data on it. I want to copy, transpose paste each row in a specified range onto a separate worksheet for each row. I'm pretty much stuck as I'm fairly new to this.
I don't quite understand where to proceed from this.
Sub LoopRow()
Dim rng As Range
Dim row As Range
Dim cell As Range
Set rng = Range("A6:AI57")
For Each row In rng.Rows
End Sub
Use this code:
All you need to do is change the Sheet Name. We are looping through the specified range and copy pasting each row on another sheets column with Transpose.
Sub LoopRow()
Dim rng As Range
Dim row As Range
Dim cel As Range
Dim i As Integer
Set rng = Worksheets("Name of sheet where data is").Range("A6:AI57")
i = 1
For Each row In rng.Rows
row.Copy
Worksheets("Name where you want your data to go").Cells(1, i).PasteSpecial Transpose:=True
i = i + 1
Next
End Sub
It will paste the data from 1st cell. You can change that by changing cells(2,i) for second and so on.
try this macro
Option Explicit
Sub TranPose_Range()
Dim rng As Range
'Source_sheet====>> name of sheet where the data is
'Target_sheet====>> name of sheet where you want your data to go
Set rng = Sheets("Source_sheet").Range("A6").CurrentRegion
rng.Copy
Sheets("Target_sheet").Cells(1, 1).PasteSpecial , Transpose:=True
End Sub
I have made a simple macro assigned to a hotkey to select the current region and then remove the header row. The problem is that the ranges we work with are often full of blank cells which prevent the selector from capturing the entire table dependant on the activecell.
I thought about maybe simply creating a loop, offsetting the ActiveCell and trying again until it hits an illegal range, but I have a bad feeling about this approach.
Sub multieditSelect()
Dim tbl As Range
If ActiveCell.Value = "" Then
MsgBox "Select a cell with something in it, you bastard"
Exit Sub
End If
Call startNoUpdates
Set tbl = ActiveCell.CurrentRegion
tbl.Offset(1, 0).Resize(tbl.Rows.Count - 1, _
tbl.Columns.Count).Select
Call endNoUpdates
Selection.Copy
End Sub
Is there a way to make this more reliable?
Edit: Let me add further complication/detail to this problem...
We work with a database and editing records en masse requires exporting them into excel, and the copy/pasting them back into the web interface, so it is common for us to be working with numerous tables of different size, using a worksheet like a notepad to store and modify them.
I want to create a sub that will select the current region irrespective of where it lies on the worksheet, quite possibly this is the third or fourth table to have been pasted onto the same sheet.
This makes going by the last column or last row too inflexible. CurrentRegion is ideal were it not for it's occasional failure to detect the table... so I suppose I need to build my own version of CurrentRegion that will overcome it's shortcomings.
Edit2: I've come up with a lazy solution.
Since these tables will always have a header, I'll just have the activecell offset up till it hits something, and hopefully that will be the header if an empty column is the starting point.
I think this will still be unreliable should there be a pocket of cells surrounded by empty cells in the middle of the table.
Sub multieditSelect2()
Dim tbl As Range
On Error GoTo errmsg
startNoUpdates
Do While ActiveCell.Value = ""
ActiveCell.Offset(-1, 0).Activate
Loop
startNoUpdates
Set tbl = ActiveCell.CurrentRegion
tbl.Offset(1, 0).Resize(tbl.Rows.Count - 1, _
tbl.Columns.Count).Select
endNoUpdates
Selection.Copy
Exit Sub
errmsg:
endNoUpdates
errMsgBox = MsgBox("Couldn't find a table!", vbCritical, "Error!")
End Sub
Edit3: Here is an example of where my code calls down:
I would like it to be able to capture the table even in this scenario where a cell in the test region is the activecell... but how?
Additional to my comment, see if this helps improve your logic (see comments in code for more details):
Sub multieditSelect()
Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets("Sheet1") 'use a variable for the sheet you want to use
Dim tbl As Range
Dim lRow As Long, lCol As Long
lRow = ws.Cells(Rows.Count, 1).End(xlUp).Row 'last row at column 1
lCol = ws.Cells(1, Columns.Count).End(xlToLeft).Column 'last column at row 1
Set tbl = ws.Range(ws.Cells(2, l), ws.Cells(lRow, lCol)) 'Set the range starting at row 2, column 1, until last row, last col
Call endNoUpdates(tbl) 'pass your range as a parameter if you require this specific range in your other sub
tbl.Copy Destination:=tbl.Offset(0, 20) 'copy 20 columns to the right
'Alternative
ws.Range("W1").Resize(tbl.Rows.Count, tbl.Columns.Count).Value = tbl.Value 'copy values to specific range
End Sub
Sub endNoUpdates(tbl As Range)
'do something with this range, i.e.:
Debug.Print tbl.address
End Sub
In reference to: Copy a row in excel if it matches a specific criteria into a new worksheet
I attempted applying the above hyperlink code to the needs of my own workbook. The only notable differences are: Object names, My data begins in "A2" instead of "A1", and my data is being copied to "L" column in a new worksheet instead of "A" column
Also... you can assume I have generated tabs in excel that correspond with each SelectCell.Value.
Sub Consolidate_Sheets()
Dim MyCell As Range
Dim MyRange As Range
Dim ws As Worksheet
Set MyRange = Sheets("Install_Input").Range("A2")
Set MyRange = Range(MyRange, MyRange.End(xlDown))
Call superSizeMe(MyCell, MyRange)
Sub superSizeMe(SelectCell As Range, SelectRange As Range)
Dim InstallInput As Worksheet
Dim strPasteToSheet As String
'New worksheet to paste into
Dim DestinationSheet As Worksheet
Dim DestinationRow As Range
'Define worksheet with input data
Set InstallInput = ThisWorkbook.Worksheets("Install_Input")
For Each SelectCell In SelectRange.Cells
InstallInput.Select
If SelectCell.Value <> "" Then
SelectCell.EntrieRow.Select ''''LOCATION OF RUN-TIME ERROR 438''''
Selection.Copy
Set DestinationSheet = Worksheets(SelectCell.Value)
Set DestinationRow = DestinationSheet.Range("L1:L" & DestinationSheet.Cells(Rows.Count, "L").End(xlUp).Row)
Range("L" & DestinationRow.Rows.Count + 1).Select
ActiveSheet.Paste
End If
Next SelectCell
InstallInput.Select
InstallInput.Cells(1, 1).Select
If IsObject(InstallInput) Then Set InstallInput = Nothing
If IsObject(SelectRange) Then Set SelectRange = Nothing
If IsObject(SelectCell) Then Set SelectCell = Nothing
If IsObject(DestinationSheet) Then Set DestinationSheet = Nothing
If IsObject(DestinationRow) Then Set DestinationRow = Nothing
End Sub
I am getting a Run-time error'438'
"Object doesn't support this property or method" on "SelectCell.EntireRow.Select"
Well your code has a typo
SelectCell.EntrieRow.Select
should say entire not Entrie. Personally I would use this method anyway, It selects the entire row based on the number you put in. FYI there is also a corresponding Columns().select if you need it in the future
sel_cell_row = SelectCell.Row
Rows(sel_cell_row).select
edit addressed to comment
The reason you get the 1004 error is like it says, the copy and paste areas don't match. Think of copying 10 rows, and trying to paste it into 2 rows, simply wouldn'y work. I'm guessing the problem actually stems from your destinationrows code. I'm not entirely sure what its trying to do, but here are two generic fixes
1)keep the copy code as it is, and modify the paste. Instead of selecting a range of cells to paste into, select the first cell (if your range was a1:a10, selecting a1 is sufficient) excel will then paste all the data starting at that first cell. so in your code do this
'comment out all this destination row stuff
'Set DestinationRow = DestinationSheet.Range("L1:L" & DestinationSheet.Cells(Rows.Count, "L").End(xlUp).Row)
'Range("L" & DestinationRow.Rows.Count + 1).Select
Range("L1").select 'only referencing the first cell to paste into
ActiveSheet.Paste
2)rather than selecting an entire row, why not select only the populated values in that row something like
sel_cell_row = SelectCell.Row
lastColumn = ActiveSheet.Cells(2, Columns.Count).End(xlToLeft).Column
range(Cells(sel_cell_row ,1),Cells(sel_cell_row ,lastColumn )).select
then do your copy as usual. the 1 is for column 1, or A. I'm assuming the data you want is in one row starting at column A and going till lastColumn. Maybe now this will match your destinationrows code.
3)Com,bine options 1 and 2. so copy only the populated cells, and paste to the first cell in the range
I'm tyring to look for a way to return a range of cells with just the lookup function. Is this really possible?
Basically like this:
=LOOKUP([MasterBook.xlsm]Sheet3!$A:$A,?)
I just want the function to look in the main workbook through all of Column A and return all cells for Column A that have something in them.
EDIT for poster below:
Sure. I have two workbooks; one workbook is essentially a local product that has a "master" sheet on top and then individual worksheets following it that have all of their information extracted from the master sheet. The second workbook is a local copy of a product that I send to a non-local entity higher up the food chain. Basically I need to pull information from the individual sheets in my first workbook and put it in the appropriate columns in the second workbook. I have a macro that gets the info from my sheets in the one workbook over to the other, but the second workbook is formatted differently. I was looking for a way to use a formula if possible.
The macro I am referring to is:
Sub CopyTest()
Dim sourceColumn As Range, targetColumn As Range
Set sourceColumn = Workbooks("Local Workbook.xlsm").Worksheets("Sheet3").Columns("A")
Set targetColumn = Workbooks("Nonlocal Workbook.xlsm").Worksheets("Sheet1").Columns("A")
sourceColumn.Copy Destination:=targetColumn
End Sub
All this does is pull the specified column from one sheet and put it in the column on the second book; but it just pastes it starting in the first block. Since the non-local book is formatted differently, the column I need to transfer to doesn't start until Row 9. shrug I have ideas abuot what I'm trying to do with this, but my ideas tend to exceed my technical ability (which occasionally makes it difficult to explain). :)
Depending on how different your workbooks are formatted. Here is two way to handle this:
Adapt your macro
Instead of copying the whole column, you can copy paste, only the values you want to.
Here is an example:
Sub CopyTest()
Dim rSource As Range, rTarget As Range
Dim lEnd As Long
lEnd = Range("A65536").End(xlUp).Row
Set rSource = Workbooks("Local Workbook.xlsm").Worksheets("Sheet3").Range("A1:A" & lEnd)
Set rTarget = Workbooks("Nonlocal Workbook.xlsm").Worksheets("Sheet1").Range("A9")
rSource.Copy Destination:=rTarget
End Sub
Use a formula
If your data are not in the same order, you'd better use a VLOOKUP formula.
See how it works.
Don't hesitate to post another question with what you've built for some help. Please give as much details as possible so we could help you the best way.
[EDIT] Another try following the comments
Option Explicit
Dim wTarget As Workbook
Sub mainCopy()
Dim bGo As Boolean
bGo = True
'Add a new workbook to copy the data - do you want the user to select one?
Set wTarget = Application.Workbooks.Add()
Do While bGo
CopyTest
bGo = MsgBox("Do you want to import data from another workbook?", vbYesNo, "Continue?")
Loop
End Sub
Sub CopyTest()
Dim rSource As Range, rTarget As Range
Dim lEnd As Long, lCol As Long
Dim ws As Worksheet
Dim vFile As Variant
vFile = Application.GetOpenFilename("Excel-files,*.xls", _
1, "Select One File To Open", , False)
'if the user didn't select a file, exit sub
If TypeName(vFile) = "Boolean" Then Exit Sub
Workbooks.Open vFile
For Each ws In ActiveWorkbook.Worksheets
'do you need to copy the columns separately?
' For lCol = 1 To 10
'find the last cell of the 10th column
lEnd = ws.Cells(65536, 10).End(xlUp).Row
Set rSource = ws.Range("A1:J" & lEnd)
'How can we define the target worksheet?
Set rTarget = wTarget.Worksheets("Sheet1").Range("A9")
rSource.Copy Destination:=rTarget
' Next lCol
Next ws
End Sub