Copying the data in Excel through VBA - vba

As you can see down, I am copy 4 columns of data from one workbook to another. I am stuck at a case where the destination has 8 columns and my area of columns are 1,2,5,7. can you suggest me some changes in the code please. The one below will work only for first 4 columns. Thanks.
Sub Copymc()
Dim x As Workbook
Dim y As Workbook
Dim rng As Range
Set x = Workbooks.Open("H:\testing\Q4 2014\US RMBS Q4.xlsx")
Set y = Workbooks.Open("H:\testing\demo\test1.xlsx")
Dim LastRow As Long
Dim NextRow As Long
x.Worksheets("RL Holdings").Activate
Range("A65536").Select
ActiveCell.End(xlUp).Select
LastRow = ActiveCell.Row
Range("A2:D" & LastRow).Copy
y.Worksheets("Sheet1").Range("a65536").End(xlUp).Offset(1, 0)
Application.CutCopyMode = False
End sub

The line Range("A2:D" & LastRow).Copy has column D hardcoded into it. This means that it will always copy A2 to D65536. If you want specific columns(A, B, E, G) then I would recommend simply repeating your code for each column.
For example
Range("A65536").Select
ActiveCell.End(xlUp).Select
Selection.Copy
y.Worksheets("Sheet1").Range("a65536").End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
then copy the code four times and replace the A to whatever column you want to copy or paste to. If this isn't what you are looking for please elaborate on what you want.

Related

FIltering a data set in excel vba and pasting results into different tabs that are named based on filter

