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
Related
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
So I am trying to write a Macro for Excel, that adds 2 worksheets from an excel file to a new one.
Therefore, I try this:
Sub addfile()
Dim sheet1 As Worksheet
Dim sheet2 As Worksheet
Set sheet1 = Sheets.Add(Type:="C:\Users\Helge\AppData\Roaming\Microsoft\Templates\page1.xltx")
Set sheet2 = Sheets.Add(Type:="C:\Users\Helge\AppData\Roaming\Microsoft\Templates\page2.xltx")
End Sub
When I test it, it imports the first page, but the 2nd page gives me a Runtime error 1004.
Why does this happen?
And is there another way to get 2 sheets from one excel file to another via vba?
Much to my surprise this version of your code actually worked for me.
Sub addfile()
Dim Sheet1 As Worksheet
Dim Sheet2 As Worksheet
Set Sheet1 = Sheets.Add(Type:=Environ("Userprofile") & "\OneDrive\Desktop\Template1.xltx")
Set Sheet2 = Sheets.Add(Type:=Environ("Userprofile") & "\OneDrive\Desktop\Book2.xlsx")
Debug.Print Sheet1.Name, Sheet2.Name
End Sub
The reason for my surprise is that Sheet1 and Sheet2 are the default CodeName for the first and second worksheets in any workbook. Therefore there is a conflict of naming between the Sheet1 in the workbook and the Sheet1 you declare which should come to the surface not later than Debug.Print Sheet1.Name. In fact, it may have. I didn't check which name was printed. But the code didn't crash. Since it crashes on your computer, perhaps you have an older version of Excel. Try to stay clear of variable names that Excel also uses. Or there is something wrong with the path & file name, which is hard to tell in that syntax and therefore kept me fooled for quite some time too.
In fact, I discovered the above only after finding out that my Desktop was on OneDrive and not before I had written the function below which is designed to avoid the use of Sheets.Add. It also has some extras such as being able to specify the sheet to take from the template (you could have one template with 2 or more sheets). You can specify an index number or a sheet name. And the function will give a name to the copy, too, if you specify one.
Private Function AddWorksheet(ByVal Template As String, _
TabId As Variant, _
Optional ByVal TabName As String) As Worksheet
Dim Wb As Workbook
Dim Path As String
Dim FileName As String
Set Wb = ThisWorkbook ' change to suit
' make sure the path ends on "\"
Path = "C:\Users\Helge\AppData\Roaming\Microsoft\Templates\"
With Workbooks.Open(Path & Template)
.Sheets(TabId).Copy After:=Wb.Sheets(Wb.Sheets.Count)
.Close
End With
Set AddWorksheet = ActiveSheet
If Len(TabName) Then ActiveSheet.Name = TabName
End Function
You can call the function from a sub routine like this:-
Sub AddWorksheets()
Dim Tab1 As Worksheet
Dim Tab2 As Worksheet
Application.ScreenUpdating = False
Set Tab1 = AddWorksheet("Page1.xltx", 1, "New Tab")
Set Tab2 = AddWorksheet("Page2.xltx", "Sheet1", "Another new Tab")
Application.ScreenUpdating = True
End Sub
Please observe the difference between the two function calls.
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
I need to select columns on a specific sheet. Somehow this is not working:
Dim ws As Worksheet
Set ws = Worksheets("Mysheet")
ws.Columns("A:S").Select
Selection.EntireColumn.AutoFit
And simple Columns("A:S").Selectdoesn't activate the sheet I need
I tested your code and it works fine as follows.
Sub test()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Mysheet")
ws.Columns("A:S").EntireColumn.AutoFit
End Sub
No need to Select anything, so I put the two statements together without the Select.
I added ThisWorkbook to (more) fully qualify your ws declaration. Make sure the worksheet Mysheet is in ThisWorkbook otherwise change that to state which workbook the sheet resides in.
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