How to restrict VBA code to a specific worksheet? - excel

I am trying to restrict the macro to a specific the Test! worksheet When I activate the macro pasted below and I am within the Test! worksheet, the macro works. However, when I try activating the macro on a different sheet, I receive an error. Any idea on what I need to do to modify the VBA code in order for it to be work any other worksheet within the workbook? Thanks
Sub Test ()
' Test Macro
'
' Keyboard Shortcut: Ctrl+Shift+B
'
Range ("Test!B1").Select
Selection.ClearContents
Range ("Test!B2").Select
Selection.ClearContents
Range ("Test!B3").Select
Selection.ClearContents
End Sub

You must reference the worksheet directly:
Dim ws as worksheet
set ws = Thisworkbook.Worksheets("Test")
with ws
.Range("B1:B3").ClearContents
end with
Other notes:
Don't use .Select or Selection. Simply operate on the objects directly.
You have String issues in your original code that would cause compile-time errors (fixed in my code)
You can clear the entire range in one line of code, rather than cell by cell

If the worksheet exists at compile-time in ThisWorkbook (i.e. the same file that's hosting the VBA code), then you don't need to retrieve the sheet at all - not by name, not by index.
VBA is already declaring a global Worksheet object variable for that sheet (and every sheet in ThisWorkbook). Verify the sheet's (Name) property; change it to TestSheet, then you can use TestSheet as an identifier anywhere in your code to refer to that sheet.
TestSheet.Range("B1:B3").ClearContents
And this code will work regardless of whether the user moved the sheet to another index/position in the workbook, or whether the user renamed the sheet's "tab" to something else.
ThisWorkbook.Worksheets(1).Range("B1:B3").ClearContents ' breaks if sheet is moved
ThisWorkbook.Worksheets("Test").Range("B1:B3").ClearContents ' breaks if sheet/tab is renamed

The Basics
If you want to learn something you should study versions 1 and 2, which are elaborate versions of versions 3 and 4 respectively.
Use Option Explicit to quickly find mistakes.
Use constants to be able to quickly change values.
Use object references to not have to type names on and on.
It is assumed that you will copy these codes in any module in the workbook where the worksheet 'Test' resides.
Option Explicit
Sub Test1()
Const cStrWs As String = "Test" 'Worksheet Name
Const cStrRng As String = "B1:B3" 'Range to 'DEL'
Dim oWs As Worksheet 'Worksheet Object
Dim oRng As Range 'Range Object
Set oWs = ThisWorkbook.Worksheets(cStrWs) 'Create a reference to the worksheet
Set oRng = oWs.Range(cStrRng) 'Create a reference to the range
oRng.ClearContents
End Sub
Sub Test2()
Const cStrWs As String = "Test" 'Worksheet Name
Const cStrCell As String = "B1" 'Cell to 'DEL'
Const cLngCells As Long = 3 'Number of cells
Dim oWs As Worksheet 'Worksheet Object
Dim oRng As Range 'Range Object
Set oWs = ThisWorkbook.Worksheets(cStrWs) 'Create a reference to the worksheet
Set oRng = oWs.Range(cStrCell) 'Create a reference to the cell range
oRng.Resize(3, 1).ClearContents
End Sub
Sub Test3()
ThisWorkbook.Worksheets("Test").Range("B1:B3").ClearContents
End Sub
Sub Test4()
ThisWorkbook.Worksheets("Test").Range("B1").Resize(3, 1).ClearContents
End Sub

Related

Sum values from one Worksheet in another Worksheet

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.

How to copy an entire sheets values as static into another sheet using vba

I am trying to take a sheet like:
A3,B3,C3 are the sum of the 2 values above them.
Copy this entire sheet into another sheet with only static values ie the sum formulas are gone and 5,73,55 are just the values.
Public Sub CopyEntireSheetValues()
Sheets("Static Data").Range("A1:M100").Value = Sheets("MAIN").Range("A1:M100").Value
End Sub
This works but ideally, i wouldn't define this range and copy all values from one sheet to another
Here's commented code for how I'd accomplish this task via .UsedRange
Sub CopyEntireSheetValues()
'Define and declare workbook and worksheet variables
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsSrc As Worksheet: Set wsSrc = wb.Worksheets("Main")
Dim wsDst As Worksheet: Set wsDst = wb.Worksheets("Static Data")
'Set the range you want to copy values from
Dim rCopy As Range: Set rCopy = wsSrc.UsedRange
'Bring only the values to the destination sheet
wsDst.Range("A1").Resize(rCopy.Rows.Count, rCopy.Columns.Count).Value = rCopy.Value
End Sub
Two ways. The exact method to do what you want is use the pastespecial method which would be as follows:
Public Sub CopyEntireSheetValues()
Sheets("MAIN").Range("A1:C100").Copy
Sheets("Static Data").Range("A1").PasteSpecial (xlPasteValues)
End Sub
The other is as explained in comment just setting values.
Sheets("Static Data").Range("A1:C100").Value = Sheets("MAIN").Range("A1:C100").Value
In general the setting values is probably the best. The only time I've used the pasteValues is sometimes dates don't quite behave the same when using the second method, but the end result should be the same.
You updated your question, but this could be dynamic (I didn't test).
Public Sub CopyEntireSheetValues()
Sheets("MAIN").UsedRange.Copy
Sheets("Static Data").Range(Sheets("MAIN").UsedRange.Address).PasteSpecial (xlPasteValues)
End Sub

Formula to Value Macro [duplicate]

I am trying to copy data from one worksheet to another. I have a workbook that has about 62 worksheet tabs.
The part that is especially tricky for me is that the worksheet the data needs to be copied to will not always be the same.
I have a dropdown menu that lists 62 different pieces of equipment. This is shown in G1 in the worksheet named "HOME". I want the text to copy over to the correct tab based on the selection.
I figured out how to copy over specific text, when I do this I see the word "TEXT" show up on the specified worksheet.
Sheets(Range("g1").Value).Activate
Range("a1").Value = "TEXT"
I cannot figure out how to copy over G4:G24 from my "HOME" worksheet to another worksheet based on the same drop-down menu.
This is what I tried.
Private Sub CommandButton1_Click()
Worksheets("HOME").Range("g4:g24").Copy
Sheets(Range("g1").Value).Activate
Range("a1").Value = "TEXT"
Sheets(Range("g1").Value).Activate
Range("f4").PasteSpecial
End Sub
Be explicit about workbook and worksheets - never use Range/Cells without qualifying a worksheet (though you can get away with it in a worksheet code module if you're referring to the associated worksheet).
Private Sub CommandButton1_Click()
Dim wb As Workbook, ws As Worksheet
Set wb = ThisWorkbook 'or ActiveWorkbook?
With wb.Worksheets("HOME")
Set ws = wb.Worksheets(.Range("G1").Value) 'create a worksheet reference
ws.Range("A1").Value = "TEXT" '...and use it
.Range("g4:g24").Copy ws.Range("f4")
End With
End Sub
See for example: What is the default scope of worksheets and cells and range?
Generally speaking you have a good start there, but it can be accomplished in much fewer lines with much more speed like this:
Sub ExampleSub()
Dim SheetName As String
SheetName = Worksheets("HOME").Range("A1").Value
Worksheets("HOME").Range("G4:G24").Value = Worksheets(SheetName).Range("G4:G24").Value
End Sub
It's not even necessary to use the variable SheetName, but it can help keep things simple, it can also now be reused later in the subroutine.
An alternative to reference sheets is to make the variable a worksheet:
Sub ExampleSub()
Dim SheetName As Worksheet
Dim HomeSheet As Worksheet
Set HomeSheet = Worksheets("HOME")
Set SheetName = Worksheets(HomeSheet.Range("A1").Value)
HomeSheet.Range("G4:G24").Value = SheetName.Range("G4:G24").Value
End Sub

Variable Range not recognized as a property of Worksheets

I'm trying to use both worksheets and ranges as variables, but I'm having some problems.
If I declare a worksheet as a variable and then use the range property it works just fine.
However, when I declare a variable Range and try to use it reference it, it throws me the error 438, object doesn't have property or method.
Sub try()
Dim ws As Worksheet
Set ws = Worksheets("Code")
ws.Range("A3", "B6").Value = "sheets"
Dim r As Range
Set r = Range("D1", "F3")
Worksheets("DATOS").r.Value = "ranges"
End Sub
My end goal would be to have both the Worksheet and the range as variables, so I could reference it such as
ws.r.Value = "123"
Thanks in advance, I hope my question isn't too basic and you can help me.
When you set a Range object, it is not a universal cell address to be used like what you did, each Range refers to a specific Worksheet that you can see under its Worksheet property. (documentation)
You did not specify the Worksheet in Set r = Range("D1", "F3") so VBA assumes that you are referring to the ActiveSheet which can be anything. (which is also why you are recommended to always fully qualify your range reference)
As mentioned in your comment - Since your objective is to use the same range for multiple worksheets, you can define the range address in a String variable and use that variable as shown below:
Sub try()
Const r As String = "D1:F3"
Worksheets("DATOS").Range(r).Value = "ranges"
Worksheets("Code").Range(r).Value = "ranges"
End Sub
You can't use range variable in this way. Rather qualify range mentioning sheet name. Try below codes.
Try below codes.
Sub try()
Dim ws As Worksheet
Set ws = Worksheets("Code")
ws.Range("A3", "B6").Value = "sheets"
Dim r As Range
Set r = Worksheets("DATOS").Range("D1", "F3")
r = "ranges"
End Sub
It is not possible to refer to the range in the way you want.
If you want to use a VBA variable to refer to ranges, you can do this:
' Get a range
Set Sht1 = ThisWorkbook.Worksheets("Sheet1")
Set Rng1 = Sht.Range("A2:B2")
' Set the contents of another range to the same value
Set Sht2 = ThisWorkbook.Worksheets("Sheet2")
Set Rng2 = Sht2.Range("C2:D2")
Rng2.value = Rng1.Value
You already seem to have a grasp of doing it this way.
If you want to refer to a range by a name, here is a method that creates a named range:
' Delete the named range if it exists and create it again.
Sub CreateNamedRange(Wbk As Workbook, Txt As String, Rng As Range)
On Error Resume Next
Wbk.Names(Txt).Delete
If Err.Number <> 0 Then Err.Clear
On Error GoTo 0
Wbk.Names.Add Txt, Rng
End Sub
Here we create a named range Name1 and retrieve it using Sht.Range("Name1"):
Sub CreateNamedRangeAndUseIt()
Dim Sht As Worksheet
Dim Rng As Range
' Set the value of the range to 42
Set Sht = ThisWorkbook.Worksheets("Sheet2")
Set Rng = Sht.Range("A2")
Rng.Value = 42
' Create a name for the range
CreateNamedRange ThisWorkbook, "Name1", Rng
' Activate some other sheet to make sure it works when the
' sheet with the named range is not active.
ThisWorkbook.Worksheets("Sheet1").Activate
' Get the named range and output the value of the range to the
' immediate window.
Set Rng = Sht.Range("Name1")
' This would also work, even though the named range does not
' exist on Sheet1:
' Set Rng = ThisWorkbook.Worksheets("Sheet1").Range("Name1")
' Or this (provided you don't have several workbooks open and
' another workbook is selected)
' Set Rng = Range("Name1")
Debug.Print Rng.Value
' Then select the range.
' We must activate the sheet first to select ranges in it.
Rng.Worksheet.Activate
Rng.Select
End Sub
The named range will still exist if you close and reopen the workbook, provided you save the workbook before closing it. So you only need to name the range once.

Why am I getting a Subscript Out of Range Error 9 when referencing another Workbook/Worksheet in VBA?

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

Resources