I am trying to filter a data set in tab "Expiring Contracts", filtered on column B (this data set can increase or decrease based at any point). The different filters come from tab "Inputs" which can change overtime (increase or decrease). I am trying to paste the results of the filter to separate tabs that are named exactly like the list, BUT I want to paste the values on the next available (blank) cell. This is what I have now:
Sub ParseList2()
Dim uwname As String
Dim lastrowUW As Long
Dim lastrow As Long
Dim N As Range
lastrowUW = Sheets("Inputs").Cells(Rows.Count, "H").End(xlUp).Row
For Each N In Sheets("Inputs").Range("H2:H" & lastrowUW).Cells
uwname = N.Text
Sheets("Expiring Contracts").Range("$A:$AA").AutoFilter Field:=2,
Criteria1:=N
lastrow = Columns(2).Find("*", SearchDirection:=xlPrevious).Row
Range("A2:AA" & lastrow).SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets(uwname).Select
lastrow = Columns(2).Find("*", SearchDirection:=xlPrevious).Row + 1
Range("A" & lastrow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Next N
Sheets("Expiring Contracts").AutoFilterMode = False
End Sub
This worked thanks to some comments below!
Sub ParseList2()
Dim uwname As String
Dim lastrowUW As Long
Dim lastrow As Long
Dim N As Range
Dim rng As Range
lastrowUW = Sheets("Inputs").Cells(Rows.Count, "H").End(xlUp).Row
For Each N In Sheets("Inputs").Range("H2:H22").Cells
uwname = N.Value
Sheets("Expiring Contracts").Range("$A:$AA").AutoFilter Field:=2,
Criteria1:=uwname
'lastrow = Columns(2).Find("*", SearchDirection:=xlPrevious).Row + 1
Range("A2:AA99999").SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets(uwname).Select
lastrow = Columns(2).Find("*", SearchDirection:=xlPrevious).Row + 1
Range("A" & lastrow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A1").Select
Sheets("Expiring Contracts").Select
Sheets("Expiring Contracts").AutoFilterMode = False
Range("A1").Select
Next N
Sheets("Expiring Contracts").Select
Sheets("Expiring Contracts").AutoFilterMode = False
Range("A1").Select
End Sub
What you are attempting to do using VBA can very easily be accomplished using PivotTables and Slicers. Turn your source data into an Excel Table, make a PivotTable out of it, put the PivotTable in the Inputs tab, set up a Slicer on the field you want to filter on, put the other fields of interest in the PivotTable as row fields, and you're done. No code necessary. Let the application do the work for you.

vba - copy data from one sheet to another due to condition

I am very new to vba (and code in general) so I apologise if I haven't asked the right question or have missed a thread that covers this. I have spent a couple of weeks trying to find the answer so hopefully you may be able to help.
I am trying to copy, data from one sheet (Named Master Sheet) to another depending on a variable in column L (Variables "In Progress" or "Not Started") to an Overview / GUI sheet. My current code (below) does this for the first line of data, however I would like this to work for the whole sheet.Unfortunately it will have a changing amount of data added so the array will be expanding- unsure how much more difficult this will make it.
Thank you very much for any help you can provide, and I apologise for the marked out notes. I can add a picture too (if possible) if it would help make more sense of what I would like to do?
Sub Update_Uncompleted_Tasks()
' Update_Uncompleted_Tasks Macro
' Selects tasks from Master Sheet and copies to the Overview Sheets if assigned as uncompleted
'DON'T USE BELOW YET (UNSURE IF IT WILL WORK)
'Maybe Vlookup?
'Dim LastRow As Long, i As Long
'LastRow = Cells(Rows.Count, "L").End(xlUp).Row
'For i = 1 To LastRow
Sheets("Master Sheet").Select
If Range("L2") = "In Progress" Then
Range("A2:L2").Select
Selection.Copy
Sheets("Overview").Select
Application.Goto Reference:="R10000C2"
Selection.End(xlUp).Select
Selection.Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ElseIf Range("L2") = "Not Started" Then
Range("A2:L2").Select
Selection.Copy
Sheets("Overview").Select
Application.Goto Reference:="R10000C2"
Selection.End(xlUp).Select
Selection.Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
'Next i
End Sub
First of all you should take a look at this: Avoid using select in Excel-VBA-Macros.
The following code should fulfill your needs, but it requires that your data in column L has no empty cells (until the end is reached)
Sub Update_Uncompleted_Tasks()
Dim row as Long
'Initial value
row = 2
With ThisWorkbook.Worksheets("Master Sheet")
Do Until IsEmpty(.Range("L" & row))
If (.Range("L" & row).Value = "In Progress") Or (.Range("L" & row).Value = "Not Started") Then
.Range("A" & row & ":L" & row).Copy
ThisWorkbook.Worksheets("Overview").Range("B10000").End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End If
row = row + 1
Loop
End With
End Sub
The loop ends when a row is reached where the cell in column L is empty.
EDIT: You can also replace the Do Until -- Loop with a For row=2 To lastRow -- Next row. To determine the last row of your data, there are many ways, check out this link Excel-VBA find last row or just use the search function.
You can use this piece of code to get the number of last nonempty line on your sheet:
Dim LastDataLine As Long
LastDataLine = Sheets("Master Sheet").Range("A" & Rows.Count).End(xlUp).Row
And for last non-empty column (just in case):
Dim LastDataCol As Integer
LastDataCol = Sheets("Master Sheet").Cells(1, Columns.Count).End(xlToLeft).Column
If you also need help implementing a loop which goes through each line leave a comment.

Paste column width won't work on Excel

I'm beginner, and I want to ask something about my code. why paste column width wont work on VBA EXCEL??
Here's my code. thank you.
Sub merge()
Dim P As Integer
On Error Resume Next
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = "RAW"
Sheets(1).Activate
ActiveSheet.UsedRange.Select
Selection.Copy Destination:=Sheets("RAW").Range("A1")
Sheets("RAW").Range("A1").PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
For P = 2 To Sheets.Count - 1
Sheets(P).Activate
Range("A5").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets("RAW").Range("A1000000").End(xlUp)(2)
Next
End Sub
:) In your code you are referencing to a range A1, which is already in "A:Z".
If you want to make the columns B to Z equal to the column A in width, use the following code.
Columns("B:Z").columnwidth = columns("A:A").columnwidth

Simple VBA Script Error [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm still pretty new with VBA (learning for work, coming from a JS background) and I need a little help with this. My goal is: loop through each worksheet (except the "Summary" sheet, although I'm not sure how to exclude this from the loop) in the workbook and copy A2 in each sheet, as well as the last cell containing a value in column L of each sheet, and paste those next to each other in columns A and B on the "Summary Sheet", respectively. I'm not an expert with VBA syntax by any means, so if anyone has any way to refactor this (I know I don't need all the .select methods), I would appreciate it. Right now I'm getting an "invalid or unqualified reference" error on line 28. My goal is to learn, so if you have any input I would appreciate a short explanation of the logic. Thanks.
Sub Macro7()
'
' Macro7 Macro
'
' Keyboard Shortcut: Ctrl+c
Dim ws As Worksheet
Dim lastRow As Integer
Dim summaryRow As Integer
summaryRow = 1
For Each ws In ActiveWorkbook.Worksheets
'Copy item number and paste on Summary Page'
Range("A2").Select
Selection.Copy
Sheets("Summary").Select
Range("A" & summaryRow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Copy corresponding BOM item # and paste on Summary Page'
ws.Select
lastRow = .Cells(.Rows.Count, "L").End(xlUp).Row
Range("L" & lastRow).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Summary").Select
Range("B" & summaryRow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
summaryRow = summaryRow + 1
Next ws
End Sub
You can avoid using .Select¹ by constructing a With ... End With statement that passes the parent worksheet reference along to the cells and range references. Direct value transfer is more expedient and more efficient than copying and pasting. Additionally, it avoids involving the clipboard altogether.
Sub Macro7()
Dim ws As Worksheet
Dim lastRow As Long
Dim summaryRow As Long
summaryRow = 1
For Each ws In ActiveWorkbook.Worksheets
With ws
If LCase(.Name) <> "summary" Then
Worksheets("Summary").Range("A" & summaryRow).Resize(1, 2) = _
Array(.Range("A2").Value, .Cells(Rows.Count, "L").End(xlUp).Value)
summaryRow = summaryRow + 1
End If
End With
Next ws
End Sub
.¹ See How to avoid using Select in Excel VBA macros for more methods on getting away from relying on select and activate to accomplish your goals.
Your code looks fine apart from the '.' reference Jeeped pointed out.
I have just neatened up your code here as using .select is a little messy and long-winded (if you are building big macros it can add unnecessary work and slow it down a lot).
You can just do the commands straight from a range reference as shown below:
Sub Macro7()
Dim ws As Worksheet
Dim lastRow As Integer
Dim summaryRow As Integer
summaryRow = 1
For Each ws In ActiveWorkbook.Worksheets
'Copy item number and paste on Summary Page'
Range("A2").Copy
Sheets("Summary").Range("A" & summaryRow).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Copy corresponding BOM item # and paste on Summary Page'
lastRow = ws.Cells(Rows.Count, "L").End(xlUp).Row
Application.CutCopyMode = False
ws.Range("L" & lastRow).copy
Sheets("Summary").Range("B" & summaryRow).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
summaryRow = summaryRow + 1
Next ws
End Sub
I typically code out worksheets("").Range("").action everytime unless I am doing a lot of work on 1 sheet so that I can see easily what is going on when I glance over, but you'll find your own preference to working (don't forget you can step through your code with F8 to look at what it is doing every step of the way)
I hope this helps you start your VBA journey!

Trying to use Excel VBA to copy/paste rows onto form, saving form in between rows

I have a workbook that serves as source data for another Excel-based form (not a Userform, just a formatted spreadsheet). The source file has anywhere from 2-40 rows of data - starting from row 18 - and each row needs to be copied into the form and saved separately, i.e. 15 rows from the Source file equates to 15 distinct Form files.
Each cell within the row must be copied separately and pasted to specific cells on the Form. The Source form contains Clients and their relevant info. I am trying to use a macro on the Form to automatically pull line items from the Source file, save the Form as the client's name in a specified folder, and continue until a blank row is reached on the Source file. I have some basic VBA experience, but have little knowledge of loops, variables, or functions, which seem to be my best course of action here.
Here's what I have so far. All I've been able to accomplish is the copy/pasting of the first row from the Source file.
Range("B18").Select
Selection.Copy
Windows("Form.xls").Activate
Range("F7:K7").Select
ActiveSheet.Paste
Windows("Source.xls").Activate
Range("C18").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Processing Form.xls").Activate
Range("D8").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("Source.xls").Activate
Range("D18").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Processing Form.xls").Activate
Range("H29").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("Source.xls").Activate
Range("E18").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Processing Form.xls").Activate
Range("E29").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("Source.xls").Activate
Range("F18").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Processing Form.xls").Activate
Range("D33").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range(“F7:K7”).Select
Application.CutCopyMode = False
Selection.Copy
ActiveWorkbook.SaveAs
I can't even get my macro to save the Form by the client's name. I also know that my extensive use of "Range" and "Select" will slow my code down to a crawl, I just don't know how to make it more efficient. I've tried using a reference cell to that tells the macro which row of the Source file to copy but haven't had any luck down that road either. Any and all help will be greatly appreciated!
Here's a simple demo:
Note: Not Tested
Option Explicit
Sub CopyToForm()
Dim wbSource As Workbook, wbForm As Workbook
Dim wsSource As Worksheet, wsForm As Worksheet
Dim formpath As String, foldertosavepath as string
Dim lrow As Long, i As Integer
Set wbSource = Thisworkbook '~~> assuming you write your code in Source.xls
Set wsSource = wbSource.Sheets("NameOfYourSheet") '~~> put the source sheet name
'~~> put the path where your form template is saved here
formpath = "C:\Users\Username\FolderName\Processing Form.xls"
'~~> put the path where you want to save individual updated forms.
foldertosavepath = "C:\Users\Username\FolderDestination\"
With wsSource
'~~> get the number of rows with data
lrow = .Range("B" & .Rows.Count).End(xlUp).Row
If lrow < 18 Then Msgbox "No data for transfer": Exit Sub
For i = 18 to lrow
Set wbForm = Workbooks.Open(formpath) '~~> open the form
Set wsForm = wbForm.Sheets("Sheetname") '~~> put the form sheet name
'~~> proceed with the copying
.Range("B" & i).Copy: wsForm.Range("F7:K7").PasteSpecial xlPasteValue
.Range("C" & i).Copy: wsForm.Range("D8").PasteSpecial xlPasteValues
.Range("D" & i).Copy: wsForm.Range("H29").PasteSpecial xlPasteValues
.Range("E" & i).Copy: wsForm.Range("E29").PasteSpecial xlPasteValues
.Range("F" & i).Copy: wsForm.Range("D33").PasteSpecial xlPasteValues
'~~> Save the form using the client name, I assumed it is in B?
wbForm.SaveAs foldertosavepath & .Range("B" & i).Value & ".xls"
wbForm.Close True
Set wbForm = Nothing
Set wsForm = Nothing
Next
End With
End Sub
In above code, I assumed that Form.xls is the same as Processing Form.xls.
This should give you the logic.
I hope this get's you started.
This is not test as I've noted, so if you encounter errors, comment it out.
You are frequently activating the workbooks. that's your code slows down..Below code will work faster
Sub test()
Dim dwb As Workbook
Dim swb As Workbook
Set dwb = Workbooks("Form.xls")
Set swb = Workbooks("Source.xls")
Set awb = Workbooks("Processing Form.xls")
With swb
.ActiveSheet.Range("B18").Copy Destination:=dwb.Sheet1.Range("F7:K7")
.ActiveSheet.Range("C18").Copy Destination:=awb.Sheet1.Range("D8")
.ActiveSheet.Range("D18").Copy Destination:=awb.Sheet1.Range("H29")
.ActiveSheet.Range("e18").Copy Destination:=awb.Sheet1.Range("E29")
.ActiveSheet.Range("F18").Copy Destination:=awb.Sheet1.Range("D33")
End With
End Sub
This might help steer you in the right direction:
Dim i As Long
For i = 1 To 10
With Range("A" & i)
.Copy Workbooks("ToWorkbook.xlsx").Worksheets("Sheet1").Range("B" & i + 9)
.Copy Workbooks("ToAnother.xlsx").Worksheets("Sheet2").Range("C" & i + 8)
.Copy Workbooks("AnotherOne.xlsx").Worksheets("SheetA").Range("D" & i + 2)
End With
Next i
i To 10 is used as a counter to loop through the rows in the source workbook.
For each i, you're taking the range from column A (i.e., with this, do something), copying and pasting it into different cells in different workbooks. In the first round, Range("A1") is being copied into 3 different workbooks at Range("B10"), Range("C9") and Range("D3"), respectively. The next turn, Range("A2") from the source book is going to be copied and pasted into the same destination workbooks from last time, but in Range("B11"), Range("C10") and Range("D4"). It's just a matter of finding the pattern for the different forms you need to paste into.