Excel Macro working different worksheet - vba

Sub CopyPaste()
'
' CopyPaste Macro
'
' Keyboard Shortcut: Ctrl+Shift+P
'
Range("A2:C5").Select
Selection.Copy
Sheets("A").Select
Range("A2").Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Range("A6:C11").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("B").Select
Range("A2").Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Range("A12:C17").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("C").Select
Range("A2").Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Range("A18:C21").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("D").Select
Range("A2").Select
ActiveSheet.Paste
End Sub
I have trying making a Macro to do a basic task but I can't seem to figure it out, can anyone help please! I'm trying to create a macro that will copy data from one worksheet and place into another worksheet based on specific letter.
For example all "A" item will paste automatically into new worksheet name "A". This I can do with no problem. But, when I want to use the same macro with another row with different no of column is where I have my problem.
I already use recorded macro and then if the row from copy worksheet have been reduced, it will paste wrongly in new worksheet.
Is there any way to solve it?
thanks in advance.
P/S--> the new worksheet will have header in it. so it would be nice if they can paste start from A2 row. Can refer image below for example.

See Example / and see comment on the code
Option Explicit
Public Sub Example()
'Declare your Variables
Dim Sht As Worksheet
Dim rng As Range
Dim List As Collection
Dim varValue As Variant
Dim i As Long
With ThisWorkbook
'Set your Sheet name
Set Sht = ActiveWorkbook.Sheets("Sheet1")
'set your auto-filter, A1
With Sht.Range("A1")
.AutoFilter
End With
'Set your agent Column range # (1) that you want to filter it
Set rng = Range(Sht.AutoFilter.Range.Columns(1).Address)
'Create a new Collection Object
Set List = New Collection
'Fill Collection with Unique Values
On Error Resume Next
For i = 2 To rng.Rows.Count
List.Add rng.Cells(i, 1), CStr(rng.Cells(i, 1))
Next i
'Start looping in through the collection Values
For Each varValue In List
'Filter the Autofilter to macth the current Value
rng.AutoFilter Field:=1, Criteria1:=varValue
'Copy the AutoFiltered Range to new Workbook
Sht.AutoFilter.Range.Copy
Worksheets.Add.Paste
ActiveSheet.Name = Left(varValue, 30)
Next ' Loop back
'Go back to main Sheet and removed filters
Sht.AutoFilter.ShowAllData
Sht.Activate
End With
End Sub
Make sure to have header on your data, see below

Related

VBA: how to avoid copying table headers from multiple sheets?

Trying to combine multiple excel sheets is there a way to modify the below so that it does not copy table headers from the other sheets into a sheet called "Combined"?
Sub Combine()
'UpdatebyExtendoffice
Dim J As Integer
On Error Resume Next
Sheets(1).Select
Worksheets.Add
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A1").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Next
End Sub
Quick rewrite and introducing some variables to hold the new sheet and copy range which should help for debugging.
This also incorporates the "skip two header rows" requirement:
Sub Combine()
Dim J As Integer
'Set the newly added sheet to a variable so we can reference.
Dim CombineSheet as Worksheet
Set CombineSheet = Worksheets.Add
CombineSheet.Name = "Combined"
'Assume you are copying the header here. It's a
' little risky hoping that Sheets(2) is going
' to be the one you want.
'Furthermore, getting rid of select/activate
' stuff. Instead directly say which sheet and
' range you want to copy and its destination.
Sheets(2).Range("A1").EntireRow.Copy Destination:=CombineSheet.Range("A1")
'Introducing a new variable to hold the range that will be copied
Dim copyRange as Range
For J = 2 To Sheets.Count
'Cutting out the activates and selects here
Set copyRange = Sheets(J).Range("A1").CurrentRegion
'Offset it and resize skipping 2 header rows and resizing the whole
' range to be 2 rows smaller (the 2 rows we just skipped)
copyRange = copyRange.Offset(2).Resize(copyRange.Rows.Count - 2)
'Copy/Paste
copyRange.Copy Destination:=CombineSheet.Range("A65536").End(xlUp)
Next
End Sub
The biggest change here, besides the removal of the .Select and .Activate is just offsetting by 2 rows and then resizing that range by -2 rows to accommodate that offset.
Try the next updated code, please:
Sub CombineSheets()
Dim J As Long, sh As Worksheet
Worksheets.Add Before:=Sheets(1)
Sheets(1).Name = "Combined"
Sheets(2).Range("A1").EntireRow.Copy Destination:=Sheets(1).Range("A1")
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> Sheets(1).Name Then
sh.Range("A1").CurrentRegion.Offset(2).Resize(sh.Range("A" & sh.rows.Count).End(xlUp).row - 1).Copy _
Destination:=Sheets(1).Range("A" & sh.rows.Count).End(xlUp)(2)
End If
Next
End Sub
Selecting, activating only consume Excel resources and make the code slower...

