creating new worksheet from workbook in VBA (Excel) - excel

If WSheetFound Then 'if WSheetFound = True
'copy and paste the record to the relevant worksheet, in the next available row
internal_numberName.Offset(0, -3).Resize(1, 10).Copy Destination:=Worksheets(internal_numberName.Value).Range("A1").End(xlDown).Offset(1, 0)
Else 'if WSheetFound = False
Set NewWSheet = Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)) ' insert a new Worksheet
NewWSheet.Name = internal_numberName 'named after that branch
DataWSheet.Range("A1", DataWSheet.Range("A1").End(xlToRight)).Copy Destination:=NewWSheet.Range("A1") 'and copy the headings to it
internal_numberName.Offset(0, -3).Resize(1, 10).Copy Destination:=NewWSheet.Range("A2") ' then copy and paste the record to i
End If
while Heading is getting created, its failing when trying to add content from A2, can anyone help me on this

Adding a New Worksheet If It Doesn't Exist
The only error I could produce was when internal_numberName contained a number, then the first line in the 'If' statement would fail which is easily avoided with ...Worksheets(CStr(internal_numberName.Value))....
These 'unexplained' errors often happen when there is an On Error Resume Next placed somewhere before the code. If that is the case, remove it because it 'hides' one or several errors previously occurring.
If the posted code doesn't help, you will need to reveal more of the code, best all of it.
The following code eliminates the need for a function or whatever you're using to determine if the destination worksheet already exists.
Option Explicit
Sub Test()
Dim DataWSheet As Worksheet ' Source Worksheet
Set DataWSheet = ThisWorkbook.Worksheets("Sheet1")
Dim internal_numberName As Range
Set internal_numberName = DataWSheet.Range("D2")
' The above is irrelevant for your code, it's just for testing purposes.
Dim NewName As String: NewName = CStr(internal_numberName.Value)
Dim NewWSheet As Worksheet ' Destination Worksheet
Dim srg As Range ' Source Range
Dim dfCell As Range ' Destination First Cell
' Reference the destination worksheet.
' Attempt to reference the worksheet.
Set NewWSheet = Nothing ' necessary if in a loop
On Error Resume Next ' defer error trapping
Set NewWSheet = ThisWorkbook.Worksheets(NewName)
On Error GoTo 0 ' stop error trapping
If NewWSheet Is Nothing Then ' worksheet doesn't exist
Set NewWSheet = ThisWorkbook.Worksheets _
.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
NewWSheet.Name = NewName
DataWSheet.Range("A1", DataWSheet.Cells(1, DataWSheet.Columns.Count) _
.End(xlToLeft)).Copy Destination:=NewWSheet.Range("A1")
'Else ' worksheet exists; do nothing
End If
' Copy
Set srg = internal_numberName.Offset(0, -3).Resize(1, 10)
Set dfCell = NewWSheet.Cells(NewWSheet.Rows.Count, "A") _
.End(xlUp).Offset(1, 0)
srg.Copy dfCell
End Sub

Related

excel vba code error(subscript out of range)

Hi all I had a code in excel vba that makes me able to change sheet name according to cell value i right click on sheet name then select (view code ) then paste the code it worked well with the sheet i did a simple macro that copy the sheet content into another new sheet then paste the code that changes the sheet name with the cell value but i got an error i just need a macro that add new sheet and copy the current sheet content into the new and make the sheet name dependent on cell value (b3)
i have 0 experience in visual basic
here is some screenshots
thanks for helping me
this the sheet name code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B3")) Is Nothing Then
ActiveSheet.Name = ActiveSheet.Range("B3")
End If
End Sub
i have already explained that THAT
Create a Copy of the Active Sheet
Copy this code into a standard module, e.g. Module1.
Option Explicit
Sub CopyActiveSheet()
' In the worst case scenario, you'll end up with an additional worksheet
' that could not be renamed. If you want to keep this worksheet,
' set DeleteIfCannotRename to False.
Const DeleteIfCannotRename As Boolean = True
' Invalidate the active sheet.
Dim sh As Object: Set sh = ActiveSheet
If sh Is Nothing Then Exit Sub ' no visible workbooks open
If Not TypeOf sh Is Worksheet Then Exit Sub ' not a worksheet
' Reference the source worksheet.
Dim sws As Worksheet: Set sws = ActiveSheet
' Create a copy.
sws.Copy After:=sws
' Reference the copy.
Dim dws As Worksheet: Set dws = ActiveSheet
' Write the value form 'B3' to a variable.
Dim dName As String: dName = CStr(dws.Range("B3").Value)
Dim ErrNumber As Long
' Prevent error if a sheet with the same name already exists
' or the value in 'B3' doesn't contain a valid worksheet name.
On Error Resume Next ' turn on error-trapping
' Attempt to rename.
dws.Name = dName
ErrNumber = Err.Number ' store the error number in a variable
On Error GoTo 0 ' turn off error trapping
' Delete and inform. Out-comment or delete the 'MsgBox' line(s)
' if the message box is too annoying.
If DeleteIfCannotRename Then ' will delete
If ErrNumber <> 0 Then
Application.DisplayAlerts = False
dws.Delete
Application.DisplayAlerts = True
MsgBox "Could not rename to '" & dName & "' so it got deleted.", _
vbCritical, "CopyActivesheet"
End If
Else ' will not delete
MsgBox "Could not rename to '" & dName & "'.", _
vbCritical, "CopyActivesheet"
End If
End Sub

