Copying a complete sheet from one Workbook to another looks like a simple task in the first place. A copy may however hav links back to the source which Microsoft tells "works as designed". The function below avoids this. The only precondition: The sheet must not already exist in the target Workbook.
Public Function WshCopyFromToWrkbk(ByVal wbkSource As Workbook, _
ByVal wbkTarget As Workbook, _
ByVal sWshCodeName As String) As Boolean
' -------------------------------------------------------------------------
' Copies the sheet named 'sWshCodeName' from the 'wbkSource' to the
' 'wbkTarget' Workbook. Prevents copying links back to the source, by
' moving it from a temporary copy instead. Prevents close compile errors
' due to the missing Worksheet by removing all copy code lines.
' Returns FALSE when executed with an error.
' || Cannot be used along with the Import of an exported sheet since this
' || would just create a Class Module.
' -----------------------------------------------------------------
Const sNameRefErr As String = "#REF"
Const sWbkNmTmpSffx As String = "_temp_"
Const sDot As String = "."
Dim bEvents As Boolean
Dim nm As Name
Dim sWbkNm As String
Dim sWbkNmTmp As String
Dim sWbkNmTmpFull As String
Dim vbc As VBComponent
Dim wbkTemp As Workbook
Dim wsh As Worksheet
On Error GoTo on_error
WshCopyFromToWrkbk = False
'~~> Create temporary copy of the source Workbook
With wbkSource
sWbkNm = Left(.Name, (InStrRev(.Name, sDot, -1, vbTextCompare) - 1))
sWbkNmTmp = sWbkNm & sWbkNmTmpSffx
sWbkNmTmpFull = Replace(.FullName, sWbkNm, sWbkNmTmp)
With New FileSystemObject
If .FileExists(sWbkNmTmpFull) Then .DeleteFile sWbkNmTmpFull
End With
.SaveCopyAs sWbkNmTmpFull
End With
Application.DisplayAlerts = False
bEvents = Application.EnableEvents
Application.EnableEvents = False
Set wbkTemp = Workbooks.Open(sWbkNmTmpFull)
With wbkTemp
If .Sheets.Count = 1 Then .Sheets.Add ' The very last sheet cannot be moved!
For Each wsh In .Sheets
If wsh.CodeName = sWshCodeName Then
wsh.Move After:=wbkTarget.Sheets(wbkTarget.Sheets.Count)
For Each nm In wbkTarget.Names
'~~> Remove all range names with a reference error caused by the sheet move
If InStr(nm.Value, sNameRefErr) Then
nm.Delete
End If
Next nm
Exit For
End If
Next wsh
'~~> Remove all code lines in the temporary Workbook and close it
For Each vbc In .VBProject.VBComponents
With vbc.CodeModule
If .CountOfLines > 0 Then .DeleteLines .CountOfLines
End With
Next vbc
.Close SaveChanges:=False
End With
With New FileSystemObject
.DeleteFile sWbkNmTmpFull
End With
Application.EnableEvents = bEvents
WshCopyFromToWrkbk = True
Exit Function
on_error:
Debug.Print "Error in '<code module>.WshCopyFromToWrkbk'! (" & sWshCodeName & ")"
End Function
The function is part of my Code Module Management, where it mimics what Export, Remove, Import does to transfer a non Data Module (Class Module, Standard Module, and UserForm).
Bookmarks