VBA Excel - Need to copy a range, paste it in a column then loop

I have a long column of words, need to copy and paste the first 30 or so into a column on another sheet, then paste the next 30 in the following column, etc.
I recorded the start of a macro, but have no idea how to make it do the whole thing without writing each bit out individually.
Sub asdasd()
'
Range("A2:A29").Select
Selection.Copy
Sheets("COMMON WORDS").Select
Range("AG2").Select
ActiveSheet.Paste
Sheets("COMMON - SINGLE LIST").Select
Range("A30").Select
Range("A30,A57").Select
Range("A57").Activate
Range("A30:A57").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("COMMON WORDS").Select
Range("AH2").Select
ActiveSheet.Paste
End Sub
Sub LoopCopy()
Dim rngCopy As Range, rngPaste As Range
Set rngCopy = Sheets("COMMON - SINGLE LIST").Range("A2:A29")
Set rngPaste = Sheets("COMMON WORDS").Range("AG2")
'copy while there's data in rngCopy...
Do while application.counta(rngCopy) > 0
rngCopy.copy rngPaste
set rngCopy = rngCopy.offset(rngCopy.rows.count, 0) '<< move copy range
set rngPaste = rngPaste.offset(0, 1) '<< move paste postion over
Loop
End Sub

Copy filtered data to another sheet using VBA

