Anyone have a macro to paste to multiple ranges in the same sheet?
Trying to get values into every other column'
Sub CopySelections()
Set cellranges = Application.Selection
Set ThisRng = Application.InputBox("Select a destination cell", "Where to paste slections?", Type:=8)
For Each cellrange In cellranges.Areas
cellrange.Copy ThisRng.Offset(i)
i = i + cellrange.Rows.CountLarge
Next cellrange
End Sub
Maybe this?
Sub Add_Spaces()
Dim ICount As Integer
Dim Sheet1 As Worksheet
Dim Sheet2 As Worksheet
Dim wb As Workbook
Set wb = ActiveWorkbook
Set Sheet1 = wb.Worksheets("Sheet1")
Set Sheet2 = wb.Worksheets("Sheet2")
Dim IStart As Integer
Dim copyz As Integer
Dim destinationz As Integer
ICount = Sheet1.Cells(1, Columns.Count).End(xlToLeft).Column
IStart = 1
destinationz = 1
For copyz = 1 To ICount Step IStart
Sheet1.Select
Columns(copyz).Select
Selection.Copy
Sheet2.Select
Columns(destinationz).Select
Sheet2.Paste
destinationz = destinationz + 2
Next copyz
End Sub
Before:
After:
Related
I have a simple loop that should copy ranges form three sheets and stack them on top of each other in another sheet. I define the ranges of each of the three sheets via a cell that counts rows in the Control Sheet.
I do not get an error message, however only the range of the first sheets gets pasted. I troubleshooted already to see if the loop is running until end and indeed it does. I cannot wrap my head around why only the range from the first sheets gets pasted in the final sheet.
Sub Loop()
Dim ws_Sheet As Worksheet, ws As Worksheet
Dim lng_LastRow As Long, lng_LastColumn As Long, lng_LastRowSheet As Long
Dim rng_WorkRange As Range
Dim arrSht, i
Dim counter As Integer
arrSht = Array("a", "b", "c")
Set ws_Sheet = Worksheets("d")
ws_Sheet.Cells.ClearContents
counter = 1
For i = 0 To 2
Set ws = Worksheets(arrSht(i))
lng_LastRow = Worksheets("Control").Range("E" & counter).Value + 1
lng_LastColumn = ws.Cells(1, Columns.Count).End(xlToLeft).Column
lng_LastRowSheet = ws_Sheet.Cells(Rows.Count, 1).End(xlUp).Row
Set rng_WorkRange = ws.Range(ws.Cells(1, 1), ws.Cells(lng_LastRow, lng_LastColumn))
rng_WorkRange.Copy ws_Sheet.Range("A" & lng_LastRowSheet)
counter = counter + 1
Next i
End Sub
The issue is
lng_LastRowSheet = ws_Sheet.Cells(Rows.Count, 1).End(xlUp).Row
is the last used row (the last row that has data).
And then you use that to start pasting
rng_WorkRange.Copy ws_Sheet.Range("A" & lng_LastRowSheet)
so you overwrite the last row of data!
The next free row is lng_LastRowSheet + 1 so you should paste there:
rng_WorkRange.Copy ws_Sheet.Range("A" & (lng_LastRowSheet + 1))
You can also see that in the debug data:
a $A$1:$B$338 to A1
b $A$1:$B$91 to A338
c $A$1:$B$356 to A428
a goes from A1:B338 but you start pasting b in A338 so it overwrites the last row of a.
I gave it a test:
Created worksheet Control with data like
Then created worksheets a, b and c like
with data until row 500 so there is enough.
Then created an empty worksheet d for the output.
And used the following code. Note I have optimized it so it uses meaningful variable names, which is much easier to read, understand and debug.
Option Explicit
Public Sub CopyData()
Dim SheetNames() As Variant
SheetNames = Array("a", "b", "c")
Dim wsDestination As Worksheet
Set wsDestination = ThisWorkbook.Worksheets("d")
wsDestination.Cells.ClearContents
Dim i As Long
For i = 0 To 2
Dim wsSource As Worksheet
Set wsSource = ThisWorkbook.Worksheets(SheetNames(i))
Dim SourceLastRow As Long
SourceLastRow = ThisWorkbook.Worksheets("Control").Range("E" & i + 1).Value + 1
Dim SourceLastColumn As Long
SourceLastColumn = wsSource.Cells(1, wsSource.Columns.Count).End(xlToLeft).Column
Dim DestinationFreeRow As Long
DestinationFreeRow = wsDestination.Cells(wsDestination.Rows.Count, 1).End(xlUp).Row + 1 ' Last used row +1
Dim SourceRange As Range
Set SourceRange = wsSource.Range(wsSource.Cells(1, 1), wsSource.Cells(SourceLastRow, SourceLastColumn))
SourceRange.Copy wsDestination.Range("A" & DestinationFreeRow)
Next i
End Sub
And I get a perfect output like:
Note that in the output I have hidden some rows so you can see eveything is there. This code perfectly does what it is supposed to.
Stack Ranges (Vertically) From Multiple Worksheets
Sub StackRanges()
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Source
Dim sWorksheetNames() As Variant: sWorksheetNames = VBA.Array("a", "b", "c")
' Lookup (Source Last Row)?
Dim lws As Worksheet: Set lws = wb.Worksheets("Control")
Dim llrCell As Range: Set llrCell = lws.Range("E1")
' Destination
Dim dws As Worksheet: Set dws = wb.Worksheets("d")
dws.UsedRange.ClearContents
Dim dfCell As Range: Set dfCell = dws.Range("A1")
Dim sws As Worksheet
Dim srg As Range
Dim slRow As Long
Dim slColumn As Long
Dim i As Long
' Loop.
For i = 0 To UBound(sWorksheetNames)
Set sws = wb.Worksheets(sWorksheetNames(i))
slRow = llrCell.Value + 1
slColumn = sws.Cells(1, sws.Columns.Count).End(xlToLeft).Column
Set srg = sws.Range("A1", sws.Cells(slRow, slColumn))
srg.Copy dfCell
' If you only need to copy values (since you're using '.ClearContents'),
' instead, use the most efficient:
'dfCell.Resize(srg.Rows.Count, srg.Columns.Count).Value = srg.Value
Set llrCell = llrCell.Offset(1) ' next source last row lookup cell
Set dfCell = dfCell.Offset(srg.Rows.Count) ' next first dest. cell
Next i
End Sub
The counter and the lng_lastRow variable is too messy.
I repaleced some code as follow:
Sub newLoop()
Dim ws_Sheet As Worksheet, ws As Worksheet
Dim lng_LastRow As Long, lng_LastColumn As Long, lng_LastRowSheet As Long
Dim rng_WorkRange As Range, rng_lastRange As Range
Dim arrSht, i
Dim counter As Integer
arrSht = Array("a", "b", "c")
Set ws_Sheet = Worksheets("Control")
ws_Sheet.Cells.ClearContents
For i = 0 To 2
Set ws = Worksheets(arrSht(i))
Set rng_lastRange = ws_Sheet.Cells(Rows.Count, 1).End(xlUp)
lng_LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
lng_LastColumn = ws.Cells(1, Columns.Count).End(xlToLeft).Column
Set rng_WorkRange = ws.Range(ws.Cells(1, 1), ws.Cells(lng_LastRow, lng_LastColumn))
rng_WorkRange.Copy rng_lastRange.Offset(1, 0)
Next i
End Sub
I have a worksheet with sales data, I've managed to create Autofilter based on department and copied the results into the new sheet (Output). What I'm trying to achieve is that code will multiply the results of respective month by value in "Adjustment" row.
So the result is following
Is there a way how to process calculations within my code or I shall multiply each column in different Sub afterwards?
Dim Last_Row As Long
Dim DbExtract, DuplicateRecords As Worksheet
Dim WKS2 As Worksheet
Dim rn As Range
Set DbExtract = ThisWorkbook.Sheets("Data")
Set DuplicateRecords = ThisWorkbook.Sheets("Output")
Set WKS2 = ThisWorkbook.Sheets("Dashboard")
iMultiplier = WKS2.Range("Z18")
Application.ScreenUpdating = False
Last_Row = DuplicateRecords.Range("A" & Rows.Count).End(xlUp).Row + 1
DbExtract.Range("C3:R1500").SpecialCells(xlCellTypeVisible).Copy
DuplicateRecords.Range("A" & Last_Row).PasteSpecial
DuplicateRecords.Range("$A$1:$P$400").AutoFilter Field:=3, Criteria1:=WKS2.Range("V2")
Set rn = DuplicateRecords.Range("G2:G500").SpecialCells(xlCellTypeVisible)
For Each cell In rn
iNewnumber = cell * iMultiplier
Next cell
End Sub
Here's an example:
Sub Tester()
Dim lastRow As Long, wb As Workbook
Dim wsData As Worksheet, wsOutput As Worksheet
Dim wsDash As Worksheet, rngVis As Range, numVisRows As Long
Dim rn As Range, rngAdj As Range, m As Long, adj, c As Range
Set wb = ThisWorkbook
Set wsData = wb.Sheets("Data") 'consistent naming helps...
Set wsOutput = wb.Sheets("Output")
Set wsDash = wb.Sheets("Dashboard")
'iMultiplier = wsDash.Range("Z18") '?
Application.ScreenUpdating = False
Set rngVis = wsData.Range("C3:R1500").SpecialCells(xlCellTypeVisible)
numVisRows = rngVis.Cells.Count / rngVis.Columns.Count
rngVis.Copy
lastRow = wsOutput.Range("A" & Rows.Count).End(xlUp).Row + 1 'start of pasted data
wsOutput.Range("A" & lastRow).PasteSpecial
Set rngAdj = wsDash.Range("C5:N5") 'for example
For m = 1 To rngAdj.Columns.Count 'loop the cells in the adjustments range
adj = rngAdj.Cells(m).Value 'adjustment value
If Len(adj) > 0 And IsNumeric(adj) Then 'have an adjustment to make?
'loop the relevant cells in the pasted data
For Each c In wsOutput.Cells(lastRow, "A").Offset(0, 2 + m).Resize(numVisRows).Cells
If Len(c.Value) > 0 And IsNumeric(c.Value) Then 'any thing to adjust?
c.Value = c.Value * adj
End If
Next c
End If
Next m
End Sub
I have two worksheets. In one worksheet named "Equipment details" I have a set of values in column A, rows 13 to 1000. I want to copy each of these values, namely A13, A14, A15 and so forth in to another worksheet named "Workshet(2)" starting at cell A2. However, the trick is A13 from the first worksheet needs to be copied into A2 of the second worksheet, A14 to A8, A15 to A14 and so on in increments of 6 each time. The following is my code but it does not work. It copies the first record from A13 to A2 but then goes all awry. Please help!
Sub CopyData2()
Dim wb As Workbook
Set wb = ThisWorkbook
Dim srcws As Worksheet
Set srcws = wb.Worksheets("Equipment details")
Dim destws As Worksheet
Set destws = wb.Worksheets("Worksheet (2)")
Dim frstRec As Long
Dim k As Integer
Dim SrcRowNo As Integer
Dim DestRowNo As Integer
Dim myRange As Range
Set myRange = destws.Range("a2")
'Source sheet starting row
SrcRowNo = 13
'Destination sheet starting row
DestRowNo = 2
'Copy and paste first record into destination sheet
srcws.Cells(SrcRowNo, 1).Copy Destination:=destws.Cells(DestRowNo, 1)
frstRec = myRange.Row
For SrcRowNo = 13 To 50
For frstRec = 2 To 50
srcws.Cells(SrcRowNo + 1, 1).Copy Destination:=destws.Cells(frstRec, 1)
Next frstRec
Next SrcRowNo
End Sub
Sub CopyData2()
Dim wb As Workbook
Set wb = ThisWorkbook
Dim srcws As Worksheet
Set srcws = wb.Worksheets("Equipment details")
Dim destws As Worksheet
Set destws = wb.Worksheets("Worksheet (2)")
Dim RowNo As Long
For RowNo = 0 To 987
srcws.Cells(RowNo + 13, 1).Copy Destination:=destws.Cells(RowNo*6 + 2, 1)
Next RowNo
End Sub
Option Explicit
Sub CopyData2()
Dim wb As Workbook, wsSrc As Worksheet, wsDest As Worksheet
Dim t0 As Single: t0 = Timer
Set wb = ThisWorkbook
Set wsSrc = wb.Worksheets("Equipment details")
Set wsDest = wb.Worksheets("Worksheet (2)")
' copy A13->A2, A14->A8, A15->A14
Const INCR = 6
Const START_ROW = 13
Const END_ROW = 1000
Dim arSrc, arDest, i As Long, j As Long
arSrc = wsSrc.Range("A" & START_ROW & ":A" & END_ROW).Value2
arDest = wsDest.Range("A2:A" & INCR * UBound(arSrc)).Value2
For i = 1 To UBound(arSrc)
j = 1 + (i - 1) * INCR
arDest(j, 1) = arSrc(i, 1)
Next
wsDest.Range("A2").Resize(UBound(arDest)) = arDest
MsgBox "Done", vbInformation, Format(Timer - t0, "0.0 secs")
End Sub
I have the working code below that copies filtered data to filtered cells when I select data from one column.
When I try a range of multiple columns it copies the data back in a single column and pastes is like so: column1V1, column1V2, column1V3, etc
How can I paste the filtered data in the same order/format in other columns?
Sub Filtered_Cells()
Dim from As Range
Set from = Application.InputBox("Select range to copy selected cells to", Type:=8)
from.Select
Selection.SpecialCells(xlCellTypeVisible).Select
Call Copy_Filtered_Cells
End Sub
Sub Copy_Filtered_Cells()
Set from = Selection
Set too = Application.InputBox("Select range to copy selected cells to", Type:=8)
For Each Cell In from
Cell.Copy
For Each thing In too
If thing.EntireRow.RowHeight > 0 Then
thing.PasteSpecial
Set too = thing.Offset(1).Resize(too.Rows.Count)
Exit For
End If
Next
Next
End Sub
Would this work for you?
Sub Copy_Filtered_Cells_New()
Dim from As Range, too As Range, fromRng As Range
Set from = Application.InputBox("Select range to copy cells from", Type:=8)
Set too = Application.InputBox("Select range to paste cells to", Type:=8)
Dim ws As Worksheet: Set ws = from.Worksheet
Dim arrRanges() As String: arrRanges = Split(from.SpecialCells(xlCellTypeVisible).address, ",")
Dim R As Long, X As Long, nextVisRow As Long
For X = LBound(arrRanges) To UBound(arrRanges) 'For each visible range
Set fromRng = ws.Range(arrRanges(X))
With fromRng
For R = 1 To .Rows.Count 'For each row in the selected range
nextVisRow = NextVisibleRow(too.Cells(1, 1)) 'Get the next visible row for paste
too.Offset(nextVisRow - too.row).Resize(1, .Columns.Count).Value = .Offset(R - 1).Resize(1, .Columns.Count).Value
Set too = too.Offset(nextVisRow - too.row + 1)
Next R
End With
Next X
End Sub
Function NextVisibleRow(rng As Range) As Long
Dim ws As Worksheet: Set ws = rng.Worksheet
Dim R As Long: R = rng.Cells(1, 1).row
Do While True
If Not ws.Rows(R).EntireRow.Hidden Then
NextVisibleRow = R
Exit Do
End If
R = R + 1
Loop
End Function
Thanks to the user FAB i was able to further develop the macro. Now it copies without any limitations or problems any range of visible cells to any visible data. The problem was the array not being able to "record" more then 18-or-so elements. I used the trick of copying the user-selected data to a new sheet, which could be attributed successfully to the array.
Here is the finished code.
Public copyRng As Range
Public wb As Workbook
Sub Copy_Paste_Filtered_Data()
Copy
Dim from As Range, too As Range, fromRng As Range
Set from = copyRng
Set too = Application.InputBox("Select range to paste cells to", Type:=8)
Dim ws As Worksheet: Set ws = from.Worksheet
Dim arrRanges() As String: arrRanges = Split(from.SpecialCells(xlCellTypeVisible).Address, ",")
Dim R As Long, X As Long, nextVisRow As Long
For X = LBound(arrRanges) To UBound(arrRanges) 'For each visible range
Set fromRng = ws.Range(arrRanges(X))
With fromRng
For R = 1 To .Rows.Count 'For each row in the selected range
nextVisRow = NextVisibleRow(too.Cells(1, 1)) 'Get the next visible row for paste
too.Offset(nextVisRow - too.Row).Resize(1, .Columns.Count).Value = .Offset(R - 1).Resize(1, .Columns.Count).Value
Set too = too.Offset(nextVisRow - too.Row + 1)
Next R
End With
Next X
wb.Activate
Application.DisplayAlerts = False
Sheets("Temp").Delete
Application.DisplayAlerts = True
End Sub
Function NextVisibleRow(rng As Range) As Long
Dim ws As Worksheet: Set ws = rng.Worksheet
Dim R As Long: R = rng.Cells(1, 1).Row
Do While True
If Not ws.Rows(R).EntireRow.Hidden Then
NextVisibleRow = R
Exit Do
End If
R = R + 1
Loop
End Function
Public Function Copy()
Dim ws As Worksheet
Set wb = Workbooks("PERSONAL.XLSB")
Set copyRng = Application.InputBox("Select range to copy cells from", Type:=8)
copyRng.Select
Selection.Copy
With wb
Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count))
ws.Name = "Temp"
End With
wb.Activate
Range("A1").Select
ActiveSheet.Paste
Set copyRng = Selection
End Function
This uses the "PERSONAL.XLSB" workbook, so be sure to record in it a macro first, to activate it, before using this Macro
I have two separate Excel files. In one of these in Sheet1 is stored infomration about orders and order numbers. Now every time I make a new order I want this information be collected from my order and inserted in to so called "database" workbook. It should identify the last empty row in column A:A in C:\Users\user\Desktop\Order_number.xlsx and insert new values from range ("C6,C17,C10,H18,B32,G32,H6,H9") to the next empty row. Here is the code I came up to but there is some mistake and it is not working. How it can be fixed?
Sub TransferValues465()
Dim wsMain As Worksheet: Set wsMain = ThisWorkbook.ActiveSheet
Dim wsData As Worksheet: Set wsData = Workbooks.Open("C:\Users\user\Desktop\Order_number.xlsx").Sheets("Sheet1")
Dim rngToCopy As Range: Set rngToCopy = wsMain.Range("C6,C17,C10,H18,B32,G32,H6,H9")
Dim c As Long
Dim ar As Range
Dim cl As Range
Dim LastRow As Long
Dim rngDestination As Range
With Application
.DisplayAlerts = False
.ScreenUpdating = False
.EnableEvents = False
End With
'Get the last row in Database sheet:
LastRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
Set rngDestination = wsData.Cells(LastRow + 1, 1).Resize(1, 25).Offset(0, 0)
For Each ar In rngToCopy.Areas
For Each cl In ar
c = c + 1
'I used this next line for testing:
' rngDestination.Cells(c).Value = cl.Address
rngDestination.Cells(c).Value = cl.Value
Next
Next
End Sub
A few corrections:
1) Set wsData = Workbooks("C:\Users\user\Desktop\Order_number.xlsx").Sheets("Sheet1") will not work. Either use Set wsData = Workbooks("Order_number.xlsx").Sheets("Sheet1") if the workbook is open. Or you need to open the workbook first.
2) I am not famliar on using Application.WorksheetFunction.CountA(wsData.Range("A:A")) to get the last row. To get the last row in Column A (with the possibility of skipping balnk cells in the middle) use wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row.
3) My preference is to use Copy >> PasteSpecial xlPasteValues with cl.Copy and the following line wsData.Range("A" & C).PasteSpecial xlPasteValues.
Code
Option Explicit
Sub TransferValues465()
Dim wsMain As Worksheet
Dim wbData As Workbook
Dim wsData As Worksheet
Dim rngToCopy As Range
Dim C As Long
Dim ar As Range
Dim cl As Range
Dim LastRow As Long
Dim rngDestination As Range
Set wsMain = ThisWorkbook.ActiveSheet
Application.DisplayAlerts = False
' you need to open the workbook
Set wbData = Workbooks.Open("C:\Users\user\Desktop\Order_number.xlsx")
Set wsData = wbData.Sheets("Sheet1")
Set rngToCopy = wsMain.Range("C6,C17,C10,H18,B32,G32,H6,H9")
'Get the last row in Database sheet:
LastRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
C = 1
For Each cl In rngToCopy
cl.Copy
wsData.Cells(LastRow + 1, C).PasteSpecial xlPasteValues
C = C + 1
Next cl
wbData.Close True '<-- close and save the changes made
Application.DisplayAlerts = True '<-- restore settings
End Sub