I have a program that needs to copy select columns within the same workbook and worksheet.
The current code results in Excel crashing, so I'm not sure if it is working or not.
Is there a better way to copy the columns within the same worksheets with the same workbook?
Code:
Sub Macro1()
Dim wb1 As Workbook
'Set it to be the file location, name, and file extension of the Working File
Set wb1 = Workbooks.Open("Z:\XXX\Working File.xlsx")
MsgBox "Copying Fields within Working File"
wb1.Worksheets(1).Columns("G").Copy wb1.Worksheets(1).Columns("H").Value
wb1.Worksheets(1).Columns("J").Copy wb1.Worksheets(1).Columns("O").Value
wb1.Worksheets(1).Columns("K").Copy wb1.Worksheets(1).Columns("N").Value
wb1.Worksheets(1).Columns("M").Copy wb1.Worksheets(1).Columns("P").Value
wb1.Close SaveChanges:=True
End Sub
Try this, it sets two ranges' values equal, which will keep the data, but no formatting. It should be quicker.
Sub Macro1()
Dim wb1 As Workbook
'Set it to be the file location, name, and file extension of the Working File
Set wb1 = Workbooks.Open("Z:\XXX\Working File.xlsx")
MsgBox "Copying Fields within Working File"
With wb1.Worksheets(1)
.Columns("H").Value = .Columns("G").Value
.Columns("O").Value = .Columns("J").Value
.Columns("N").Value = .Columns("K").Value
.Columns("P").Value = .Columns("M").Value
End With
wb1.Close SaveChanges:=True
End Sub
Note you're using a whole column, so it might hang up or take a little longer. If you want, you can instead just get the last Row of each column and use that to shorten the ranges being copied.
Edit: As mentioned above, you may be better off using a smaller range. This is a little more verbose, but you should be able to follow what it's doing:
Sub Macro1()
Dim wb1 As Workbook
Dim lastRow As Long
'Set it to be the file location, name, and file extension of the Working File
Set wb1 = ActiveWorkbook
MsgBox "Copying Fields within Working File"
With wb1.Worksheets(1)
lastRow = .Cells(.Rows.Count, "G").End(xlUp).Row
.Range("H1:H" & lastRow).Value = .Range("G1:G" & lastRow).Value
lastRow = .Cells(.Rows.Count, "J").End(xlUp).Row
.Range("O1:O" & lastRow).Value = .Range("J1:J" & lastRow).Value
lastRow = .Cells(.Rows.Count, "K").End(xlUp).Row
.Range("N1:N" & lastRow).Value = .Range("K1:K" & lastRow).Value
lastRow = .Cells(.Rows.Count, "M").End(xlUp).Row
.Range("P1:P" & lastRow).Value = .Range("M1:M" & lastRow).Value
End With
wb1.Close SaveChanges:=True
End Sub
Related
I have two worksheets in the same workbook where they have different # of columns containing policy information and I would like to use vba to save multiple workbooks based on a certain column (state) since trying to save 50 times manually isn't the most efficient way.
State in sheet1 is column E & in sheet2 is column F. Now sheet1 & sheet2 have different ranges & columns so last row may need to be defined separately.
I found some codes online but wasn't able to make it work. My issues now is how to incorporate sheet2 and secondly make it work. The codes I have now have script out of range error in line Windows(state).Activate
Sub ExtractToNewWorkbook()
Dim ws As Worksheet
Dim wsNew As Workbook
Dim rData As Range
Dim rfl As Range
Dim state As String
Dim sfilename As String
Dim LR1 As Long
Set ws = ThisWorkbook.Sheets("Sheet1")
LR1 = ws.Cells(Rows.Count, "A").End(xlUp).Row
'Apply advance filter in your sheet
With ws
Set rData = Range("A1", "E" & LR1)
.Columns(.Columns.Count).Clear
.Range(.Cells(2, 5), .Cells(.Rows.Count, 5).End(xlUp)).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=.Cells(1, .Columns.Count), Unique:=True
For Each rfl In .Range(.Cells(1, .Columns.Count), .Cells(.Rows.Count, .Columns.Count).End(xlUp))
state = rfl.Text
Set wsNew = Workbooks.Add
sfilename = state & ".xlsx"
'Set the Location
ActiveWorkbook.SaveAs FilePath & sfilename
Application.DisplayAlerts = False
ws.Activate
rData.AutoFilter Field:=5, Criteria1:=state
rData.Copy
Windows(state).Activate
ActiveSheet.Paste
ActiveWorkbook.Close SaveChanges:=True
Next rfl
Application.DisplayAlerts = True
End With
ws.Columns(Columns.Count).ClearContents
rData.AutoFilter
End Sub
You should avoid ActiveWorkbook and .Activate (also see: How to avoid using Select in Excel VBA). Instead access the workbook wsNew directly:
Set wsNew = Workbooks.Add
sfilename = state & ".xlsx"
'Set the Location
wsNew.SaveAs FilePath & sfilename
Application.DisplayAlerts = False
rData.AutoFilter Field:=5, Criteria1:=state
rData.Copy
wsNew.Worksheets(1).Paste
wsNew.Close SaveChanges:=True
Note that in Set rData = Range("A1", "E" & LR1) you missed a . before the range to make it use the with statement: Set rData = .Range("A1", "E" & LR1)
Note that you should consider to rename wsNew into wbNew in your entire procedure because you set a workbook with Set wsNew = Workbooks.Add and not a worksheet.
I have two workbooks, source workbook and a Destination workbook.
I would like to copy particular column (A,C;D;E;F;G;K;AP;AV;AW;AX)containing data from source workbook to the Destination workbook in column (A till E). I already searched through the page and could find a code like below
Sub Extract()
Dim x As Workbook
Dim y As Workbook
Dim Value As Variant
Set y = ThisWorkbook
Set x = Workbooks.Open("D:\data\Jenny_Work.xlsx")
Value = x.Sheets("Work_Jenny").Range("A1").Value
y.Sheets("Sheet1").Range("A1").Value = Value
x.Close
End Sub
It would be great if you can suggest me for the above criteria
Thanking in advance
try this
it is working for me!
Sub Extract()
Dim x As Workbook
Dim y As Workbook
Dim Value As Variant
Set y = ThisWorkbook
Set x = Workbooks.Open("G:\Book1.xlsm")
lRow = x.Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
dRow = y.Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
Union(y.Worksheets("Sheet1").Range("A1:A" & dRow), y.Worksheets("Sheet1").Range("B1:B" & dRow)).Copy
x.Worksheets("Sheet1").Range("A" & lRow).PasteSpecial xlPasteAll
Application.CutCopyMode = False
x.Save
End Sub
Please note that a sheet is not the same as a workbook as this will create confusion.
A workbook/excel file can contain multiple sheets/worksheets and not the other way around.
That being said here is your code:
Sub RunMe()
Dim lRow, lCol As Integer
Sheets("Master").Select
lRow = Range("A" & Rows.Count).End(xlUp).Row
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
For Each cell In Range(Cells(1, "B"), Cells(1, lCol))
Union(Range("A1:A" & lRow), Range(Cells(1, cell.Column), Cells(lRow, cell.Column))).Copy
Workbooks.Add
Range("A1").PasteSpecial
ActiveWorkbook.SaveAs Filename:= _
"C:\YourMap\" & cell.Value & ".xls" 'You might want to change the extension (.xls) according to your excel version
ActiveWorkbook.Close
Next cell
Application.CutCopyMode = False
End Sub
Just watch the file extension within the code (look for green text after pasting.).
I had tried to use VBA to help grab values from a Excel form into a another workbook (Which is blank inside for now) here is the VBA code I'm using:
Sub RunMe()
Dim lRow, lCol As Integer
Sheets("Sheet1").Select
lRow = Range("A" & Rows.Count).End(xlUp).Row
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
For Each cell In Range(Cells(1, "B"), Cells(1, lCol))
Union(Range("A1:A" & lRow), Range(Cells(1, cell.Column), Cells(lRow, cell.Column))).Copy
Workbooks.Add
Range("A1").PasteSpecial
ActiveWorkbook.SaveAs Filename:= _
"C:\Users\john\Desktop\Testforvba" & cell.Value & ".xls"
ActiveWorkbook.Close
Next cell
Application.CutCopyMode = False
End Sub
But the thing is that when I run this code after inputting a sample value on the form and manually run the macro, it works as it creates a new file and store the sample data I had type on the Form workbook.
But once I tried running the macro again, I realised that it recreates the file AGAIN which means it replace all the previous data. VBA is so dang hard lol. Anyone please give a hand thanks.
P.S The macro I stored in my personal Workbook
Try this one:
Option Explicit
Sub RunMe()
Application.ScreenUpdating = False
Dim lRow As Long, lCol As Long
Dim wb As Workbook, wbNew as Workbook
Dim ws As Worksheet, wsNew as Worksheet
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")
lRow = ws.Range("A" & Rows.Count).End(xlUp).Row
lCol = ws.Cells(1, Columns.Count).End(xlToLeft).Column
Dim cell As Variant
For Each cell In ws.Range(ws.Cells(1, "B"), ws.Cells(1, lCol))
Union(ws.Range("A1:A" & lRow), ws.Range(ws.Cells(1, cell.Column), ws.Cells(lRow, cell.Column))).Copy
Set wbNew = Workbooks.Add
Set wsNew = wbNew.Sheets("Sheet1")
Dim yourdesktopaddress As String
yourdesktopaddress = CreateObject("WScript.Shell").specialfolders("Desktop") & "\Testforvba"
wsNew.Range("A1").PasteSpecial
If Not Dir(yourdesktopaddress & "\" & cell.Value & ".xls", vbDirectory) = vbNullString Then
'MsgBox "exists"
Application.DisplayAlerts = False
Else
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:= _
yourdesktopaddress & "\" & cell.Value & ".xls"
End If
wbNew.Close
Application.DisplayAlerts = True
Next cell
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
The main issue was, whenever macro runs, Excel was creating the files from zero and this was causing Excel to recreate each file again. I have added that If Not Dir(yourdesktopaddress & "\Testforvba" & cell.Value & ".xls", vbDirectory) = vbNullString part of my code to check whether did this file already created or not, if not it's creating the file now. If you delete the "'" from the beginning of 'MsgBox "exists" it will always tell you that this file is already exist.
Also In the case of variables are not defined well, excel might start to overwrite itself and it may replace the previous data. (Especially Range("A1).PasteSpecial and Activeworkbook.close kind of critical points are most important ones) So I also edited whole code,defined all variables, defined the user's desktop address to ensure code works on every user.
This question already has answers here:
Loop through Excel Sheets
(2 answers)
Closed 6 years ago.
I am using the below script to copy data from "Sheet1" of a multi-sheet Excel file into a master sheet of another Excel file. It's working perfectly for one sheet. Now I need to get it to run through all the sheets pasting the data into the next available row in the Master file.
Please note: all the sheets use the same password.
Please help!
Thanks,
Yohanan
Sub CopyRanges()
Dim WB1 As Workbook
Dim WB2 As Workbook
Dim LastRow As Long
Set WB1 = ActiveWorkbook
Set WB2 = Workbooks.Open(WB1.Path & "\Datafile.xls")
Sheets("Sheet1").Unprotect ("Password1")
With WB2.Sheets("Sheet1")
LastRow = .Range("B" & .Rows.Count).End(xlUp).Row
End With
WB2.Sheets("71235").Range("B6:M" & LastRow).Copy
WB1.Sheets("Output").Range("A2").PasteSpecial xlPasteValues
Sheets("Sheet1").Protect ("FTCCTOR")
WB2.Close
End Sub
Try this:
Sub CopyRanges()
Dim WB1 As Workbook
Dim WB2 As Workbook
Dim LastRow As Long
Dim sht As Worksheet
Set WB1 = ActiveWorkbook
Set WB2 = Workbooks.Open(WB1.Path & "\Datafile.xls")
For Each sht In WB2.Sheets
With sht
.Unprotect ("Password1")
LastRow = .Range("B" & .Rows.count).End(xlUp).Row
WB1.Sheets("Output").Range("A" & WB1.Sheets("Output").Rows.count).End(xlUp).Resize(LastRow - 5, 12).value = .Range("B6:M" & LastRow).value
.Protect ("Password1")
End With
Next sht
WB2.Close
End Sub
When only wanting the values it is faster to assign the values than to copy them.
I have an Excel macro that copies and pastes line items from a source file to an Excel-based form. It opens a form template and saves each line item as it's own file then loops through the remaining rows. Right now I have a file path built into the code that refers to the form template needed, but I need the user to be able to choose which file they want to use as their template. I have code for both of these processes but I haven't been able to combine them. My example below results in a Compile Error: Variable not defined.
Here's what I have so far:
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 '~~> Write your code in Indication Tool.xls
Set wsSource = wbSource.Sheets("Indication Tool") '~~> Put the source sheet name
'~~> This opens the Processing Form template.
formpath = "C:\File path.xls"
'~~> Prompts user with Open File Dialog Box
strCancel = "N"
strWorkbookNameAndPath = Application.GetOpenFilename _
(FileFilter:=strFilt, _
FilterIndex:=intFilterIndex, _
Title:=strDialogueFileTitle)
'~~> Exits If No File Selected
If strWorkbookNameAndPath = "" Then
MsgBox ("No Filename Selected")
strCancel = "Y"
Exit Sub
ElseIf strWorkbookNameAndPath = "False" Then
MsgBox ("You Clicked The Cancel Button")
strCancel = "Y"
Exit Sub
End If
Workbooks.Open strWorkbookNameAndPath
'~~> This declares path where the Individual forms will be saved.
foldertosavepath = "C:\File path\Forms\"
With wsSource
'~~> Counts how many rows are in the Indication Tool
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("Processing Form") '~~> Declare which worksheet to activate
'~~> Proceed with the copying
.Range("B" & i).Copy wsForm.Range("F7:K7")
.Range("C" & i).Copy wsForm.Range("D8")
.Range("C" & i).Copy wsForm.Range("D30")
.Range("D" & i).Copy wsForm.Range("H29")
.Range("E" & i).Copy wsForm.Range("E29")
.Range("F" & i).Copy wsForm.Range("D33")
.Range("G" & i).Copy wsForm.Range("J30:K30")
.Range("H" & i).Copy wsForm.Range("P33")
.Range("I" & i).Copy wsForm.Range("L33:N33")
.Range("L" & i).Copy wsForm.Range("H32")
.Range("R" & i).Copy wsForm.Range("D87")
.Range("C2:F2").Copy wsForm.Range("J101:M101")
.Range("C3:M3").Copy wsForm.Range("E102:O102")
'~~> Save the form using the client name
wbForm.SaveAs foldertosavepath & .Range("B" & i).Value & ".xls"
'~~> These steps are for formatting, as I haven't figured out how paste values only
Set wbForm = Workbooks.Open(formpath)
Cells.Select
Selection.Copy
wsForm.Activate
'~~> This allows the format to be pasted into the updated Form
wsForm.Unprotect
Cells.Select
Selection.PasteSpecial Paste:=xlPasteFormats
wsForm.Protect
ActiveWorkbook.Save
ActiveWorkbook.Close
wbForm.Close ([SaveChanges:=False])
Set wbForm = Nothing
Set wsForm = Nothing
Next
End With
End Sub
When I debug the error, Sub CopyToForm() is highlighted in yellow and strCancel = is selected. Is there a way to set the user-chosen file as the formpath? Thanks in advance for your help, this has been a thorn in my side for quite some time.
Option Explicit is declared, and strCancel isn't declared as a variable.
Add Dim strCancel As String to your code