I am trying to automate a process that involves copy pasting data from one workbook to a new workbook. I've been able to put together the code shows below from snippets found in the forums here, and other places. However, I am receiving a "Runtime error 1004" when attempting to run the procedure. Any suggestions?
Option Explicit
Dim wbI As Workbook, wbO As Workbook, wsI As Worksheet, wsO As Worksheet
Dim wbName As String
Sub transferit()
wbName = InputBox("Enter name", "name")
'~~> Source/Input Workbook
Set wbI = ThisWorkbook
'~~> Set the relevant sheet from where you want to copy
Set wsI = wbI.Sheets("Sheet1")
'~~> Destination/Output Workbook
Set wbO = Workbooks.Add
'~~> Set the relevant sheet to where you want to paste
Set wsO = wbO.Sheets("Sheet1")
With wbO
'~~>. Save the file
.SaveAs Filename:="D:\Documents\Output\wbName
End With
With wsI
Call RangeSelectionPrompt
Selection.Copy
End With
With wsO
'~~> Paste it in say Cell A1. Change as applicable
.Range("A1").PasteSpecial xlPasteValues
End With
End Sub
Sub RangeSelectionPrompt()
Dim rng As Range
Set rng = Application.InputBox("Select a range", "Obtain Range Object", Type:=8)
End Sub
Do you need global variables? It is unlikely, move them inside the Sub. You didn't concatenate the filename rightly for the .SaveAs, and you did not copy what you was expecting to...
Here is my code, ther is still some control of errors missing.
Sub transferit()
Dim wbI As Workbook, wbO As Workbook, wsI As Worksheet, wsO As Worksheet
Dim wbName As String
wbName = InputBox("Enter name", "name")
'~~> Source/Input Workbook
Set wbI = ThisWorkbook
'~~> Set the relevant sheet from where you want to copy
Set wsI = wbI.Sheets("Sheet1")
'~~> Destination/Output Workbook
Set wbO = Workbooks.Add
'~~> Set the relevant sheet to where you want to paste
Set wsO = wbO.Sheets("Sheet1")
With wbO
'~~>. Save the file
.SaveAs Filename:="D:\Documents\Output\" & wbName
End With
RangeSelectionPrompt.Copy
With wsO
'~~> Paste it in say Cell A1. Change as applicable
.Range("A1").PasteSpecial xlPasteValues
End With
End Sub
Function RangeSelectionPrompt() As Range
Set RangeSelectionPrompt = Application.InputBox("Select a range", "Obtain Range Object", Type:=8)
End Function
RangeSelectionPrompt.Copy
With wsO
'~~> Paste it in say Cell A1. Change as applicable
.Range("A1").PasteSpecial xlPasteValues
End With
End Sub
Function RangeSelectionPrompt() As Range
Set RangeSelectionPrompt = Application.InputBox("Select a range", "Obtain Range Object", Type:=8)
End Function
Related
I have a workbook made up with 100+ worksheets. These worksheets have account number/names/days in the name of the worksheet.
The naming convention for the worksheets follows this pattern of AccountNumber/AccountName/Description:
11-Greg-Monday
11-Greg-Tuesday
11-Greg-Friday
38-Rachel-Sunday
38-Rachel-Tuesday
38-Rachel-Saturday
I would like Excel to loop through all the worksheets, and extract all of the 11-Greg worksheets and save into a new workbook named 11-Greg, and then do the same for 38-Rachel, etc. I have a list of the account numbers/names on a worksheet named "Accounts" in the workbook.
Would it be possible to maintain the formulas after the extract of the worksheets, and formatting like column widths?
I found this code that might work to start, but I don't know how to reference the list on the "Accounts" tab to loop through for the account names?
Dim wb as Workbook, sht as WorkSheet
Dim strFileName As String
'Copy sheet as a new workbook
ActiveWorkbook.Sheets("Sheet1").Copy
Set wb = ActiveWorkbook
Set sht = wb.Sheets(1)
'SaveAs
strFileName = Application.GetSaveAsFilename(wb.Name) & "xlsx"
If strFileName = "False" Then Exit Sub 'User Canceled
wb.SaveAs Filename:=strFileName
The easiest way would be to create a list of the names you want to stack on a separate list. set that list as a range and then loop through each cell checking to see if the x letters of the sheet name match. something like this
Sub stacksheets()
Dim rng As Range, cCell As Range
Dim ws As Worksheet
Dim wb As Workbook, wb2 As Workbook
Dim shName As String
Set rng = ActiveWorkbook.Sheets("list").Range("a1:a2") ''this would be the list of names
Set wb2 = ActiveWorkbook ''remembering activeworkbook so can return
For Each cCell In rng
shName = Left(cCell.Value, 5) ''this needs to be the minimum letters from each name that is unique
Set wb = Workbooks.Add
For Each ws In wb2.Sheets
If InStr(ws.Name, shName) > 0 Then ''checks for name in sheet name
ws.Copy after:=wb.Sheets(1)
wb2.Activate
End If
Next ws
wb.SaveAs (wb2.Path & "\" & cCell.Value) '' saves workbook as list name
Next cCell
End Sub
I am using VBA to try to see if values in cells from one workbook match the named ranges from another workbook and if they do match then copy paste values from another column in those named ranges. I know they will match. the purpose is just to copy the values over into their designated named range.
The problem is in this line:
If rng = ws2.Range("NamedRange") Then
Here is my code below:
Sub Button4_Click()
Dim strFileName As String
Dim wb1 As Workbook
Dim ws1 As Worksheet
Dim wb2 As Workbook
Dim ws2 As Worksheet
Dim cell As Range
Dim rng As Range
Dim RangeName As String
Dim CellName As String
''Set wb2 = ActiveWorkbook
''Set ws2 = wb2.Sheet("Output")
''ws2.Range("D1:D12").Copy
''Set wb1 = ActiveWorkbook
strFileName = CreateObject("WScript.Shell").specialfolders("Desktop") & "\BAC GVP - Template_Update_121917.xlsm"
If Dir(strFileName) <> vbNullString Then
Set wb1 = Workbooks.Open(strFileName)
Else
MsgBox "Sorry, the file does not exist on your Desktop at this time, please drop a copy to your Desktop from server!"
End If
''Set wb2 = ThisWorkbook
''Set ws2 = wb2.Sheets("Output")
''Set ws1 = wb1.Sheets("RVP Local GAAP")
''ws2.Range("D4:D12").Copy
''ws1.Range("G13:G21").PasteSpecial xlPasteValues
''RangeName = "myData"
''CellName = "G11:G83"
''Set cell = Worksheets("RVP Local GAAP").Range(CellName)
''ThisWorkbook.Names.Add Name:=RangeName, RefersTo:=cell
''RangeName = "NamedRange"
''CellName = "C4:C12"
Set wb2 = ThisWorkbook
Set ws2 = wb2.Sheets("Output")
Set ws1 = wb1.Sheets("RVP Local GAAP")
For Each rng In ws1.Range("CurrentTaxPerLocalGAAPProvision")
If rng = ws2.Range("NamedRange") Then
ws2.Range("ReportBalance").Copy
ws1.Range("CurrentTaxPerLocalGAAPProvision").PasteSpecial xlPasteValues
MsgBox "Values Copied Successfully"
End If
Next rng
MsgBox "Both Ranges do not have the same data"
End Sub
See image below - Cell G29 is called "GVP_Donations_CurrentTaxPerLocalGAAPProvision"... so for this example I would want $4,313 to appear in the cell G29
CurrentTaxPerLocalGAAPProvision:
Range ("NameRange"):
Your line saying
If rng = ws2.Range("NamedRange") Then
is crashing out due to the attempt to compare the value of rng (e.g. "" when rng is referring to the cell G29) with an array of values (the values in "NamedRange"). VBA cannot handle the comparison of a scalar to a vector. But it isn't what you are wanting to do anyway.
I believe that, to do what it seems you are trying to do, you can replace your loop with:
'Loop through all the values in NamedRange
For Each rng In ws2.Range("NamedRange")
'Transfer the value from the next column to the appropriate range in the
'destination sheet
ws1.Range(rng.Value).Value = rng.Offset(0, 1).Value
Next
MsgBox "Values Copied Successfully"
If only some of the values in "NamedRange" should be copied, then you may need to include a bit of testing to see whether the ranges are in the correct target area:
Dim dstRng As Range
'Loop through all the values in NamedRange
For Each rng In ws2.Range("NamedRange")
Set dstRng = Nothing
On Error Resume Next
Set dstRng = ws1.Range(rng.Value)
On Error GoTo 0
'Check that the range exists in destination sheet
If Not dstRng Is Nothing Then
'Check that the range exists in the appropriate area
If Not Intersect(dstRng, ws1.Range("CurrentTaxPerLocalGAAPProvision")) Is Nothing Then
'Transfer the value from the next column to the appropriate range in the
'destination sheet
dstRng.Value = rng.Offset(0, 1).Value
End If
End If
Next
MsgBox "Values Copied Successfully"
I am trying to copy all the results from cell "A9" tell the end of the data using XLDOWN from the the file named "DDR" & tab named "everett" and paste it back into the workbook im currently using.
Any help will be greatly appreciated
Sub XLDOWN1()
'
' XLDOWN1 Macro
'
'
Dim wbSource As Workbook, wbDest As Workbook
Dim wsSource As Worksheet, wsDest As Worksheet
Dim rngSource As Range, rngDest As Range
Set wbSource = Workbooks.Open("G:\GAGC\Accounting\Payroll\Payroll\Analysis Macro Upload\DDR.xlsx", , True)
Set wsSource = wbSource.Worksheets("Everett")
ws.Range("A9", Range("A9").End(xlDown)).Select
Selection.Copy
Set rngSource = wsSource.Range("A9").Range(Selection, Selection.End(xlDown))
Set wbDest = ThisWorkbook
Set wsDest = wbDest.Worksheets("2016")
Set rngDest = wsDest.Range("A4") 'Destination Cell
rngDest.Value = rngSource.Value 'Copies values over only
wbSource.Close (False) 'Close without saving changes
End Sub
Give this a shot. There were a few issues in the code you provided that should be clear after seeing the refactored code below.
Dim wbSource As Workbook, wbDest As Workbook
Dim wsSource As Worksheet, wsDest As Worksheet
Dim rngSource As Range, rngDest As Range
'set up source workbook, sheet, range
Set wbSource = Workbooks.Open("G:\GAGC\Accounting\Payroll\Payroll\Analysis Macro Upload\DDR.xlsx", , True)
Set wsSource = wbSource.Worksheets("Everett")
Set rngSource = wsSource.Range(wsSource.Range("A9"), wsSource.Range("A9").End(xlDown))
'set up destination workbook, sheet, range
Set wbDest = ThisWorkbook
Set wsDest = wbDest.Worksheets("2016")
Set rngDest = wsDest.Range("A4") 'Destination Cell
rngSource.Copy Destination:=rngDest
wbSource.Close False
I have the following code which I am trying to get to name the entire A and B columns range according to the worksheet tab name. I want each A:B range of cells in each worksheet to be named RoomCode_ + the name of the excel sheet tab.
So for example if I had 3 sheets called XYZ, ABC and DEF, then my cell range names for those 3 sheets respectively should be:
RoomCode_XYZ
RoomCode_ABC
RoomCode_DEF
I would typically do this manually by highlighting the cell range and just typing the range name I wanted, however I have over 150 tabs and would like to be able to do them all automatically through this process.
Sub nameRanges()
Set wbook = ActiveWorkbook
For Each sht In wbook.Worksheets
sht.Activate
RangeName = "RoomCode_" + ActiveSheet.Name
CellName = "A:B"
Set cell = ActiveWorksheets.Range(CellName)
ActiveWorksheets.Names.Add Name:=RangeName, RefersTo:=cell
Next sht
End Sub
Just a bit of refactoring to get what you need. Biggest this to work directly with objects and eliminate the Active... stuff.
Also ActiveWorksheets is not proper syntax in any way.
Sub nameRanges()
Dim wbook As Workbook
Set wbook = ThisWorkbook
Dim sht As Worksheet
For Each sht In wbook.Worksheets
Dim RangeName As String, CellName As String
RangeName = "RoomCode_" + sht.Name
CellName = "A:B"
Dim cell As Range
Set cell = sht.Range(CellName)
sht.Names.Add Name:=RangeName, RefersTo:=cell
Next sht
End Sub
Here's another way:
Option Explicit
Sub nameRanges()
Dim sht As Worksheet
Dim RangeName As String
Dim cell As String
For Each sht In ActiveWorkbook.Worksheets
RangeName = "RoomCode_" + sht.Name
cell = "=" & sht.Name & "!" & "A:B"
Names.Add Name:=RangeName, RefersTo:=cell
Next sht
End Sub
I think that you would want to add the names to the workbook names collection. The way it is now you'll still have to reference the individual worksheet before you can access the name.
WorkSheets("RoomCode").Range("RoomCode_XYZ")
By adding the names to the workbook you'll be able to access no matter the ActiveSheet.
Range("RoomCode_XYZ")
Sub nameRanges()
Dim wbook As Workbook
Set wbook = ThisWorkbook
Dim sht As Worksheet
For Each sht In wbook.Worksheets
Dim RangeName As String, CellName As String
RangeName = "RoomCode_" + sht.Name
CellName = "A:B"
Dim cell As Range
Set cell = sht.Range(CellName)
ThisWorkBook.Names.Add Name:=RangeName, RefersTo:=cell
Next sht
End Sub
The problem: I am trying to copy data from one workbook to another.
Lets say I have a workbook (called DATA) with several worksheets filled with data. Each column of data has a unique heading (all headings on the same row).
On the other hand I have another workbook (called REPORT) with one worksheet that contains only the heading of the data (in one row). They are not in the same order as in DATA workbook. For example I have 3 headings in REPORT worksheet that can be found in different worksheets in DATA workbook.
I need to loop through all the worksheets in the DATA workbook and copy paste the whole column to the REPORT worksheet when the same heading is found.
This image may help to understand. Explanation
My first attempt:
Dim MyFile As String
Dim ws As Worksheet
''Workbook that contains one worksheet with all the headings ONLY NO DATA
Dim TargetWS As Worksheet
Set TargetWS = ActiveSheet
Dim TargetHeader As Range
''Location of Headers I want to search for in source file
Set TargetHeader = TargetWS.Range("A1:G1")
''Source workbook that contains multiple sheets with data and headings _
not in same order as target file
Dim SourceWB As Workbook
Set SourceWB = Workbooks("Source.xlsx")
Dim SourceHeaderRow As Integer: SourceHeaderRow = 1
Dim SourceCell As Range
''Stores the col of the found value and the last row of data in that col
Dim RealLastRow As Long
Dim SourceCol As Integer
''Looping through all worksheets in source file, looking for the heading I want _
then copying that whole column to the target file I have
For Each ws In SourceWB.Sheets
ws.Activate
For Each Cell In TargetHeader
If Cell.Value <> "" Then
Set SourceCell = Rows(SourceHeaderRow).Find _
(Cell.Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not SourceCell Is Nothing Then
SourceCol = SourceCell.Column
RealLastRow = Columns(SourceCol).Find("*", LookIn:=xlValues, _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
If RealLastRow > SourceHeaderRow Then
Range(Cells(SourceHeaderRow + 1, SourceCol), Cells(RealLastRow, _
SourceCol)).Copy
TargetWS.Cells(2, Cell.Column).PasteSpecial xlPasteValues
End If
End If
End If
Next
Next
I am getting an error of Application-defined or object-defined error Run-time 1004. Is there something wrong with my logic/syntax..?
Please help I am so bad in VBA.
Thanks in advance!
your last edited code works
but you're making unnecessary checks and I'd suggest you to loop through each sheet header and check if it exists in TargetHeader range to possibly subsequently copy its column to SourceWB
furthermore you may want to have your code more robust and check for actual wanted workbooks/worksheets existence before attempting to set variables to them
like follows:
Option Explicit
Sub main()
Dim SourceWB As Workbook
Dim ws As Worksheet, TargetWS As Worksheet
Dim TargetHeader As Range, cell As Range, SourceCell As Range
Dim SourceHeaderRow As Integer: SourceHeaderRow = 1
''Source workbook that contains multiple sheets with data and headings _
not in same order as target file
Set SourceWB = GetWb("Source.xlsx")
If SourceWB Is Nothing Then Exit Sub
''Workbook that contains one worksheet with all the headings ONLY NO DATA
'Set TargetWS = ActiveSheet
Set TargetWS = GetWs("REPORT") 'it will get the first worksheet (if any) in "REPORT" workbook (if open)
If TargetWS Is Nothing Then Exit Sub
''Location of Headers I want to search for in source file
Set TargetHeader = TargetWS.Range("A1:G1")
''Looping through all worksheets in source file, looking for the heading I want _
then copying that whole column to the target file I have
For Each ws In SourceWB.Sheets
For Each cell In ws.Rows(SourceHeaderRow).SpecialCells(xlCellTypeConstants, xlTextValues)
Set SourceCell = TargetHeader.Find(cell.Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not SourceCell Is Nothing Then
Range(cell.Offset(1), ws.Cells(ws.Rows.Count, cell.Column).End(xlUp)).Copy
SourceCell.Offset(1).PasteSpecial xlPasteValues
End If
Next
Next
End Sub
Function GetWb(wbName As String) As Workbook
On Error Resume Next
Set GetWb = Workbooks(wbName)
On Error GoTo 0
If GetWb Is Nothing Then MsgBox "Sorry, the workbook '" & wbName & "' isn't open" & vbCrLf & vbCrLf & "Please open it and run the macro again"
End Function
Function GetWs(wbName As String, Optional wsName As Variant) As Worksheet
Dim wb As Workbook
Dim ws As Worksheet
Set wb = GetWb(wbName)
If wb Is Nothing Then Exit Function
On Error Resume Next
If IsMissing(wsName) Then
Set GetWs = wb.Worksheets(1) ' if no ws name passed then get the first one
Else
Set GetWs = wb.Worksheets(wsName)
End If
On Error GoTo 0
If GetWs Is Nothing Then MsgBox "Sorry, the worksheet '" & wsName & "0 isn't in '" & wb.Name & "'" & vbCrLf & vbCrLf & "Please open a valid workbook and run the macro again"
End Function