I have two sheets. One has the complete data and the other is based on the filter applied on the first sheet.
Name of the data sheet : Data
Name of the filtered Sheet : Hoky
I am just taking a small portion of data for simplicity. MY objective is to copy the data from Data Sheet, based on the filter. I have a macro which somehow works but its hard-coded and is a recorded macro.
My problems are:
The number of rows is different everytime. (manual effort)
Columns are not in order.
Sub TESTTHIS()
'
' TESTTHIS Macro
'
'FILTER
Range("F2").Select
Selection.AutoFilter
ActiveSheet.Range("$B$2:$F$12").AutoFilter Field:=5, Criteria1:="hockey"
'Data Selection and Copy
Range("C3").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("Hockey").Select
Range("E3").Select
ActiveSheet.Paste
Sheets("Data").Select
Range("D3").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Hockey").Select
Range("D3").Select
ActiveSheet.Paste
Sheets("Data").Select
Range("E3").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Hockey").Select
Range("C3").Select
ActiveSheet.Paste
End Sub
Best way of doing it
Below code is to copy the visible data in DBExtract sheet, and paste it into duplicateRecords sheet, with only filtered values. Range selected by me is the maximum range that can be occupied by my data. You can change it as per your need.
Sub selectVisibleRange()
Dim DbExtract, DuplicateRecords As Worksheet
Set DbExtract = ThisWorkbook.Sheets("Export Worksheet")
Set DuplicateRecords = ThisWorkbook.Sheets("DuplicateRecords")
DbExtract.Range("A1:BF9999").SpecialCells(xlCellTypeVisible).Copy
DuplicateRecords.Cells(1, 1).PasteSpecial
End Sub
I suggest you do it a different way.
In the following code I set as a Range the column with the sports name F and loop through each cell of it, check if it is "hockey" and if yes I insert the values in the other sheet one by one, by using Offset.
I do not think it is very complicated and even if you are just learning VBA, you should probably be able to understand every step. Please let me know if you need some clarification
Sub TestThat()
'Declare the variables
Dim DataSh As Worksheet
Dim HokySh As Worksheet
Dim SportsRange As Range
Dim rCell As Range
Dim i As Long
'Set the variables
Set DataSh = ThisWorkbook.Sheets("Data")
Set HokySh = ThisWorkbook.Sheets("Hoky")
Set SportsRange = DataSh.Range(DataSh.Cells(3, 6), DataSh.Cells(Rows.Count, 6).End(xlUp))
'I went from the cell row3/column6 (or F3) and go down until the last non empty cell
i = 2
For Each rCell In SportsRange 'loop through each cell in the range
If rCell = "hockey" Then 'check if the cell is equal to "hockey"
i = i + 1 'Row number (+1 everytime I found another "hockey")
HokySh.Cells(i, 2) = i - 2 'S No.
HokySh.Cells(i, 3) = rCell.Offset(0, -1) 'School
HokySh.Cells(i, 4) = rCell.Offset(0, -2) 'Background
HokySh.Cells(i, 5) = rCell.Offset(0, -3) 'Age
End If
Next rCell
End Sub
When i need to copy data from filtered table i use range.SpecialCells(xlCellTypeVisible).copy. Where the range is range of all data (without a filter).
Example:
Sub copy()
'source worksheet
dim ws as Worksheet
set ws = Application.Worksheets("Data")' set you source worksheet here
dim data_end_row_number as Integer
data_end_row_number = ws.Range("B3").End(XlDown).Row.Number
'enable filter
ws.Range("B2:F2").AutoFilter Field:=2, Criteria1:="hockey", VisibleDropDown:=True
ws.Range("B3:F" & data_end_row_number).SpecialCells(xlCellTypeVisible).Copy
Application.Worksheets("Hoky").Range("B3").Paste
'You have to add headers to Hoky worksheet
end sub
it needs to be .Row.count not Row.Number?
That's what I used and it works fine
Sub TransfersToCleared()
Dim ws As Worksheet
Dim LastRow As Long
Set ws = Application.Worksheets("Export (2)") 'Data Source
LastRow = Range("A" & Rows.Count).End(xlUp).Row
ws.Range("A2:AB" & LastRow).SpecialCells(xlCellTypeVisible).Copy

Copying Format of one excel sheet to another excel worksheet using VBA

Is it possible to copy format of one excel sheet to another worksheet using VBA.
Like manually we can do by selecting entire sheet and then click on format button. And then select other worksheet and format will be copied. Is it possible to do by code.
Thanks & Regards
Sahil Chaudhary
Absolutely. Below is sample code.
see https://msdn.microsoft.com/en-us/library/office/ff837425.aspx
Sub Wsh_PasteSpecial()
Dim WshSrc As Worksheet
Dim WshTrg As Worksheet
Rem Set working worksheets
Set WshSrc = ThisWorkbook.Worksheets("Source")
Set WshTrg = ThisWorkbook.Worksheets("Target")
WshSrc.Cells.Copy
With WshTrg.Cells
.PasteSpecial Paste:=xlPasteColumnWidths
.PasteSpecial Paste:=xlPasteFormats
.PasteSpecial Paste:=xlPasteFormulasAndNumberFormats
Application.CutCopyMode = False
End With
End Sub
Find below the full code to paste the format of one Worksheet named "Source", including Color, ColumnWidth, RowHeight, Comment, DataValidation, except the contents (Values, Formulas) of the cells to all other Worksheets in the same Workbook excluding a List of Worksheets as an Array
Option Explicit
Sub Wsh_PasteSpecial_Test()
Dim aWshExcluded As Variant, vWshExc As Variant
aWshExcluded = Array("Exclude(1)", "Exclude(2)")
Dim WshSrc As Worksheet
Dim WshTrg As Worksheet
Rem Set Source Worksheet
Set WshSrc = ThisWorkbook.Worksheets("Source")
Application.ScreenUpdating = 0
Rem Process All Worksheets
For Each WshTrg In WshSrc.Parent.Worksheets
Rem Exclude Worksheet Source
If WshTrg.Name <> WshSrc.Name Then
Rem Validate Worksheet vs Exclusion List
For Each vWshExc In aWshExcluded
If WshTrg.Name = vWshExc Then GoTo NEXT_WshTrg
Next
Rem Process Worksheet Target
With WshTrg.Cells
WshSrc.Cells.Copy
.PasteSpecial Paste:=xlPasteFormats 'Source format is pasted.
.PasteSpecial Paste:=xlPasteComments 'Comments are pasted.
.PasteSpecial Paste:=xlPasteValidation 'Validations are pasted.
Application.CutCopyMode = False
Application.Goto .Cells(1), 1
End With: End If:
NEXT_WshTrg:
Next
Application.Goto WshSrc.Cells(1), 1
Application.ScreenUpdating = 1
End Sub

