Copy sheet and get resulting sheet object?

后端 未结 13 1993
醉梦人生
醉梦人生 2020-11-28 12:21

Is there any easy/short way to get the worksheet object of the new sheet you get when you copy a worksheet?

ActiveWorkbook.Sheets(\         


        
相关标签:
13条回答
  • 2020-11-28 13:12

    Updated with suggestions from Daniel Labelle:

    To handle possible hidden sheets, make the source sheet visible, copy it, use the ActiveSheet method to return the reference to the new sheet, and reset the visibility settings:

    Dim newSheet As Worksheet
    With ActiveWorkbook.Worksheets("Sheet1")
        .Visible = xlSheetVisible
        .Copy after:=someSheet
        Set newSheet = ActiveSheet
        .Visible = xlSheetHidden ' or xlSheetVeryHidden
    End With
    
    0 讨论(0)
  • 2020-11-28 13:12

    As already mentioned here, copy/paste the sheet to the very left (index = 1), then assign it to a variable, then move it where you would like.

    Function CopyWorksheet(SourceWorksheet As Worksheet, AfterDestinationWorksheet As Worksheet) As Worksheet
    
        Dim DestinationWorkbook As Workbook
        Set DestinationWorkbook = AfterDestinationWorksheet.Parent
    
        Dim FirstSheetVisibility As XlSheetVisibility
        FirstSheetVisibility = DestinationWorkbook.Sheets(1).Visible
    
        DestinationWorkbook.Sheets(1).Visible = xlSheetVisible
        SourceWorksheet.Copy Before:=DestinationWorkbook.Sheets(1)
        DestinationWorkbook.Sheets(2).Visible = FirstSheetVisibility
    
        Dim NewWorksheet As Worksheet
        Set NewWorksheet = DestinationWorkbook.Sheets(1)
    
        NewWorksheet.Move After:=AfterDestinationWorksheet
    
        Set CopyWorksheet = NewWorksheet
    
    End Function
    
    0 讨论(0)
  • 2020-11-28 13:16

    Wanted to share my simple solution to this with the following code

    Sub copy_sheet(insheet As String, newsheet As String)
    Application.DisplayAlerts = False
    On Error Resume Next
    ThisWorkbook.Sheets(newsheet).Delete
    ThisWorkbook.Sheets(insheet).Copy before:=ThisWorkbook.Sheets(1)
    For Each ws In ThisWorkbook.Worksheets
        If (InStr(ws.Name, insheet) > 0 And InStr(ws.Name, "(") > 0) Then
            ThisWorkbook.Sheets(ws.Name).Name = newsheet
            Exit For
        End If
    Next
    Application.DisplayAlerts = True
    End Sub
    

    Whenever you copy a sheet, the resulting "copied" sheet ALWAYS has the name of the original sheet, and a bracketed number. As long as none of your original sheets contain bracketed number names, this will work 100% of the time.

    It copies the sheet, then loops through all sheet names looking for one that 1) contains the original name and 2) has a bracketed number, and then renames the sheet

    0 讨论(0)
  • 2020-11-28 13:18

    Based on Trevor Norman's method, I've developed a function for copying a sheet and returning a reference to the new sheet.

    1. Unhide the last sheet (1) if not visible
    2. Copy the source sheet (2) after the last sheet (1)
    3. Set the reference to the new sheet (3), i.e. the sheet after the last sheet (1)
    4. Hide the last sheet (1) if necessary

    Code:

    Function CopySheet(ByRef sourceSheet As Worksheet, Optional ByRef destinationWorkbook As Workbook) As Worksheet
    
        Dim newSheet As Worksheet
        Dim lastSheet As Worksheet
        Dim lastIsVisible As XlSheetVisibility
    
        If destinationWorkbook Is Nothing Then Set destinationWorkbook = sourceSheet.Parent
    
        With destinationWorkbook
            Set lastSheet = .Worksheets(.Worksheets.Count)
        End With
    
        ' store visibility of last sheet
        lastIsVisible = lastSheet.Visible
        ' make the last sheet visible
        lastSheet.Visible = xlSheetVisible
    
        sourceSheet.Copy After:=lastSheet
        Set newSheet = lastSheet.Next
    
        ' restore visibility of last sheet
        lastSheet.Visible = lastIsVisible
    
        Set CopySheet = newSheet
    
    End Function
    

    This will always insert the copied sheet at the end of the destination workbook.

    After this, you can do any moves, renames, etc.

    Usage:

    Sub Sample()
    
        Dim newSheet As Worksheet
    
        Set newSheet = CopySheet(ThisWorkbook.Worksheets("Template"))
    
        Debug.Print newSheet.Name
    
        newSheet.Name = "Sample" ' rename new sheet
        newSheet.Move Before:=ThisWorkbook.Worksheets(1) ' move to beginning
    
        Debug.Print newSheet.Name
    
    End Sub
    

    Or if you want the behaviour/interface to be more similar to the built-in Copy method (i.e. before/after), you could use:

    Function CopySheetTo(ByRef sourceSheet As Worksheet, Optional ByRef beforeSheet As Worksheet, Optional ByRef afterSheet As Worksheet) As Worksheet
    
        Dim destinationWorkbook As Workbook
        Dim newSheet As Worksheet
        Dim lastSheet As Worksheet
        Dim lastIsVisible As XlSheetVisibility
    
        If Not beforeSheet Is Nothing Then
            Set destinationWorkbook = beforeSheet.Parent
        ElseIf Not afterSheet Is Nothing Then
            Set destinationWorkbook = afterSheet.Parent
        Else
            Set destinationWorkbook = sourceSheet.Parent
        End If
    
        With destinationWorkbook
            Set lastSheet = .Worksheets(.Worksheets.Count)
        End With
    
        ' store visibility of last sheet
        lastIsVisible = lastSheet.Visible
        ' make the last sheet visible
        lastSheet.Visible = xlSheetVisible
    
        sourceSheet.Copy After:=lastSheet
        Set newSheet = lastSheet.Next
    
        ' restore visibility of last sheet
        lastSheet.Visible = lastIsVisible
    
        If Not beforeSheet Is Nothing Then
            newSheet.Move Before:=beforeSheet
        ElseIf Not afterSheet Is Nothing Then
            newSheet.Move After:=afterSheet
        Else
            newSheet.Move After:=sourceSheet
        End If
    
        Set CopySheetTo = newSheet
    
    End Function
    
    0 讨论(0)
  • 2020-11-28 13:18

    I've been trying to create a reliable generic "wrapper" function for the sheet.Copy method for re-use across multiple projects for years.

    I've tried several of the approaches here and I've found only Mark Moore's answer to be a reliable solution across all scenarios. Ie the one using the "Template (2)" name to identify the new sheet.

    In my case, any solution using the "ActiveSheet method" was useless as in some instances the target workbook was in a non-Active or hidden Workbook.

    Similarly, some of my Workbooks have hidden sheets intermixed with visible sheets in various locations; at the beginning, in the middle, at the end; and therefore I found the solutions using the Before: and After: options also unreliable depending on the ordering of the visible and hidden sheets, along with the additional factor when the source sheet is also hidden.

    Therefore after several re-writes, I've ended up with the following wrapper function:

    '***************************************************************************
    'This is a wrapper for the worksheet.Copy method.
    '
    'Used to create a copy of the specified sheet, optionally set it's name, and return the new
    ' sheets object to the calling function.
    '
    'This routine is needed to predictably identify the new sheet that is added. This is because
    ' having Hidden sheets in a Workbook can produce unexpected results in the order of the sheets,
    ' eg when adding a hidden sheet after the last sheet, the new sheet doesn't always end up
    ' being the last sheet in the Worksheets collection.
    '***************************************************************************
    Function wsCopy(wsSource As Worksheet, wsAfter As Worksheet, Optional ByVal sNewSheetName As String) As Worksheet
    
        Dim Ws              As Worksheet
    
        wsSource.Copy After:=wsAfter
        Set Ws = wsAfter.Parent.Sheets(wsSource.Name & " (2)")
    
        'set ws Name if one supplied
        If sNewSheetName <> "" Then
            Ws.Name = sNewSheetName
        End If
        Set wsCopy = Ws
    End Function
    

    NOTE: Even this solution will have issues if the source sheet's Name is more than 27 chars, as the maximum sheet name is 31, but that is usually under my control.

    0 讨论(0)
  • 2020-11-28 13:19

    Another solution I used would be to copy the sheet to a place where you know its index, aka first. There you can easily have a reference to it for whatever you need, and after that you can move it freely to where you want.

    Something like this:

    Worksheets("Sheet1").Copy before:=Worksheets(1)
    set newSheet = Worksheets(1)
    newSheet.move After:=someSheet
    
    0 讨论(0)
提交回复
热议问题