Copy & Paste range into next available columns - excel

I have a range of data - B5:AG1004
In the macro, I need to copy this range and paste it in the next available column. The dedicated space for pasting begins in AX5.
In the code I have now, it copies and pastes the range into the desired (first) position, however once I click the command button again it re-pastes into the exact same place i.e. overwriting the original paste. I need the next iteration to paste in the next available cells to the right.
Here is my code so far;
Sub columnmacro()
ActiveSheet.Range("B5:AG1004").Copy
Sheets("Optimise").Range("ax5").End(xlToLeft).Offset(, 1).PasteSpecial xlValues
Application.CutCopyMode = False
End Sub
Hopefully someone can help, thanks!

Try this:
Sub SubColumnMacro()
'Declarations.
Dim RngSource As Range
Dim RngDestination As Range
'Setting variables.
Set RngSource = ActiveSheet.Range("B5:AG1004")
Set RngDestination = Sheets("Optimise").Range("AX5").Resize(RngSource.Rows.Count, RngSource.Columns.Count)
'Finding the next avaiable spot on the right to report RngSource values.
Do Until Excel.WorksheetFunction.CountBlank(RngDestination) = RngDestination.Cells.Count
Set RngDestination = RngDestination.Offset(0, 1)
Loop
'Reporting Rngsource values in RngDestination.
RngDestination.Value = RngSource.Value
End Sub

Related

Copy_Paste_Visible_Cells_Only

I have been trying to Copy the Filtered data and pasting the data on filtered cell but my code is not working.
I have data in Range Sheet2.Range("O2:O10000") and i filtered this range to Sheet2.Range("O173:O2400").
I want to copy the data from filtered cells Sheet2.Range("O173:O2400") then paste this data to visible cells on same Sheet2.Range("N173:N2400")
Please note there are multiple hidden rows in this range.
Any help will be appreciated
Sub Copy_Paste__Visible_Cells_Only()
Sheet2.Range("O173:O2400").SpecialCells(xlCellTypeVisible).Copy
Sheet2.Range("N173:N2400").SpecialCells(xlCellTypeVisible).Paste
End Sub
In this case, pasting won't work. As far as I know, you can't change the paste behaviour to only paste to visible cells.
When you select visible cells only, you get a collection of areas (you can think of them as a discontinuous set of ranges). Given you're just trying to move your visible data to the left, you can do it by looping through the areas and assigning their values to the same area in the previous column. Something like this:
Public Sub CopyVisible()
Dim a As Range
For Each a In Sheet1.Range("O4:O17").SpecialCells(xlCellTypeVisible).Areas
a.Offset(0, -1).Value = a.Value
Next
End Sub
The .Offset(0,-1) is signalling that you wish the values to be moved one column to the left
You can see from this example, when I filter on "a" in column O and run the macro, only the "a" values are moved to column N.
I would use a generic sub copyVisibleCellsToOtherColumn to which you pass the source-range and the target-start range.
Advantage you can re-use it for different scenarios.
Sub test_CopyVisibleCells()
Dim rgSource As Range
Set rgSource = sheet2.Range("O173:O2400")
Dim rgTarget As Range
Set rgTarget = sheet2.Range("N173:02400")
copyVisibleCells rgSource, rgTarget
End Sub
'this ist the generic sub
Public Sub copyVisibleCellsToOtherColumn(rgSource As Range, rgTarget As Range)
Dim c As Range, a As Range
For Each a In rgSource.Areas
'this will return the visible cells within rgsource
For Each c In a.Cells
rgTarget.Rows(c.Row).Value = c.Value
Next
Next
End Sub
I found code from somewhere which able to copy visible cells and paste into visible cells. For easy usage, I manually assign a shortcut ctrl+shift+C to call the macro.
Public Sub Copy_Range_Paste_Into_Visible_Cells()
'Sub Copy_Range_Paste_Into_Visible_Cells()
Dim rngSource As Range, rngDestination As Range, cell As Range, cc As Long, i As Long
On Error Resume Next
Application.DisplayAlerts = False
Set rngSource = Application.InputBox("Select the filtered range to copy. ", "Select Filtered Cells", Type:=8)
If rngSource Is Nothing Then Application.DisplayAlerts = True: Exit Sub 'User canceled
Set rngDestination = Application.InputBox("Select the destination cell to paste to. ", "Select Paste Destination", Type:=8)
If rngDestination Is Nothing Then Application.DisplayAlerts = True: Exit Sub 'User canceled
On Error GoTo 0
Application.DisplayAlerts = True
cc = rngSource.Columns.Count
For Each cell In rngSource.Columns(1).SpecialCells(xlCellTypeVisible)
Do Until Not rngDestination(1).Offset(i).EntireRow.Hidden
i = i + 1
Loop
rngDestination(1).Offset(i).Resize(1, cc).Value = cell.Resize(1, cc).Value
i = i + 1
Next
End Sub

Copying different ranges of cell data from one sheet to another

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.

How to pass on the value from a cell as an input to Range function?

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.

Copy and Paste special without selecting cell

The code I have runs but it does not do what I intend in the last line. The line at the end pastes the formula but it does not adjust the formula for the new cell.
As an example If the formula im copying is is A3 and the formula is A3=A1+A2, when it is pasted into A10 the formula is still A1+A2 instead of A9+A8.
I tried using paste special but I cannot get that to work. I do not want to select a new active cell as I will have to return back to the original active cell and reference it again.
Sub Macro1()
'
' Macro1 Macro
'
' Keyboard Shortcut: Ctrl+Shift+Z
'
Dim StartCell As Range
Dim copyRance As Range
Dim dataSheet As Worksheet
Dim destSheet As Worksheet
Set dataSheet = Sheets("Macro (insert data)")
Set destSheet = Sheets("Jun-2019")
Set StartCell = ActiveCell
Set copyRange = dataSheet.Range("G4:Q4")
ActiveCell.Resize(copyRange.Rows.Count, copyRange.Columns.Count).Value = copyRange.Value
Set copyRange = dataSheet.Range("W4:AG5")
destSheet.Range("C42").Resize(copyRange.Rows.Count, copyRange.Columns.Count).Value = copyRange.Value
Set copyRange = destSheet.Range("N10:X10")
StartCell.Offset(0, 11).Resize(copyRange.Rows.Count, copyRange.Columns.Count).Value = copyRange.Formula
End Sub
From comments, it seems that you want to copy the Formula, and then convert it to values. This needs to be done in 2 stages, optionally with an explicit .Calculate in case Calculation is set to Manual:
Set copyRange = dataSheet.Range("G4:Q4")
'Copy formulas to ActiveCell
copyRange.Copy Destination:=ActiveCell
With ActiveCell.Resize(copyRange.Rows.Count, copyRange.Columns.Count)
'Force the calculation
.Calculate
'Keep just the values
.Value = .Value
End With

In reference to "Copy a row in excel if it matches a specific criteria into a new worksheet"

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

Resources