I am trying to copy a worksheet and rename it based on a variable and that is working. The issue is that it changes the name of the template sheet in the process of copying. Any ideas how to fix it?
Sub AddAgent()
Dim wsname As String
Dim lRow As Long
wsname = ActiveWorkbook.Sheets("Summary").Range("E5").Value
Set ws = Sheets("Agent Template")
ws.Copy After:=Sheets("Summary")
Set wsNew = Sheets(Sheets("Summary").Index + 2)
wsNew.Range("C4").Value = wsname
wsNew.Name = wsname
As I understand it, the Copy() function automatically sets the new worksheet as the ActiveSheet. So you wouldn't need to find it by index. You could simply access the properties of the ActiveSheet object:
With ThisWorkbook.Worksheets
.Item("Agent Template").Copy After:=.Item("Summary")
End With
With ThisWorkbook.ActiveSheet
.Name = ThisWorkbook.Worksheets("Summary").Range("E5").Value2
.Range("C4").Value = .Name
End With
If my understanding is correct, then I'd favour this way, as you could lose control of indexing if users start moving sheets around.
You're incrementing the Index too far
Set ws = Sheets("Agent Template")
ws.Copy After:=Sheets("Summary")
Set wsNew = Sheets(Sheets("Summary").Index + 1)
Note you can get unpredictable results if any sheets are hidden:
Copy sheet and get resulting sheet object?
Related
Im attempting a bit of code that creates a sheet with a name set by a variable, and then formatting this new sheet by copy/pasting all the cells from a master to this new sheet. The issue I'm having is referring to this new sheet once it's created as the title is stored in a variable.
Currently, my code is as below, everything works except for the last line where I'm attempting to select the newly created worksheet by referring to it by the variable name.
Sub Create_New_Sheet()
Dim title As String
title = Sheets("config").range("A3 ").Value & "_" & Sheets("config").range("B3 ").Value & "_" & "Calculations"
Sheets.Add(Before:=Sheets("Results")).Name = title
Sheets("Calc_master").UsedRange.Copy
Sheets("title").range("A1").Paste
End Sub
Is there a way to select the sheet using the variable? I haven't been able to find anything to suggest it can.
After adding or copying a worksheet the new worksheet will be the activesheet.
But consider copying the calc_master-sheet - no need to copy/paste the usedrange:
Function get_New_Sheet() as Worksheet
Dim title As String
Dim wsConfig As Worksheet, wsMaster as Worksheet
With ThisWorkbook
Set wsConfig = .Worksheets("Config")
With wsConfig
title = .Range("A3") & "_" & .Range("B3") & "_Calculations"
End With
Set wsMaster = .Worksheets("Calc_master")
wsMaster.Copy before:=.Worksheets("Results")
End With
ActiveSheet.Name = title
Set get_New_Sheet = ActiveSheet
End Function
Within your larger scope:
Public Sub doSomething
Dim wsNew as worksheet
Set wsNew = get_New_Sheet
wsNew.Range("A1") = "xxx"
End Sub
I have a small app containing about 20 subs which runs perfectly... Every other time.
It fails, in the sub ImportData, the first time I add a code name to a newly created sheet. on the following line:
ThisWorkbook.VBProject.VBComponents(wsTarget.CodeName).Name = "Customers"
The code below contains three subs which which can recreate the issue. Important note: I can run the sub ImportData as many times in a row without any issues but if I call the sub "Sync()" twice in a row it will fail on the second attempt but works fine on the third attempt and so on (Maybe it doesn't like odd numbers..)
Any ideas as to why this is happening would be greatly appreciated.
FYT: I am running this code in Excel for Mac
Public LastRow As Long
Private wks As Worksheet
Sub Sync()
Call ImportData
Call SyncBoth
End Sub
Public Sub ImportData()
'++++++++++++++++++++++++++++++++++++++++++++++++++++++
'+++++ 1. ImportData will allow user to select file to import data from
'+++++ 2. Copy both the Customers and Vendors data to their respective sheets
'++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dim wsSource As Worksheet
Dim wsTarget As Worksheet
Dim LastRow As Long
Dim MaxDate As Date
Dim ShCount As Integer
Dim SourceFile As String
SourceFile = "/Users/phild/Documents/RTPro/Customer and Vendor Raw Sync.xlsm"
Dim SourceWb As Workbook
Set SourceWb = Workbooks.Open(SourceFile)
Dim TargetWb As Workbook
Set TargetWb = ThisWorkbook
Dim sheet As Worksheet
For ShCount = 1 To 2
Select Case ShCount
Case 1
Set wsSource = SourceWb.Worksheets("Sheet1") 'Set Worksheet to copy data from
ThisWorkbook.Sheets("Customers").Delete 'Delete old Customer worksheet in this worksheet
Set sheet = ThisWorkbook.Sheets.Add 'Create New Customer woeksheet in this woekbook
sheet.Name = "Customers" 'Name new Customer worksheet
Set wsTarget = ThisWorkbook.Worksheets("Customers") 'Set Customers ws as the target ws
Debug.Assert ThisWorkbook.VBProject.Name <> vbNullString '<--Force the VBE to exist. Don't pollute the Immediate window
ThisWorkbook.VBProject.VBComponents(wsTarget.CodeName).Name = "Customers" 'Give Customers a Code name
'THE LINE OF CODE ABOVE RESULTS IN A Runtime error '32813"
' Method 'Name' of object '+VBComponent' failed
' EVERY OTHER TIME I RUN THE SUB Sync()
Case 2
Set wsSource = SourceWb.Worksheets("Sheet3") 'Set Worksheet to copy data from
ThisWorkbook.Sheets("Vendors").Delete 'Delete old Vendors worksheet in this worksheet
Set sheet = ThisWorkbook.Sheets.Add 'Create New Vendor worksheet in this woekbook
sheet.Name = "Vendors" 'Name new Vendor worksheet
Set wsTarget = ThisWorkbook.Worksheets("Vendors") 'Set Customers ws as the target ws
Debug.Assert ThisWorkbook.VBProject.Name <> vbNullString '<--Force the VBE to exist. Don't pollute the Immediate window '
ThisWorkbook.VBProject.VBComponents(wsTarget.CodeName).Name = "Vendors" 'Give Vendors a Code name
End Select
Call CleanTarget(wsTarget)
LastRow = Find_LastRow(wsSource)
wsSource.Range("A1:Z" & LastRow).Copy Destination:=wsTarget.Range("A1")
Next ShCount
SourceWb.Close
End Sub
Sub SyncBoth()
Dim ShCount As Integer
For ShCount = 1 To 2
Select Case ShCount
Case 1
Set wks = Customers 'Work in sheet("Customers")
LastRow = Find_LastRow(wks) 'Last row of "Customers"
Case 2
Set wks = Vendors 'Work in sheet("Vendors")
LastRow = Find_LastRow(wks) 'Last row of "Vendors"
End Select
Debug.Print wks.Name
Next ShCount
'Normally I have about 10 subs here that are called sequentially. But this is enough the cause the errorw
End Sub```
You're modifying the host VBA project at run-time - the code name identifier for Sheet1 is a compile-time, project-global scope object: even if it's not used anywhere, there's a legitimate chance that changing it requires recompiling the project.
So the code runs fine, up until it shoots its own foot off by renaming a global object; the next run now runs fine because now the compiled code matches the actual VBComponent in the project.
Consider having the macro in a separate VBA project, that prompts for which macro-enabled workbook to rename components in: because that VBA project won't be the VBA code that's compiled & running, it should "just work" then.
I am looking to copy a range of data (columns A:M) on a temporary excel worksheet, with a "tmp" prefix into a worksheet designed to crunch all of this data output into a useable report.
Currently, the user will simply manually copy the temporary output into the report making tool, then run the macro.
Is it possible to automate this data input?
Aaron, SO is used for teaching. But, since I got bored, and in case you don't re-post this here, this is an idea of how to accomplish your goal. Keep in mind that with VBA, and probably all other languages, there's 20 different ways to accomplish the same task, but what fits each users unique scenario is what SO likes to resolve. To give you a rolling start and perhaps some motivation...
Option Explicit
Sub CopyStuff()
Dim ws As Worksheet
Dim ws2 As New Worksheet
Dim rngToCopy As Range
Dim ShtName As String
'use ActiveSheet or actual name
Set ws = ActiveSheet
Set rngToCopy = ws.UsedRange.Columns("A:M")
Set ws2 = ThisWorkbook.Worksheets.Add
'gets name for sheet
ShtName = InputBox("Please enter name for Sheet.")
'more properties to fill if needed, or adjust area to copy to
'just an example here
With ws2
.Name = "tmp" & ShtName
rngToCopy.Copy .UsedRange.Columns(.UsedRange.Columns.Count + 1)
End With
'cleanup
Set ws = nothng: Set ws2 = Nothing
Set rngToCopy = Nothing: ShtName = vbNullString
End Sub
Danny,
ExcelVBADude
For some reason, Sheets.copy is making another workbook. I don't know how to fix it. I just want it to copy the first Sheets("New") and paste everything that I have selected over to a new Sheets("New(2)").
Sheets.Copy
Sheets("New").Select
Sheets("New").Copy After:=Sheet1
'****Copy Assessment Date to the Nourish Report Printable****
Sheets("New").Select
Range("C74").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("New (2)").Select
Range("V96").Select
ActiveSheet.Paste
I think the issue is with the Sheets object. In my experience it is better to use the Worksheets object. I would recommend simplifying your code by removing all of the copy and paste / select and just making the cell range take the exact value you want. The Macro Recorder does not do a very a good job of producing efficient code but it certainly does help with syntax and getting you started. Consider the code below to accomplish what you want.
Sub CopySheet()
Dim wb As Workbook, ws As Worksheet, nws As Worksheet
'set up
Set wb = ThisWorkbook
Set ws = wb.Worksheets("New")
'Create a copy of the worksheet
ws.Copy wb.Worksheets(1) 'places the worksheet at the front
Set nws = wb.Worksheets(1) 'References the new front worksheet
'set a name for the new sheet for easy reference
nws.Name = "newSheet" 'set to whatever name you want
'Print out the actual value you want rather than copy and paste.
nws.Range("V96").Value = ws.Range("C74").Value
nws.Activate 'select the new worksheet
End Sub
And here it is without all of the comments
Sub CopySheet()
Dim wb As Workbook, ws As Worksheet, nws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Worksheets("New")
ws.Copy wb.Worksheets(1)
Set nws = wb.Worksheets(1)
nws.Name = "newSheet"
nws.Range("V96").Value = ws.Range("C74").Value
End Sub
Let me know if this works.
I have following code
Set wb = ThisWorkbook`
ComboBox7.RowSource = wb.Worksheets("Sheet5").Range("A2", _
Range("A65536").End(xlUp)).Address
If I don't put wb.Sheets("Sheet5").Select before this line, this code throws error
"Application defined or object-defined error"
I want this code to work without selecting the Sheet5.
If I put ComboBox7.RowSource = wb.Worksheets("Sheet5").Range("A2:A7").Address then it works fine without selecting the sheet5.
Is there any way to use End(xlUp) without selecting the sheet?
Yes it is possible.
Logic: Find the last row and then use that to create a range which you can assign to your combobox.
Is this what you are trying?
Private Sub CommandButton1_Click()
Dim wb As Workbook
Dim ws As Worksheet
Dim lRow As Long
Dim rng As Range
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet5")
With ws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rng = .Range("A1:A" & lRow)
End With
ComboBox5.RowSource = rng.Address
End Sub
The other thing is to do this in one line
Private Sub CommandButton1_Click()
Set wb = ThisWorkbook
Set ws = wb.sheets("sheets5")
ComboBox7.RowSource = ws.Range("A2", ws.Range("A65536").End(xlUp)).Address
The second range thinks it is working from the active sheet, you need to tell it otherwise.
Using With is better but this is one line if you are writing code quickly just to get something done.