VBA Excel - copy object to last active sheet

I have an object located on a different sheet, which I would like to copy to the last active sheet. Unfortunately, the code I have throws an error:
Object doesn't support this property or method
Sub AddCabinet()
Dim MooSheet, CurrentSheet As Worksheet
Set CurrentSheet = ThisWorkbook.ActiveSheet
Set MooSheet = ThisWorkbook.Sheets("Cab Templates")
MooSheet.Shapes.Range(Array("VHPOPA")).Select
Selection.Copy
CurrentSheet.Range("A1").Paste
End Sub
How can I copy an object to my previous current sheet? I have a few sheets with the same buttons.
.paste is a worksheet method, not a range method, that is where the error is coming from.
We can remove all the Selects to make this a bit cleaner.
Dim MooSheet As Worksheet, CurrentSheet As Worksheet
Set CurrentSheet = ThisWorkbook.ActiveSheet
Set MooSheet = ThisWorkbook.Sheets("Cab Templates")
MooSheet.Shapes("VHPOPA").Copy
CurrentSheet.Paste
Copy Shapes
Can you even get rid of Select and Activate when copying multiple shapes? I couldn't.
My idea was to copy the shape(s) and restore the worksheets initial selections.
The array is useful to copy multiple shapes. Note that if you don't explicitly use the array function as the parameter for the Shape.Range property, you need to evaluate the array by putting it into parentheses, if its variable is declared as a variant without parentheses i.e.:
Dim shpArr() As Variant... sws.Shapes.Range(shpArr).Select
' or:
Dim shpArr As Variant ... sws.Shapes.Range((shpArr)).Select
The Flow
Exit if the workbook containing this code (ThisWorkbook) is not the active workbook (ActiveWorkbook). Exit if the active sheet (ActiveSheet) is not a worksheet. Reference the active sheet i.e. the destination worksheet.
Reference the source worksheet. Exit if it's the destination worksheet.
Reference the destination Selection to restore after the job is done. Reference the destination cell. Activate it, if it's not active.
Select the source worksheet. Reference its Selection to restore it after the job is done. Select all shapes whose names are in the array and copy them using Selection.
Activate the destination worksheet and paste. Restore its initial selection using Select.
Select the source workbook to restore its initial selection using Select.
Select the destination worksheet.
Sub AddCabinet()
' Define constants.
Const sName As String = "Cab Templates"
Const dFirstCellAddress As String = "A1"
Dim shpArr() As Variant: shpArr = Array("VHPOPA")
'Dim shpArr() As Variant: shpArr = Array("Oval 1", "Oval 2")
' Reference ThisWorkbook's active sheet, the destination worksheet ('dws').
Dim wb As Workbook: Set wb = ThisWorkbook
If Not wb Is ActiveWorkbook Then Exit Sub ' another workbook is active
If Not TypeOf ActiveSheet Is Worksheet Then Exit Sub ' not a worksheet
Dim dws As Worksheet: Set dws = wb.ActiveSheet ' or 'ActiveSheet'
' Reference the source worksheet ('sws')
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
If sws Is dws Then Exit Sub ' source and destination are the same
'Application.ScreenUpdating = False
' Reference the destination cell ('dCell') and activate if not active.
Dim dSel As Object: Set dSel = Selection ' store
Dim dCell As Range: Set dCell = dws.Range(dFirstCellAddress)
If Not dCell Is ActiveCell Then dCell.Activate ' ensure it's active
' Copy.
sws.Select
Dim sSel As Object: Set sSel = Selection ' store
sws.Shapes.Range(shpArr).Select
Selection.Copy
' Paste.
With dws
.Activate
.Paste
End With
If Not dSel Is Nothing Then dSel.Select ' restore
sws.Select
If Not sSel Is Nothing Then sSel.Select ' restore
dws.Select
'Application.ScreenUpdating = True
End Sub
Before copying the object need to be there in that sheet, solve the problem...
try this...
Sub AddCabinet()
Dim MooSheet, CurrentSheet As Worksheet
Set CurrentSheet = ThisWorkbook.ActiveSheet
Set MooSheet = ThisWorkbook.Sheets("Cab Templates")
MooSheet.Select
MooSheet.Shapes.Range(Array("VHPOPA")).Select
Selection.Copy
CurrentSheet.Select
Range("A1").Select
ActiveSheet.Paste
End Sub
Hope it Helps...

