I would like to copy a Cell from all worksheet but "Data" Worksheet on column C of "Data Worksheet". The following code is not working properly, always blank value. The value I would like to copy is placed on E16 Cell.
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "Data" Then
x = x + 1
Sheets("Data").Range("B1").Offset(x) = Worksheets(ws.Name).Cells(4, 16).Value
End If
Next ws
Try it that Way, without coping every value by it's own:
Sub m()
vartemp2 = Range("A1:A2")
vartemp2 = WorksheetFunction.Transpose(vartemp2)
Dim varTemp As Variant
For Each ws In Worksheets
If ws.Name <> "Data" Then
If i = 0 Then
ReDim varTemp(1 To 1, 1 To 1)
i = 1
Else
varTemp = WorksheetFunction.Transpose(varTemp)
ReDim Preserve varTemp(1 To UBound(varTemp) + 1)
varTemp = WorksheetFunction.Transpose(varTemp)
End If
varTemp(UBound(varTemp), 1) = ws.Cells(16, 5).Value
End If
Next ws
With Worksheets("Data")
.Range(.Cells(1, 2), .Cells(UBound(varTemp), 2)).Value = varTemp
End With
End Sub
BTW: On your code, 4 is column D not E. Columns start with 1 on counting and the defintion is Cells(RowNumber, ColumnNumber) :)
Copy Single Cell's Value From All Other Worksheets
Compact
Sub CopySingleCellValuesCompact()
Dim wb As Workbook: Set wb = ActiveWorkbook ' possibly use 'ThisWorkbook'
Dim dws As Worksheet: Set dws = wb.Worksheets("Data")
Dim dCell As Range: Set dCell = dws.Range("B1")
Dim sws As Worksheet
Dim sCell As Range
For Each sws In wb.Worksheets
If Not sws Is dws Then
Set sCell = ws.Range("E16")
Set dCell = dCell.Offset(1)
dCell.Value = sCell.Value
End If
Next sws
End Sub
Argumented
Now, to get rid of the magic numbers, you could create a method...
Sub CopySingleCellValues( _
ByVal wb As Workbook, _
ByVal DestinationWorksheetName As String, _
ByVal DestinationLastCellAddress As String, _
ByVal SourceCellAddress As String)
Dim dws As Worksheet: Set dws = wb.Worksheets(DestinationWorksheetName)
Dim dCell As Range: Set dCell = dws.Range(DestinationLastCellAddress)
Dim sws As Worksheet
Dim sCell As Range
For Each sws In wb.Worksheets
If Not sws Is dws Then
Set sCell = ws.Range(SourceCellAddress)
Set dCell = dCell.Offset(1)
dCell.Value = sCell.Value
End If
Next sws
End Sub
Usage
... and in your code, use it in the following way:
Sub MyCode()
Dim wb As Workbook: Set wb = ActiveWorkbook ' possibly use 'ThisWorkbook'
CopySingleCellValues wb, "Data", "B1", "E16"
End Sub
... and keep your code clean as a whistle.
It reads something like: in the given workbook, from all worksheets except worksheet Data, copy the value from cell E16 to worksheet Data, one below the other, starting with the first cell below B1.
Related
Hello all I did a macro in VBA that should check column D for the first empty cell then paste on that row but on column C, and when adding new info in the table it should take the first empty cell again, but it is replacing data, I don't check column C for first row because I have an filled cell midway, and if data were to replace that cell it should add a new row and avoid that.
`Sub CopyPasteToAnotherSheet()
Dim sourceRange As Range
Dim targetRange As Range
Dim lastRow As Long
Dim firstEmptyRow As Long
Set sourceRange = Selection
Set targetRange = Sheets("PARKING").Range("D18")
lastRow = targetRange.End(xlDown).Row
firstEmptyRow = Sheets("PARKING").Range("D" & lastRow).End(xlUp).Row + 1
If lastRow = targetRange.Row Then
targetRange.EntireRow.Insert
End If
If Sheets("PARKING").Range("C" & firstEmptyRow).Value <> "" Then
firstEmptyRow = firstEmptyRow + 1
End If
Set targetRange = Sheets("PARKING").Range("C" & firstEmptyRow)
sourceRange.Copy
targetRange.PasteSpecial xlPasteValues
End Sub
`
I have tried to work with different search ranges but it keeps overwriting data.
also if it would keep numbering the newly added rows when adding new data it would be great I am clueless on how I should do that
Append Values
Sub AppendValues()
Const PROC_TITLE As String = "Append Values"
Const DST_NAME As String = "PARKING"
Const DST_FIRST_CELL As String = "C18"
If Selection Is Nothing Then Exit Sub ' no visible workbooks open
If Not TypeOf Selection Is Range Then Exit Sub ' not a range
Dim srg As Range: Set srg = Selection
Dim sws As Worksheet: Set sws = srg.Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
If Not sws.Parent Is wb Then Exit Sub ' not in this workbook
Dim dws As Worksheet: Set dws = wb.Sheets(DST_NAME)
If sws Is dws Then Exit Sub ' src. and dst. are the same worksheet
If dws.FilterMode Then dws.ShowAllData ' '.Find' will fail if 'dws' filtered
Dim dfCell As Range: Set dfCell = dws.Range(DST_FIRST_CELL)
Dim dlCell As Range
Set dlCell = dws.UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If Not dlCell Is Nothing Then
Set dfCell = dfCell.Offset(dlCell.Row - dfCell.Row + 1)
End If
Dim sarg As Range
For Each sarg In srg.Areas
dfCell.Resize(sarg.Rows.Count, sarg.Columns.Count).Value = sarg.Value
Set dfCell = dfCell.Offset(sarg.Rows.Count)
Next sarg
MsgBox "Values appended to worksheet """ & DST_NAME & """.", _
vbInformation, PROC_TITLE
End Sub
I'm trying to create a macro that copies a certain range (CA1:CZ99) from "Sheet A" to lots of other sheets. The names of the other sheets are based on a value of column F in "Sheet B".
The code for copying the data is easy to find.
Worksheets("Sheet A").Range("CA1:CZ99").Copy Worksheets("Sheet X").Range("CA1")
But how do I loop this part over all the sheets from column F?
Copy a Range to Multiple Worksheets
Option Explicit
Sub CopyRange()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Source
Dim sws As Worksheet: Set sws = wb.Worksheets("Sheet A")
Dim srg As Range: Set srg = sws.Range("CA1:CZ99")
' Lookup
Dim lws As Worksheet: Set lws = wb.Worksheets("Sheet B")
Dim lfRow As Long: lfRow = 2
Dim llRow As Long: llRow = lws.Cells(lws.Rows.Count, "F").End(xlUp).Row
If llRow < lfRow Then Exit Sub ' no data
Dim lrg As Range: Set lrg = lws.Cells(lfRow, "F").Resize(llRow - lfRow + 1)
' Copy to Destination
Dim dws As Worksheet
Dim lCell As Range
Dim lCount As Long
For Each lCell In lrg.Cells
On Error Resume Next ' check if the worksheet exists
Set dws = wb.Worksheets(CStr(lCell.Value))
On Error GoTo 0
If Not dws Is Nothing Then ' the worksheet exists
lCount = lCount + 1
srg.Copy dws.Range("CA1")
Set dws = Nothing
'Else ' the worksheet doesn't exist
End If
Next lCell
' Inform
MsgBox "Range copied to " & lCount & " worksheets.", _
vbInformation, "CopyRange"
End Sub
Specify exactly where to get the data from as a variable, and then loop over it. Example:
Sub loopCopy()
Dim shtRng As Range
Dim c As Variant
Set shtRng = Worksheets("Sheet B").Range("F1:F5")
For Each c In shtRng
Worksheets("Sheet A").Range("CA1:CZ99").Copy Worksheets(c.Value).Range("CA1")
Next c
End Sub
This is a very basic setup. If the value from the column doesn't match a sheet, or if "Sheet A" or "Sheet B" change names, it will crash.
You might want to have the list adjust in size dynamically by finding last row, etc.
I've been wanting to copy the value but also the format and the cell color of the last non empty cell in column B, and past it in cell B1 in all the sheets.
Here is the code I used, but I always get an error.
Sub copypaste()
Dim wb As Workbook
Dim ws As Worksheet
Dim Lastcell As String
Application.ScreenUpdating = False
Set wb = ThisWorkbook
For Each ws In wb.Worksheets
Lastcell = ws.Cells(Rows.Count, "B").End(xlUp).Cell
Lastcell.Copy
ws.Range("B1").PasteSpecial Paste:=xlPasteFormats
ws.Range("B1").PasteSpecial Paste:=xlPasteValue
Next ws
Set wb = Nothing
End Sub
could you please help ?
Thanks in advance
Cell Copy in Multiple Worksheets
Option Explicit
Sub CopyPaste()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet
Dim sCell As Range ' Source Cell Range
Dim dCell As Range ' Destination Cell Range
Application.ScreenUpdating = False
For Each ws In wb.Worksheets
' Cells...
Set dCell = ws.Cells(1, "B")
Set sCell = ws.Cells(ws.Rows.Count, "B").End(xlUp)
' ... or Range...
'Set dCell = ws.Range("B1")
'Set sCell = ws.Range("B" & ws.Rows.Count).End(xlUp)
' Fastest (if it covers what you need)
dCell.Value = sCell.Value
dCell.NumberFormat = sCell.NumberFormat
dCell.Interior.Color = sCell.Interior.Color
' Fast
' sCell.Copy dCell
' dCell.Value = sCell.Value
' Slow (the selection changes)
' sCell.Copy
' dCell.PasteSpecial xlPasteValues
' dCell.PasteSpecial xlPasteFormats
Next ws
' Only for the Slow version:
'Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
You look to be declaring Lastcell as a string but treating it as a range. Something like this would work.
Sub copypaste()
Dim wb As Workbook
Dim ws As Worksheet
Dim Lastcell As Range
Application.ScreenUpdating = False
Set wb = ThisWorkbook
For Each ws In wb.Worksheets
Set Lastcell = ws.Cells(Rows.Count, "B").End(xlUp)
Lastcell.Copy
ws.Range("B1").PasteSpecial Paste:=xlPasteValues
ws.Range("B1").PasteSpecial Paste:=xlPasteFormats
Next ws
Set wb = Nothing
End Sub
The final code is this
Sub Unique_Values_Worksheet_Variables()
'1 Code + Sub splitByChars
Const Chars As Long = 4
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sws As Worksheet: Set sws = wb.Worksheets("export")
Dim dws As Worksheet:
Set dws = wb.Worksheets.Add(After:=wb.Sheets(wb.Sheets.Count))
sws.Range("C:C").AdvancedFilter _
Action:=xlFilterCopy, _
CopyToRange:=dws.Range("A:A"), _
Unique:=True
dws.Columns("A:J").EntireColumn.AutoFit
Dim rng As Range:
Set rng = dws.Range("A1:B1", dws.Cells(dws.Rows.Count, 1).End(xlUp))
rng.Borders(xlDiagonalDown).LineStyle = xlNone
rng.HorizontalAlignment = xlCenter
Unfortunately this was just focused on one part which has to be copied, the values for these columns were in another column so i try to switch the code
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sws As Worksheet: Set sws = wb.Worksheets("export")
Dim dws As Worksheet:
Set dws = wb.Worksheets.Add(After:=wb.Sheets(wb.Sheets.Count))
sws.Range("C:C").AdvancedFilter _
Action:=xlFilterCopy, _
CopyToRange:=dws.Range("A:A"), _
Unique:=True
to this. I used the macro reader for it.
Sub Test()
'
' Test Makro
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sws As Worksheet: Set sws = wb.ActiveSheet
Dim dws As Worksheet:
Set dws = wb.Worksheets.Add(After:=wb.Sheets(wb.Sheets.Count))
Application.ScreenUpdating = False
sws.Columns("C:C").AdvancedFilter Action:=xlFilterInPlace, Unique:=True
Columns("D:H").EntireColumn.Hidden = True
Columns("C:J").Select
Selection.Copy Destination:=dws.Range("A1")
End Sub
what works:
the code recognizes the part with the new worksheet dws.
it filters in sws the column C:C, what means
it also recognizes sws
what does not work:
by copy paste the range no values are hand over.
I have to use the advanced filter on C:C by avoiding duplicates, then i have data which i do not want to handover in column "D:I". The only thing what i want to hand over is column C & J. So i tried it with hiding the columns in between but it does not work.
Has anybody an idea?
i also tried it with .Delete what actually would be not that nice.
Is it a problem that i just assigned A1 for pasting it?
Selection.Copy Destination:=dws.Range("A1")
Copy Columns (Unique)
About Your Solution
Your solution is pretty cool. You probably meant to hide D:I though, which is a minor issue.
After hiding and filtering you might consider unhiding the columns and removing the filter to bring the source worksheet to the initial state.
I prefer using a worksheet with a name instead of ActiveSheet, but it's no big deal if you know what you're doing.
I don't like the references to the whole columns i.e. letting Excel (VBA) decide which range should be processed.
About the following
I first wrote the second code which is kind of more efficient but comes with the cost of not being able to control the order of the columns (due to Union) to be copied, hence the first code is recommended.
You can easily replace the source worksheet (Worksheets(sName)) with ActiveSheet if necessary.
It is assumed that the source data (table (one row of headers)) starts in cell A1. Otherwise, you may need to create the source range reference in a different way.
Adjust (play with) the values in the constants section.
Option Explicit
Sub copyColumnsUnique()
' Source
Const sName As String = "Sheet1"
Const sUniqueColumn As String = "C"
Const sCopyColumnsList As String = "C,J" ' exact order of the columns
' Destination (new worksheet)
Const dFirst As String = "A1"
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sCopyColumns() As String: sCopyColumns = Split(sCopyColumnsList, ",")
Dim dCell As Range: Set dCell = wb.Worksheets _
.Add(After:=wb.Sheets(wb.Sheets.Count)).Range(dFirst)
Application.ScreenUpdating = False
Dim srg As Range
With wb.Worksheets(sName).Range("A1").CurrentRegion
.Columns(sUniqueColumn).AdvancedFilter xlFilterInPlace, , , True
Dim n As Long
For n = 0 To UBound(sCopyColumns)
.Columns(sCopyColumns(n)).Copy dCell
Set dCell = dCell.Offset(, 1)
Next n
.Parent.ShowAllData
End With
Application.ScreenUpdating = True
End Sub
Sub copyColumnsUniqueAsc()
' Source
Const sName As String = "Sheet1"
Const sUniqueColumn As String = "C"
Const sCopyColumnsList As String = "C,J" ' forced ascending order of columns
' Destination (new worksheet)
Const dFirst As String = "A1"
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sCopyColumns() As String: sCopyColumns = Split(sCopyColumnsList, ",")
Application.ScreenUpdating = False
Dim srg As Range
With wb.Worksheets(sName).Range("A1").CurrentRegion
.Columns(sUniqueColumn).AdvancedFilter xlFilterInPlace, , , True
' Using 'Union' will force the resulting columns be in ascending order.
' If 'sCopyColumnsList' is "C,J,D", the order will be "C,D,J".
Dim n As Long
For n = 0 To UBound(sCopyColumns)
If srg Is Nothing Then
Set srg = .Columns(sCopyColumns(n))
Else
Set srg = Union(srg, .Columns(sCopyColumns(n)))
End If
Next n
End With
srg.Copy wb.Worksheets.Add(After:=wb.Sheets(wb.Sheets.Count)).Range(dFirst)
srg.Parent.ShowAllData
Application.ScreenUpdating = True
End Sub
Thanks to #Tragmor
for everyone who has same kind of problems, this could solve it
Sub Test()
'
' Test Makro
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sws As Worksheet: Set sws = wb.ActiveSheet
Dim dws As Worksheet:
Set dws = wb.Worksheets.Add(After:=wb.Sheets(wb.Sheets.Count))
Application.ScreenUpdating = False
With sws
.Columns("C:C").AdvancedFilter Action:=xlFilterInPlace, Unique:=True
.Columns("D:H").EntireColumn.Hidden = True
.Columns("C:J").Copy Destination:=dws.Range("A1")
End With
End Sub
my code aims to copy the same range from multiple sheets and paste the data from each sheet into the next empty column in a Combined sheet. My code copies from each sheet correctly, but pastes into the same column and overwrites the preceding paste.
Could someone please point out my error?
Many thanks!
Sub CopyToNextCol()
Dim Sh As Worksheet
Dim NextCol As Long
For Each Sh In ThisWorkbook.Worksheets
If Sh.Name <> "Master" And Sh.Name <> "Lists" And Sh.Name <> "Combined" Then
NextCol = Sheets("Combined").Cells(, Columns.Count).End(xlToLeft).Column + 1
Sh.Range("B2:B44").Copy Sheets("Combined").Cells(, NextCol)
End If
Next Sh
End Sub
Copy Same Ranges From Multiple Worksheets
The following example will copy the worksheet names ("I am planning to use a different column header" in the comments) in the first row and each range below it.
s - Source, d - Destination.
A Quick Fix
Option Explicit
Sub CopyToNextCol()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = wb.Worksheets("Combined")
Dim dCell As Range
Set dCell = dws.Cells(1, dws.Columns.Count).End(xlToLeft).Offset(, 1)
Dim sws As Worksheet
Dim srg As Range
For Each sws In wb.Worksheets
Select Case sws.Name
Case "Master", "Lists", "Combined"
' Skip (do nothing)
Case Else
Set srg = sws.Range("B2:B44")
dCell.Value = sws.Name
srg.Copy dCell.Offset(1)
Set dCell = dCell.Offset(, 1)
End Select
Next sws
'wb.Save
End Sub