I am trying to sum values from my original worksheet in specific cells in my newly created worksheet, which has a template to fill out.
When I used macro recorder, it references the worksheet name, which would not be useful as the worksheet name changes depending on which worksheet I am working in when I run the code.
So I tried changing the worksheet name to a variable "XCXX".
The first argument works so I thought everything was okay, however, on the second argument, it keeps trying to open a file, when it should simply go back to XCXX and pull the values.
Is it a problem with my activesheet changing?
Sub AddWorkbooks()
Dim ChangeOrder As Range
Dim XCXX As Worksheet
Dim CoForm As Worksheet
Set XCXX = ActiveSheet
Set CoForm = Worksheets("+CO Form+")
'Set wbNew = Workbooks.Add
CoForm.Copy After:=Sheets(ActiveSheet.Index)
With CoForm
Range("A6:D6").Select
ActiveCell.FormulaR1C1 = XCXX.Range("D2").Value
Range("AD81").Select
ActiveCell.FormulaR1C1 = "='XCXX'!R[-64]C[-24]+'XCXX'!R[-64]C[-23]"
End With
End Sub
This should be close:
Sub AddWorkbooks()
Dim ChangeOrder As Range
Dim XCXX As Worksheet, wb As Workbook
Dim CoForm As Worksheet, CoFormCopy As Worksheet
Set wb = ActiveWorkbook
Set XCXX = ActiveSheet
Set CoForm = wb.Worksheets("+CO Form+")
CoForm.Copy After:=XCXX
Set CoFormCopy = XCXX.Next 'the copy of "+CO Form+"
With CoFormCopy 'assuming you want to work with the copy?
.Range("A6:D6").Value = XCXX.Range("D2").Value
.Range("AD81").FormulaR1C1 = _
Replace("='<nm>'!R[-64]C[-24]+'<nm>'!R[-64]C[-23]", "<nm>", XCXX.Name)
End With
End Sub
Note when using With you need to use a period to link (eg) Range() with the object used in the With statement, otherwise it defaults to the active sheet.
Also generally there's no need to select a range to do something with it.
Related
Having trouble with vba using range Union method. I have resolved it, at the end. But could not find the proper explanation, why it is so?
Set ws = ThisWorkbook.ActiveSheet
Set rng00 = Range("A1:C3")
Set rng01 = Range("F1:G3")
ws.Union(rng00,rng01).Copy 'the error giving line
When I have changed the line with below one strangely it has started to work. But as I remember I have used union method of range before with ThisWorkbook(or maybe Workbooks(name))
Worksheets("Sheet1").Activate
Application.Union(rng00,rng01).Copy
Application.Union feat. Qualifying Object References
Your 1st Code
Set ws = ThisWorkbook.ActiveSheet
Set rng00 = Range("A1:C3")
Set rng01 = Range("F1:G3")
ws.Union(rng00,rng01).Copy 'the error giving line
Your 2nd Code
Worksheets("Sheet1").Activate
Application.Union(rng00,rng01).Copy
Application.ThisWorkbook property
ThisWorkbook is (a reference to) the workbook containing this code. It is an exact workbook and there can only be one of it.
Dim wb As Workbook: Set wb = ThisWorkbook
Qualifying Worksheets
When referencing the sheets in a workbook, you want to qualify them (note the wb.):
Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
This can be only one worksheet, the worksheet named Sheet1 in the wb - workbook. It can't be the wrong worksheet unless you have incorrectly referenced the workbook.
When you do Set ws = ThisWorkbook.ActiveSheet, it creates a reference to any sheet (worksheet, chart) that is currently active (selected, you're looking at), yet in the line Worksheets("Sheet1").Activate you are activating Sheet1˛ of the ActiveWorkbook, the workbook which is the currently active (could be ThisWorkbook, but may not).
Qualifying Ranges
When referencing the ranges in a worksheet, you want to qualify them (note the ws.):
Dim rg1 As Range: Set rg1 = ws.Range("A1:C3")
Dim rg2 As Range: Set rg2 = ws.Range("F1:G3")
These are ranges in the ws - worksheet. They can't be the wrong ones unless you have incorrectly referenced the worksheet.
When you do Set rng00 = Range("A1:C3"): Set rng01 = Range("F1:G3"), you are creating references to ranges of the ActiveSheet (could be a worksheet, could be a chart), of the ActiveWorkbook (could be ThisWorkbook, but may not). It would have worked correctly only by chance in case your ActiveWorkbook was ThisWorkbook and your ActiveSheet was a worksheet named Sheet1 in the ActiveWorkbook.
Application.Union method
Its 'full name' says it all: it's a member of the Application object, not the Worksheet object. You can omit the Application. part from some of the Application object members: Union is such a member.
Union(rng1, rng2).Copy
Alltogether
Option Explicit
Sub CopyRange()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
Dim rg1 As Range: Set rg1 = ws.Range("A1:C3")
Dim rg2 As Range: Set rg2 = ws.Range("F1:G3")
Union(rng1, rng2).Copy
End Sub
Of course, if there is no worksheet named Sheet1 in the workbook, an error will occur. But that's another story.
Union is a function of the Application Object, not of a Worksheet Object. Which means that ws.Union would not work because there is no member with the name Union as a member of ws. The correct parent is Application.Union but since it would be tedious to write Application. for every function, most of the time the Application. is not written.
The arguments of Union must be Range Objects that are from the same Worksheet. When declaring Ranges, it is important to explicitly declare their parent sheet, to avoid issues later with functions like Union. Adding ws in front of Range like ws.Range is how you can declare that the range is a member of that sheet.
So the full corrected code would be
Set ws = ThisWorkbook.ActiveSheet
Set rng00 = ws.Range("A1:C3")
Set rng01 = ws.Range("F1:G3")
Application.Union(rng00, rng01).Copy
I have a Macro (within a Master Workbook) that is getting data from another Workbook/Worksheet using .value2.
I've tried different changes, within the code. I double checked that both workbooks are open. However, I keep getting the Subscript out of range (Error 9).
Sub NielsenScorecard_DataPaste()
Dim WbNielsenScorecard As Workbook
Set WbNielsenScorecard = Workbooks("Nielsen Scorecard_Template.xlsm")
TotalUS_DataPaste
End Sub
Sub TotalUS_DataPaste()
**Subscript out of range (Error 9)**
With Workbooks("Power Query - Meijer_Walmart_Total US xAOC.xlsm").Worksheets("PQTotalUS")
Dim Data(0) As Variant
'Copy Data Range
Data(0) = .Range(.Cells(.Rows.Count, "A").End(xlUp), "AA2").Value2
End With
'Worksheet Code Name within this Workbook
With wsTotalUS
Debug.Print wsTotalUS.Name
.AutoFilter.ShowAllData
.Range("A2:AA" & .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Row).ClearContents
With .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Resize(UBound(Data(0)))
.Resize(ColumnSize:=UBound(Data(0), 2)).Value2 = Data(0)
End With
End With
End Sub
You can reference a sheet by its codename, however it is a different format and must be in ThisWorkbook. A drawback is that you cannot reference a sheet in another workbook by its codename. Worksheets("PQ Total US").Activate versus PQTotalUS.Activate. If your goal is to shorten the code and not have to repeat a long name, then another option is to do the following:
Dim wb1 as Workbook
Dim ws1 as Worksheet
Set wb1 = Workbooks("Power Query Meijer_Walmart_Total US xAOC.xlsm")
Set ws1 = wb1.Worksheets("PQ Total US")
With ws1
'Do something
End with
I am trying to copy a range from one workbook to another, using the code below. The other posts similar to this issue on here and elsewhere seem to be confined to specific syntax errors which aren't relevant (as far as I'm aware) to my specific case (last line of my code). For anyone generally trying to copy and paste a given range (hard-coded) between workbooks, this may be relevant:
Sub ImportT12Accounts()
'
' ImportT12Accounts Macro
' Pulls in the list of account numbers from a report of the user's choice.
'
'
Dim fileChoice As Integer
Dim filePath As String
Dim sheetName As Variant
Dim ws0 As Worksheet 'this workbook's 2nd tab
Dim ws1 As Worksheet 'the opened workbook's 2nd tab
Dim wb0 As Workbook 'this workbook (the log)
Dim wb1 As Workbook 'the opened T12 sheet
Dim rng0 As Range 'the range of cells in this workbook's 2nd sheet to be copied to
Dim rng1 As Range 'the range of cells from the openeed workbook to be copied from
Set ws0 = ActiveSheet
Set wb0 = ActiveWorkbook
Set rng0 = Range("B9:B159")
'Find the desired T12 workbook filepath
'only allow the user to select one file
Application.FileDialog(msoFileDialogOpen).AllowMultiSelect = False
'make the file dialog visible to the user
fileChoice = Application.FileDialog(msoFileDialogOpen).Show
'determine what choice the user made
If fileChoice <> 0 Then
'get the file path selected by the user
filePath = Application.FileDialog(msoFileDialogOpen).SelectedItems(1)
End If
'Set variables using the newly-opened workbook
Set wb1 = Workbooks.Open(filePath)
Set ws1 = ActiveSheet
Set rng1 = Range("A9:A159")
'Use the filepath selected by User in formulas to pull the account numbers into this book, in Sheet 2
Workbooks(wb0).Worksheets(ws0).Range(rng1).Value = _
Workbooks(wb1).Worksheets(ws1).Range(rng0).Value
End Sub
When run, it throws the "Run-time error '13': Type mismatch" error on the last line, "Workbooks(wb0)...Range(rng0).Value".
I have tried subbing out this copy-paste method for a few others, without avail. For example, I have tried subbing out the range variables .Range(rng0) and .Range(rng1) with/for .Range("A9:A159") and .Range("B9:B159") directly, but get the same error.
Another example of a method I tried is:
Workbooks(wb1).Worksheets(ws1).Range(rng1).Copy
Destination:=Workbooks(wb0).Worksheets(ws0).Range(rng0)
But this gave me the same error.
I have a feeling the mismatch is being caused by one of the workbook or worksheet variables, however, I can't figure out why this would be the case. From what I can tell, it is fine to pass workbook, worksheet, and range variables into their respective methods.
This seems to be a misunderstanding of objects. The error occurs because you are passing the objects in to a string field which results in "type mismatch". The objects can be called directly and they are fully qualified as declared. You don't need to stack them like that.
Sub ImportT12Accounts()
'
' ImportT12Accounts Macro
' Pulls in the list of account numbers from a report of the user's choice.
'
'
Dim fileChoice As Integer
Dim filePath As String
Dim sheetName As Variant
Dim ws0 As Worksheet 'this workbook's 2nd tab
Dim ws1 As Worksheet 'the opened workbook's 2nd tab
'Dim wb0 As Workbook 'this workbook (the log)
Dim wb1 As Workbook 'the opened T12 sheet
Dim rng0 As Range 'the range of cells in this workbook's 2nd sheet to be copied to
Dim rng1 As Range 'the range of cells from the openeed workbook to be copied from
'Set wb0 = ActiveWorkbook
Set ws0 = ActiveSheet
Set rng0 = ws0.Range("B9:B159")
'Find the desired T12 workbook filepath
'only allow the user to select one file
Application.FileDialog(msoFileDialogOpen).AllowMultiSelect = False
'make the file dialog visible to the user
fileChoice = Application.FileDialog(msoFileDialogOpen).Show
'determine what choice the user made
If fileChoice <> 0 Then
'get the file path selected by the user
filePath = Application.FileDialog(msoFileDialogOpen).SelectedItems(1)
End If
'Set variables using the newly-opened workbook
Set wb1 = Workbooks.Open(filePath)
Set ws1 = ActiveSheet
Set rng1 = ws1.Range("A9:A159")
'Use the filepath selected by User in formulas to pull the account numbers into this book, in Sheet 2
rng1.Value = rng0.Value
End Sub
I am trying to execute a macro on a workbook that is downloaded from the web daily.
It has only one worksheet that changes names accordingly with the date downloaded (say: "vendas 201709294524455").
I need to set this worksheet as a variable. How can I do that with this dynamic name change?
I tried:
Dim Sh1 As Worksheet
Dim Sh2 As Worksheet
Dim FindCell As Range
Set Sh2 = ThisWorkbook.Worksheets("book1")
Set Sh1 = Workbooks("vendas.xlsm").Worksheets("*vendas*")
LastRow = Sh2.Range("d65536").End(xlUp).Row
'...rest of the code
As it only has one worksheet just use:
Set Sh1 = Workbooks("vendas.xlsm").Worksheets(1)
The Worksheets() allows for the index or a string name. With only one sheet the index is always 1 of that one sheet. See: https://msdn.microsoft.com/en-us/vba/excel-vba/articles/worksheet-object-excel
This will set Sh1 to the first worksheet in the workbook regardless of the name.
Scott Craner's solution is perfect for you. But just for anyone in future -- this is how you would do it if you want to avoid using the worksheet index (which changes if you change the order of the worksheets). Only worth using this method if you have more than one worksheet.
Sub SetWorksheet()
Dim ws As Worksheet, targetWorksheet As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name Like "*test*" Then
Set targetWorksheet = ws
Exit For
End If
Next ws
'use targetWorksheet
MsgBox targetWorksheet.Name
End Sub
If there are multiple sheets like "test" (in this example), you will get the first one.
I know this might come off as a trivial question, but I can't seem to declare a workbook or a worksheet as a variable in VBA. I have the following code, but I can't figure out what I am doing wrong, it should be straight forward. Normally I don't have any problems declaring variables such as Dim i As Integer etc.
sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
Set ws = Sheet("name")
wb.ws.Select
End Sub
When I run the above code, I receive a type missmatch error.
Use Sheets rather than Sheet and activate them sequentially:
Sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
Set ws = Sheets("Sheet1")
wb.Activate
ws.Select
End Sub
If the worksheet you want to retrieve exists at compile-time in ThisWorkbook (i.e. the workbook that contains the VBA code you're looking at), then the simplest and most consistently reliable way to refer to that Worksheet object is to use its code name:
Debug.Print Sheet1.Range("A1").Value
You can set the code name to anything you need (as long as it's a valid VBA identifier), independently of its "tab name" (which the user can modify at any time), by changing the (Name) property in the Properties toolwindow (F4):
The Name property refers to the "tab name" that the user can change on a whim; the (Name) property refers to the code name of the worksheet, and the user can't change it without accessing the Visual Basic Editor.
VBA uses this code name to automatically declare a global-scope Worksheet object variable that your code gets to use anywhere to refer to that sheet, for free.
In other words, if the sheet exists in ThisWorkbook at compile-time, there's never a need to declare a variable for it - the variable is already there!
If the worksheet is created at run-time (inside ThisWorkbook or not), then you need to declare & assign a Worksheet variable for it.
Use the Worksheets property of a Workbook object to retrieve it:
Dim wb As Workbook
Set wb = Application.Workbooks.Open(path)
Dim ws As Worksheet
Set ws = wb.Worksheets(nameOrIndex)
Important notes...
Both the name and index of a worksheet can easily be modified by the user (accidentally or not), unless workbook structure is protected. If workbook isn't protected, you simply cannot assume that the name or index alone will give you the specific worksheet you're after - it's always a good idea to validate the format of the sheet (e.g. verify that cell A1 contains some specific text, or that there's a table with a specific name, that contains some specific column headings).
Using the Sheets collection contains Worksheet objects, but can also contain Chart instances, and a half-dozen more legacy sheet types that are not worksheets. Assigning a Worksheet reference from whatever Sheets(nameOrIndex) returns, risks throwing a type mismatch run-time error for that reason.
Not qualifying the Worksheets collection is an implicit ActiveWorkbook reference - meaning the Worksheets collection is pulling from whatever workbook is active at the moment the instruction is executing. Such implicit references make the code frail and bug-prone, especially if the user can navigate and interact with the Excel UI while code is running.
Unless you mean to activate a specific sheet, you never need to call ws.Activate in order to do 99% of what you want to do with a worksheet. Just use your ws variable instead.
Third solution:
I would set ws to a sheet of workbook wb as the use of Sheet("name") always refers to the active workbook, which might change as your code develops.
sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
'be aware as this might produce an error, if Shet "name" does not exist
Set ws = wb.Sheets("name")
' if wb is other than the active workbook
wb.activate
ws.Select
End Sub
Just coming across the same problem.
What you need to do is to declare ws as Object
Also it should be:
Set ws = wb.Sheets("Sheet1")
And should not be:
Set ws = Sheet("Sheet1")
The code below are working to me.
sub kl()
Dim wb As Workbook
Dim ws As Object
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")
MsgBox ws.Name
End Sub
Try changing the name of the variable as sometimes it clashes with other modules/subs
Dim Workbk As Workbook
Dim Worksh As Worksheet
But also, try
Set ws = wb.Sheets("name")
I can't remember if it works with Sheet
to your surprise, you do need to declare variable for workbook and worksheet in excel 2007 or later version. Just add single line expression.
Sub kl()
Set ws = ThisWorkbook.Sheets("name")
ws.select
End Sub
Remove everything else and enjoy.
But why to select a sheet? selection of sheets is now old fashioned for calculation and manipulation.
Just add formula like this
Sub kl()
Set ws = ThisWorkbook.Sheets("name")
ws.range("cell reference").formula = "your formula"
'OR in case you are using copy paste formula, just use 'insert or formula method instead of ActiveSheet.paste e.g.:
ws.range("your cell").formula
'or
ws.colums("your col: one col e.g. "A:A").insert
'if you need to clear the previous value, just add the following above insert line
ws.columns("your column").delete
End Sub
I had the same issue. I used Worksheet instead of Worksheets and it was resolved. Not sure what the difference is between them.
Dim ws as Object
Set ws = Worksheets("name")
when declaring the worksheet as worksheet instead of an ojbect I had issues working with OptionButtons (Active X) in this worksheet (I guess the same will be with any Active-X element. When declared as object everything works fine.
Lots of answers above! here is my take:
Sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set ws = Sheets("name")
Set wb = ThisWorkbook
With ws
.Select
End With
End Sub
your first (perhaps accidental) mistake as we have all mentioned is "Sheet"... should be "Sheets"
The with block is useful because if you set wb to anything other than the current workbook, it will ececute properly