I'm currently trying to copy text from my front sheet to a variant sheet.
What I want is to copy cells J19,J20,J21 to cells A1,B1,C1 of the different sheets. J19 decides which sheet to copy to as each agent has their own sheet which has a macro pulling the agent names into a data validation onto J19.
J19 = Agent Name
J20 = Holiday Start Date
J21 = Holiday End Date
How do I change Set wsDestin = Sheets("Agent1")so that it looks at J19 to decide the destination cell.
Sub CopyColumnP()
Dim wsSource As Worksheet
Dim wsDestin As Worksheet
Dim lngDestinRow As Long
Dim rngSource As Range
Dim rngCel As Range
Set wsSource = Sheets("Front")
Set wsDestin = Sheets("Agent1")
With wsSource
Set rngSource = .Range(.Cells(19, "J"), .Cells(.Rows.Count, "J").End(xlUp))
End With
For Each rngCel In rngSource
If rngCel.Value = "Design" Then
With wsDestin
lngDestinRow = .Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0).Row
rngCel.EntireRow.Copy Destination:=wsDestin.Cells(lngDestinRow, "A")
End With
End If
Next rngCel
End Sub
It's easy like this:
Set wsDestin = ThisWorkbook.Worksheets(wsSource.Range("J19").Value)
To check if the sheet exists end prevent errors use:
On Error Resume Next
Set wsDestin = ThisWorkbook.Worksheets(wsSource.Range("J19").Value)
If Not Err.Number = 0 Then
MsgBox "Sheet '" & wsSource.Range("A1").Value & "' not found."
Exit Sub
End If
On Error GoTo 0
Or if J19 doesn't contain the destination worksheet name but you need to select a worksheet based on J19's value then use:
Select Case wsSource.Range("J19").Value
Case "AAA" 'if value of J19 is AAA select sheet A
Set wsDestin = Sheets("A")
Case "B", "C" 'if value of J19 is B or C select sheet BC
Set wsDestin = Sheets("BC")
Case Else
MsgBox "no corresponding worksheet found."
End Select
Related
The following macro does everything it is designed for, EXCEPT the copy/paste portion. I am at a loss what correction/s to make.
The macro searches each sheet, specific column (either F or G), seeking any value greater than ZERO. If found, it should copy Cols B:F or B:G (depending on which column was searched) and paste those values to the appropriate worksheet.
Thank you for your assistance !
Option Explicit
Sub SampleCopy()
Dim ws As Worksheet
Dim c As Range
'On Error Resume Next
Application.ScreenUpdating = False
For Each ws In Worksheets
Select Case ws.Name
Case "In Stock", "To Order", "Sheet1"
'If it's one of these sheets, do nothing
Case Else
For Each c In Range("F15:F" & Cells(Rows.Count, 6).End(xlUp).Row)
If c.Value >= 1 Then
Range("B:G").Copy Sheets("In Stock").Cells(Rows.Count, 2).End(xlUp)(1) 'Edit sheet name
End If
Next c
For Each c In Range("G15:G50" & Cells(Rows.Count, 7).End(xlUp).Row)
If c.Value >= 1 Then
Range("B:G").Copy Sheets("To Order").Cells(Rows.Count, 2).End(xlUp)(1) 'Edit sheet name
End If
Next c
End Select
Next ws
Application.ScreenUpdating = True
End Sub
Download Example WB
Try this code. Pay attention to the explicit indication of the sheet ws.Range,ws.Cells and the need to fill in cells B14 on the sheets In Stock,To Order to correctly determine the last rows in the tables in case are they empty:
Option Explicit
Sub SampleCopy()
Dim ws As Worksheet
Dim c As Range, rngToCopy As Range
'On Error Resume Next
'Application.ScreenUpdating = False
For Each ws In Worksheets
Select Case ws.Name
Case "In Stock", "To Order", "Sheet1"
'If it's one of these sheets, do nothing
Case Else
For Each c In ws.Range("F15:F" & ws.Cells(Rows.Count, 6).End(xlUp).Row)
If c.Value > 0 Then
Set rngToCopy = Intersect(ws.Columns("B:G"), c.EntireRow)
If Not rngToCopy Is Nothing Then
rngToCopy.Copy Sheets("In Stock").Cells(Rows.Count, 2).End(xlUp)(2).Resize(, rngToCopy.Columns.Count) 'Edit sheet name
End If
End If
Next c
For Each c In ws.Range("G15:G" & ws.Cells(Rows.Count, 7).End(xlUp).Row)
If c.Value > 0 Then
Set rngToCopy = Intersect(ws.Columns("B:G"), c.EntireRow)
If Not rngToCopy Is Nothing Then
rngToCopy.Copy Sheets("To Order").Cells(Rows.Count, 2).End(xlUp)(2).Resize(, rngToCopy.Columns.Count) 'Edit sheet name
End If
End If
Next c
End Select
Next ws
Application.ScreenUpdating = True
End Sub
I have range of cells on Sheet2 F2:F41, which I want to paste into visible cells in Sheet1. Visible cells on Sheet1 are in Range M111:M643. My Problem is, Excel pastes it to another cells as I want.
Snippet for it:
Do I miss loop or something like this?
Sheets("Tabelle2").Select
Dim tgt As Worksheet
Set tgt = ThisWorkbook.Sheets("Tabelle1")
Dim from As Range
Dim destination As Range
Set from = Sheets("Tabelle2").Range("F2:F41") Selection.Copy
Set destination = Sheets("Tabelle1").Range("M11:M643").SpecialCells(xlCellTypeVisible) from.Copy Destination:=Sheets("Tabelle1").Range("M111")
I found this on the internet - I forget where (could have been stackoverflow) - but it should do what you are looking for. You may want to edit out the plethora of messages, I find them helpful to ensure I'm copying pasting the ranges I intended.
Public Sub Copy_Paste_Visible_Cells()
'This subroutine only handles copying visible cells in a SINGLE COLUMN
Dim RangeCopy As Range
Dim RangeDest As Range
Dim rng1 As Range
Dim dstRow As Long
Set RangeCopy = Application.InputBox("Select a range to copy ", "Obtain Range Object", Type:=8)
MsgBox "The range you selected to copy is " & RangeCopy.Address
Set RangeDest = Application.InputBox("Select range to paste onto ", "Obtain Range Object", Type:=8)
MsgBox "The range you have selected to paste onto is " & RangeDest.Address
If RangeCopy.Cells.Count > 1 Then
If RangeDest.Cells.Count > 1 Then
If RangeCopy.SpecialCells(xlCellTypeVisible).Count <> RangeDest.SpecialCells(xlCellTypeVisible).Count Then
MsgBox "Data could not be copied"
Exit Sub
End If
End If
End If
If RangeCopy.Cells.Count = 1 Then
'Copying a single cell to one or more destination cells
For Each rng1 In RangeDest
If rng1.EntireRow.RowHeight > 0 Then
RangeCopy.Copy rng1
End If
Next
Else
'Copying a range of cells to a destination range
dstRow = 1
For Each rng1 In RangeCopy.SpecialCells(xlCellTypeVisible)
Do While RangeDest(dstRow).EntireRow.RowHeight = 0
dstRow = dstRow + 1
Loop
rng1.Copy RangeDest(dstRow)
dstRow = dstRow + 1
Next
End If
Application.CutCopyMode = False
End Sub
Please try this code.
Sub copythis(ByRef rFrom As Range, ByRef rTo As Range)
Dim rVisible As Range
Set rVisible = rFrom.SpecialCells(xlCellTypeVisible)
rVisible.Copy destination:=rTo
End Sub
that should be called like:
Sub caller()
copythis "range with hidden to be copied", "range to receive"
End Sub
I have the following workbook called master:
Column I Column K
1234
1222
1111
I also have a workbook called slave:
Column J Column R
1234 Ambient
1222 Ambient
1111 Chiller
When the user enters/pastes the number in column I on my master workbook, i want to check if the same number exists in my slave workbook in column J.
If it does, i want to copy the corresponding prodcut groups from column R over to my master workbook in column K.
The other problem is my slave workbook changes name from time to time, but will always contain the word 'Depot memo' like so:
Food Depot Memo
Drinks Depot Memo 01-19
etc.
I am trying to reference my slave workbook by checking if the file name contains 'depot memo'.
For some reason this is not working. Please can someone show me where i am going wrong?
Code:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = True
Dim Dic As Object, key As Variant, oCell As Range, i As Long
Dim w1 As Worksheet, w2 As Worksheet
If Not Intersect(Target, Range("I:I")) Is Nothing Then ' <-- run this code only if a value in cell C5 has change
Application.EnableEvents = False
Set Dic = CreateObject("Scripting.Dictionary")
If Not Dic.exists(Target.Value) Then
Dic.Add Target.Value, Target.Offset(1, 0).Value
End If
Dim wbInd As Integer
Dim wb2 As Workbook
For wbInd = 1 To Workbooks.Count ' <-- loop through all open workbooks
If Workbooks(wbInd).Name Like "Depot Memo*" Then '<-- check if workbook name contains "volumes"
Set wb2 = Workbooks(wbInd)
Exit For
End If
Next wbInd
On Error GoTo message
Set w2 = wb2.Sheets(1)
With w2
i = .Cells(.Rows.Count, "J").End(xlUp).Row
End With
For Each oCell In w2.Range("J6:J" & i)
For Each key In Dic
If oCell.Value = key Then
Target.Offset(0, 2).Value = oCell.Offset(0, 8) '<-- put the the value in column F (offset 1 column) to cell C6 (one row offset)
End If
Next
Next
End If
Application.EnableEvents = True
Exit Sub
message:
Exit Sub
End Sub
EDIT:
With the suggested code from #user3598756 i encounter this problem:
If the user copy and pastes these values, rather than typing them, the correct supplier number does not correspond with the item number in column I.
This is obviously not correct, since it should have a different supplier number for each different item number.
edited to handle multiple changed cells
one thing that doesn't work as you'd expect is :
Like "Depot Memo*
that would not detect neither "Food Depot Memo" nor "Drinks Depot Memo 01-19"
while you have to use
Like "*Depot Memo*"
Furthermore:
there's no need for any Dictionary object
you don't need to iterate with For Each oCell In w2.Range("J6:J" & i)
so I'd go with the following refactoring of your code:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim oCell As Range, targetCell As Range
Dim ws2 As Worksheet
If Not Intersect(Target, Range("I:I")) Is Nothing Then ' <-- run this code only if a value in column I has changed
If Not GetWb("Depot Memo", ws2) Then Exit Sub
With ws2
For Each targetCell In Target
Set oCell = .Range("J1", .Cells(.Rows.count, "J").End(xlUp)).Find(what:=targetCell.Value, LookIn:=xlValues, lookat:=xlWhole)
If Not oCell Is Nothing Then
Application.EnableEvents = False
targetCell.Offset(0, 2).Value = oCell.Offset(0, 8)
Application.EnableEvents = True
End If
Next
End With
End If
End Sub
Function GetWb(wbNameLike As String, ws As Worksheet) As Boolean
Dim wb As Workbook
For Each wb In Workbooks
If wb.name Like "*" & wbNameLike & "*" Then '<-- check if workbook name contains "Depot Memo"
Set ws = wb.Worksheets(1)
Exit For
End If
Next
GetWb = Not ws Is Nothing
End Function
The wildcard in "Depot Memo*" name check should appear at the beginning AND the end of the text. This would detect if a workbook name contains any text before and/or after "Depot Memo".
If Workbooks(wbInd).Name Like "*Depot Memo*" Then
I have two worksheets . L12 Database and Working Sheet. I have a userform which copies rows of data from any sheet to range A393 of the working sheet. However I realised that I only need to copy certain column data of that row instead of the entire row. It is split into 3 ranges , L12 Database should copy Columns A:D, I:J, and L:R. This copied data should paste into the Working Sheet Columns A:D,E:F and I:O. A previous suggestion was to do a loop through but it was only applicable to two ranges. Hence I would need some help on how I can copy and paste to three ranges in one userform. This was a code done by a stackoverflow user (Sorry I do not remember your name) which is what I roughly want to do. Thanks!
Private Sub CommandButton1_Click()
Dim rngCopy As Range, rngPaste As Range
Dim wsCopy As Worksheet, wsPaste As Worksheet
Dim LngCounter As Long
If RefEdit1.Value <> "" Then
Set wsCopy = ThisWorkbook.Sheets(Replace(Split(RefEdit1.Value, "!")(0), "'", ""))
Set wsPaste = ThisWorkbook.Sheets("Working Sheet")
For LngCounter = 0 To 1
If LngCounter = 0 Then
Set rngCopy = wsCopy.Range(Split(RefEdit1.Value, "!")(1))
Set rngPaste = wsPaste.Range("A401")
Else
Set rngCopy = wsCopy.Range(Replace(Replace(Split(RefEdit1.Value, "!")(1), "A", "I"), "D", "R"))
Set rngPaste = wsPaste.Range("E401")
End If
If CheckBox1.Value = True Then
wsPaste.Activate
rngPaste.Select
rngCopy.Copy
ActiveSheet.Paste Link:=True
Else
rngCopy.Copy rngPaste
End If
Set rngPaste = Nothing
Set rngCopy = Nothing
Next
Else
MsgBox "Please select Input range"
End If
End Sub
This was the userform code I did previously:
Private Sub CommandButton1_Click()
Dim rngCopy As Range, rngPaste As Range
Dim wsCopy As Worksheet, wsPaste As Worksheet
If RefEdit1.Value <> "" Then
Set wsCopy = ThisWorkbook.Sheets(Replace(Split(RefEdit1.Value, "!")(0), "'", "")) 'Sheet name of the data selected by user
Set rngCopy = wsCopy.Range(Split(RefEdit1.Value, "!")(1)) 'Range of the data selected by user
Set wsPaste = ThisWorkbook.Sheets("Working Sheet") 'Sheet location where data copied would be pasted
Set rngPaste = wsPaste.Range("A393") 'Range Area where data copied would be pasted in columns A and B of database sheet
If CheckBox1.Value = True Then
wsPaste.Activate
rngPaste.Select
rngCopy.Copy
ActiveSheet.Paste Link:=True 'Activate paste link between info sheet and database sheet
Else
rngCopy.Copy rngPaste
End If
Else
MsgBox "Please select Input range" 'If user did not key in any input, this message wouldp pop up
End If
End Sub
edited: to fix "Solution A" Areas object handling. and added "rngPaste handling
I'll throw in two solutions
solution A
following your "scheme"
Option Explicit
Private Sub CommandButton1_Click()
Dim rngCopy As Range, rngPaste As Range, rngSelected As Areas '<~~ rngSelected is to be of "Areas" type
Dim wsCopy As Worksheet, wsPaste As Worksheet, wsActive As Worksheet
If RefEdit1.Value <> "" Then
Set rngSelected = Range(Replace(RefEdit1.Text, ";", ",")).Areas '<~~ store the selected range. Note:I had to use this Rpelace since my country customizations has addresses returned by RefEdit control Text property separed by a ";" instead of a ","
Set wsCopy = rngSelected.Parent.Parent '<~~ the parent property of Areas object returns a Range object, whose parent property eventually returns a worksheet object!
Set wsPaste = ThisWorkbook.Sheets("Working Sheet")
If Me.CheckBox1 Then '<~~ if requested...
Set wsActive = ActiveSheet ''<~~ ... store active sheet for eventually returning to it...
wsPaste.Select ''<~~ ... and activate "wsPaste" sheet once for all and avoid sheets jumping
End If
For Each rngCopy In rngSelected
Set rngPaste = Nothing '<~~ initialize rngPaste to Nothing, so that it's possible to detect its possible setting to a range if any check of Select Case block is successful
Select Case rngCopy.Columns.EntireColumn.Address(False, False) '<~~ check columns involved in each area
Case "A:D" '<~~ if columns range A to D is involved, then...
Set rngPaste = wsPaste.Range("A401") '<~~ ... have it pasted form wsPaste cell A401 on
Case "I:J" '<~~ if columns range I to J is involved, then...
Set rngPaste = wsPaste.Range("E401") '<~~ ... have it pasted form wsPaste cell E401 on
Case "L:R" '<~~ if columns range L to R is involved, then...
Set rngPaste = wsPaste.Range("I401") '<~~ ... have it pasted form wsPaste cell I401 on
End Select
If Not rngPaste Is Nothing Then '<~~ check to see if any rngPaste has been set
If Me.CheckBox1.Value Then
rngPaste.Select
rngCopy.Copy
ActiveSheet.Paste link:=True
Else
rngCopy.Copy rngPaste
End If
End If
Next rngCopy
If Me.CheckBox1 Then
wsActive.Select '<~~ if necessary, return to starting active sheet
End If
Else
MsgBox "Please select Input range"
End If
End Sub
solution B
I understand it simply suffices the user selects a single cell in a sheet and then you'll copy cells from relevant columns in that cell row and paste them into wsPaste sheet starting from corresponding cell addresses:
Private Sub CommandButton1_Click()
Dim rngSelected As Range, rngCopy As Range
Dim wsCopy As Worksheet, wsPaste As Worksheet, wsActive As Worksheet
If RefEdit1.Value <> "" Then
Set rngSelected = Range(Replace(RefEdit1.Text, ";", ",")).Areas(1).Cells(1, 1).EntireRow '<~~ store the selected range. Note:I had to use this Replace since my country customization has addresses returned by RefEdit control Text property separated by a ";" instead of a ","
Set wsCopy = rngSelected.Parent
Set wsPaste = ThisWorkbook.Sheets("Working Sheet")
If Me.CheckBox1 Then '<~~ if requested...
Set wsActive = ActiveSheet ''<~~ ... store active sheet for eventually returning to it...
wsPaste.Select ''<~~ ... and activate "wsPaste" sheet once for all and avoid sheets jumping
End If
Set rngCopy = Intersect(rngSelected, wsCopy.Columns("A:D"))
If Not rngCopy Is Nothing Then copyrng rngCopy, wsPaste.Range("A401"), Me.CheckBox1
Set rngCopy = Intersect(rngSelected, wsCopy.Columns("I:J"))
If Not rngCopy Is Nothing Then copyrng rngCopy, wsPaste.Range("E401"), Me.CheckBox1
Set rngCopy = Intersect(rngSelected, wsCopy.Columns("L:R"))
If Not rngCopy Is Nothing Then copyrng rngCopy, wsPaste.Range("I401"), Me.CheckBox1
If Me.CheckBox1 Then
wsActive.Select '<~~ if necessary, return to starting active sheet
End If
Else
MsgBox "Please select Input range"
End If
End Sub
Sub copyrng(rngCopy As Range, rngPaste As Range, okLink As Boolean)
If Not rngCopy Is Nothing Then
If okLink Then
rngPaste.Select
rngCopy.Copy
ActiveSheet.Paste link:=True
Else
rngCopy.Copy rngPaste
End If
End If
End Sub
of course, both solutions still can be optimized, for instance:
store both copying columns and corresponding pasting cells into arrays
this, to have a loop processing each "pair". so that in case your need will change again (and most probably they will...) you'll only have to add elements to the arrays while not changing code
add RefEdit return text validation
this control accepts anything typed from the user
so you may want to add a check that it's really returning a valid range
something like
If Not Range(RefEdit1.Text) Is Nothing Then... '<~~ if you expect only one selection
or
If Not Range(Range(Replace(RefEdit1.Text, ";", ",")).Areas) Is Nothing Then... '<~~ if you expect more then one selection
Good morning,
I'm attempting to copy data from multiple worksheets (in cells M78:078) into one, where the name in the column (L) of the summary sheet matches to the worksheet name (pasting into columns Z:AA in the summary sheet.
At present the below code is erroring out:
Sub Output_data()
Application.ScreenUpdating = False
For Each ws In ActiveWorkbook.Worksheets
If ActiveSheet.Range("L:L").Value = wkSht.Name Then
ws.Range("M78:O78").Copy
ActiveSheet.Range("L").CurrentRegion.Copy Destination:=wkSht.Range("Z:AA").Paste
End If
Next ws
Application.ScreenUpdating = True
End Sub
Any help would be great.
DRod
Something like this should work for you. I commented the code in an attempt to explain what it does.
Sub Output_data()
Dim wb As Workbook
Dim ws As Worksheet
Dim wsGet As Worksheet
Dim LCell As Range
Dim sDataCol As String
Dim lHeaderRow As Long
sDataCol = "L" 'Change to be the column you want to match sheet names agains
lHeaderRow = 1 'Change to be what your actual header row is
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Summary") 'Change this to be your Summary sheet
'Check for values in sDataCol
With ws.Range(sDataCol & lHeaderRow + 1, ws.Cells(ws.Rows.Count, sDataCol).End(xlUp))
If .Row <= lHeaderRow Then Exit Sub 'No data
'Loop through sDataCol values
For Each LCell In .Cells
'Check if sheet named that value exists
If Evaluate("ISREF('" & LCell.Text & "'!A1)") Then
'Found a matching sheet, copy M78:O78 to the corresponding row, column Z and on
Set wsGet = wb.Sheets(LCell.Text)
wsGet.Range("M78:O78").Copy ws.Cells(LCell.Row, "Z")
End If
Next LCell
End With
End Sub