Filtering multiple worksheets in excel based on the cell value

I am using below code to filter all my worksheets based on the selections from the drop down list.
I am using inbuilt auto-filter function but somehow the code is not working.
The list I want to use to filter is in Sheet 2 and I have several worksheets
Any reason??
Sub apply_autofilter_across_worksheets()
Dim xWs As Worksheet
On Error Resume Next
For Each xWs In Worksheets
xWs.Range("A1").AutoFilter 3, Sheet2.Range("C4")
Next
End Sub
A Worksheet Change: Dropdown AutoFilter
Copy the code into the sheet module of Sheet2.
The code runs automatically on each change of the dropdown value.
The code filters all worksheets except the one with the dropdown.
If you clear the dropdown cell, all filters will be cleared (hopefully you don't need to filter blanks).
Feel free to download the file from my Google drive.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
' Define constants.
' Source
Const sddCellAddress As String = "C4"
' Destination
Const dFilterColumn As Long = 3
Const dFirstCellAddress As String = "A1"
' Reference the source dropdown cell ('sddCell').
Dim sddCell As Range: Set sddCell = Me.Range(sddCellAddress)
' Check if the value in the dropdown cell was not changed.
If Intersect(sddCell, Target) Is Nothing Then Exit Sub
' Write the source worksheet's name ('sName') to a variable.
Dim sName As String: sName = Me.Name
' Write the criterion converted to a string to a variable ('sCriterion').
Dim sCriterion As String: sCriterion = CStr(sddCell.Value)
' Determine if the dropdown is not blank and write the information
' to a boolean variable ('DropDownIsNotBlank').
' This will be used to clear the filters when the dropdown is blank.
Dim DropDownIsNotBlank As Boolean
If Len(sCriterion) > 0 Then DropDownIsNotBlank = True
' Reference the workbook ('wb').
Dim wb As Workbook: Set wb = Me.Parent ' (or 'Set wb = ThisWorkbook')
' Declare additional variables.
Dim dws As Worksheet ' Destination Worksheet
Dim drg As Range ' Destination Range
' Loop through all worksheets in the workbook...
' (Reference each worksheet in the workbook...)
For Each dws In wb.Worksheets
' Check if the current worksheet is not the source worksheet.
If dws.Name <> sName Then ' is not the source worksheet
' Clear any previous filters.
If dws.FilterMode Then dws.ShowAllData
' Check if the dropdown is not blank
If DropDownIsNotBlank Then
' Reference the destination range ('drg').
Set drg = dws.Range(dFirstCellAddress).CurrentRegion
' Check if the destination range has enough columns.
If drg.Columns.Count >= dFilterColumn Then ' enough columns
' Apply the filter.
drg.AutoFilter dFilterColumn, sCriterion
'Else ' not enough columns; do nothing
End If
'Else ' dropdown is blank (previous filters cleared); do nothing
End If
'Else ' is the source worksheet; do nothing
End If
Next dws
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.

VBA - Unable to Set Worksheet Variable

I'm new to VBA but I'm not new to scripting languages. I have a problem with setting a worksheet variable for some reason in this routine. The same syntax works in other routines but for some reason it won't in this one.
Can someone explain why my worksheet variable 'wks' will NOT populate? I'm not getting any errors but it will not populate. It remains empty.
The problem is this line "Set wks = .Sheets(strTemplate)". The variable 'strTemplate', when mousing over it DOES indicate the proper template sheet name but the worksheet variable 'wks' never populates.
Here's the subroutine that creates a copy of a template sheet, then renames it in order to be populated with data from the 'Main' sheet. I even put in 'Debug' commands but the one that prints "Sheet =" never executes due to 'wks' being empty.
' REPLACE MAIN WORKSHEET AFTER COPYING
'
Public Sub SheetReplace(strSheetName As String, strTemplate As String)
Dim wks As Worksheet
Debug.Print "Entered SheetReplace"
' We don't want screen updating
Application.ScreenUpdating = False
' Delete the existing Main - Copy if it exists
Application.DisplayAlerts = False 'turn off alerts
On Error Resume Next 'continue execution
Worksheets("Main - Copy").Delete 'delete the worksheet
Err.Clear 'clear error
Application.DisplayAlerts = True 'turn on alerts
With ThisWorkbook
' Duplicate the Main - Tmplt sheet
' Duplicate the template sheet
Set wks = .Sheets(strTemplate)
Debug.Print "Sheet = [" & wks & "]"
' Check sheet visibility
isVisible = (wks.Visible = xlSheetVisible)
' Make the sheet visible if not
If Not isVisible Then wks.Visible = xlSheetVisible
' Copy duplicate to the end of the sheets
wks.Copy After:=.Sheets(strSheetName)
' Change the name of the sheet
ActiveSheet.Name = strSheetName & " - Copy"
' Make the sheet invisible
If isVisible Then ws.Visible = xlSheetHidden
' BEGIN COPYING MAIN SHEET INFO
With Worksheets("Main")
Set srcWorkSheet = Worksheets(ActiveSheet.Name) ' Duplicate the Copy name
lastRowMain = .Cells(.Rows.Count, "A").End(xlUp).Row ' Find the last row used in "Main" sheet
' Copy the ranges that contain daily data.
' Copy the Month
.Range("$C$8").Copy Destination:=Worksheets(ActiveSheet.Name).Range("$C$8")
.Range("$I$11").Copy Destination:=Worksheets(ActiveSheet.Name).Range("$I$11")
.Range("$B15:$I51").Copy Destination:=Worksheets(ActiveSheet.Name).Range("$B15:$I51")
srcWorkSheet.Visible = xlSheetHidden ' Make the copy sheet invisible
' Clear cells (including formatting)
.Range("$C15:$H51").ClearContents
End With
' THIS IS THE END OF THE MAIN COPY
End With
End Sub
Any info would be appreciated. Thanks.
Well apparently I had a syntax error & the 'wks' variable WAS being set, I just needed to reference the 'wks.Name' property. Once I did that the execution continued.
Set wks = .Sheets(strTemplate)
Debug.Print "Sheet = [" & wks.Name & "]" <------ OUTPUT: Sheet = [Main - Copy]
#VBasic2008 : Yep. I didn't see your post until now but thanks for responding with that. You've all been a great help.
Update Workbook
Use Option Explicit.
Use ThisWorkbook if you're doing stuff in the workbook containing the code.
On Error Goto 0 turns off error handling (This was the fatal mistake).
A Quick Fix
Option Explicit
Public Sub SheetReplace(strSheetName As String, strTemplate As String)
Dim wb As Workbook
Set wb = ThisWorkbook
' We don't want screen updating
Application.ScreenUpdating = False
' Delete the existing Main - Copy if it exists
On Error Resume Next 'continue execution
Application.DisplayAlerts = False 'turn off alerts
wb.Worksheets("Main - Copy").Delete 'delete the worksheet
Application.DisplayAlerts = True 'turn on alerts
On Error GoTo 0 'disable error handling
' Duplicate the Main - Tmplt sheet
' Duplicate the template sheet
Dim wks As Worksheet
Set wks = wb.Worksheets(strTemplate)
' Check sheet visibility
Dim isVisible As Boolean
isVisible = (wks.Visible = xlSheetVisible)
' Make the sheet visible if not
If Not isVisible Then
wks.Visible = xlSheetVisible
End If
' Copy duplicate to the end of the sheets
wks.Copy After:=wb.Worksheets(strSheetName)
' Change the name of the sheet
Dim src As Worksheet
Set src = wb.ActiveSheet
src.Name = strSheetName & " - Copy"
' Make the sheet invisible
If isVisible Then wks.Visible = xlSheetHidden
' BEGIN COPYING MAIN SHEET INFO
Dim LastRowMain As Long
With wb.Worksheets("Main")
' Find the last row used in "Main" sheet
LastRowMain = .Cells(.Rows.Count, "A").End(xlUp).Row
' Copy the ranges that contain daily data.
' Copy the Month
.Range("$C$8").Copy Destination:=src.Range("$C$8")
.Range("$I$11").Copy Destination:=src.Range("$I$11")
.Range("$B15:$I51").Copy Destination:=src.Range("$B15:$I51")
' If you only need values, this is more efficient (faster).
'src.Range("$C$8").Value = .Range("$C$8").Value
'src.Range("$I$11").Value = .Range("$I$11").Value
'src.Range("$B15:$I51").Value = .Range("$B15:$I51").Value
' Make the copy sheet invisible
src.Visible = xlSheetHidden
' Clear cells (including formatting)
.Range("$C15:$H51").ClearContents
End With
' THIS IS THE END OF THE MAIN COPY
End Sub

Resources