copy paste data from a different workbook to current worksheet

I am basically stuck. I have a code which allows me to browse a file, once the file is selected it copies all the data in that file and then allows me to select a worksheet, from any workbook that is open at that time. Once the worksheet is selected [this is where i get stuck] i want it to paste it into j7. instead it doesn't do that, baring in mind i will be changing the file name everyday as it has the current days date on it.
here is my code:
Sub Macro4()
'
' Macro4 Macro
'
'
Range("A1").Select
Dim fileStr As String
fileStr = Application.GetOpenFilename()
If fileStr = "False" Then Exit Sub
Workbooks.Open fileStr
Range("A2").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Window.Sheets(Array("Forecast_workings")).Select{**this is where i want to be able to select a worksheet from any open workbook and it will paste the data in cell J7 of that worksheet.**
Range("J7").Select
Application.CutCopyMode = False
Range("C16:C27").Select
Selection.Copy
Range("E16").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("G16:G27").Select
Selection.Copy
Range("C16").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("O16").Select
End Sub
I can see lot of errors in your code.
First things first. You avoid the use of .Select. INTERESTING READ
If I understand you correctly then to get the name of the sheet which user selects at runtime, you can use Application.InputBox with Type:=8. This will return a range and from that you can use .Parent.Name to get the name of the worksheet.
Is this what you are trying?
Your code can be written as (UNTESTED)
Sub Macro4()
Dim fileStr As String
Dim wb As Workbook, thiswb As Workbook
Dim ws As Worksheet, thisws As Worksheet
Dim Lcol As Long, LRow As Long
Dim Ret As Range
'~~> Set an object for thisworkbook and worksheet
Set thiswb = ThisWorkbook
'~~> Change this to the sheet from where you want to copy
Set thisws = thiswb.Sheets("Sheet1")
'~~> Let user choose a file
fileStr = Application.GetOpenFilename()
If fileStr = "False" Then Exit Sub
'~~> Set an object for workbook opened and it's worksheet
Set wb = Workbooks.Open(fileStr)
On Error Resume Next
Set Ret = Application.InputBox("Select a cell from the sheet you want to choose", Type:=8)
On Error GoTo 0
If Ret Is Nothing Then Exit Sub
Set ws = wb.Sheets(Ret.Parent.Name)
With thisws
'~~> Find Last column in row 2
Lcol = .Cells(2, .Columns.Count).End(xlToLeft).Column
'~~> Find last cell in Col 1
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Copy your range directly to new worksheet selected
.Range(.Cells(2, 1), .Cells(LRow, Lcol)).Copy ws.Range("J7")
.Range("C16:C27").Copy ws.Range("E16")
.Range("G16:G27").Copy ws.Range("C16")
Application.CutCopyMode = False
End With
End Sub
when working with multiple workbooks, dont use range() but wb.range(), where wb is defined with the set function.
Also activesheet can be tricky. Preferably name the sheet you are using sheets("whatever").
And for last, to copy things dont use activate/select, just do as this:
wb.sheets("whatever").range() thisworkbook.sheets("watever2").range("").
I also saw you dont use application.enableevents=false/true, so events will trigger like crazy and your activesheet (or cell) will change like crazy if you have code in worksheet_change section.