This is bothering me for a years now, I would like to open another workbook using VBA and copy worksheet to the current workbook and close it. Another workbook can be also macro enabled workbook. My method is following:
Application.DisplayAlerts = False
Dim workBookName1 As String
Application.AutomationSecurity = msoAutomationSecurityForceDisable
Application.AutomationSecurity = msoAutomationSecurityLow
Workbooks.Open fileName:="C:\test.xlsm", ReadOnly:=True
workBookName1 = ActiveWorkbook.Name
'some work with copying, filtering, etc.
With Workbooks(workBookName1)
.Close
End With
BUT the issue is that is not bulletproof -> sometimes this procedure closes all opened workbooks.
is there any other way to deal with this, maybe another method to try it?
If you declare and use objects properly, you will not face this problem as you will be working with only those objects. Here is an example
Option Explicit
Dim wbThis As Workbook, wbThat As Workbook
Set wbThis = ThisWorkbook
Set wbThat = Workbooks.Open(Filename:="C:\test.xlsm", ReadOnly:=True)
'
' Do some copying. For example see how I am using the objects below
' wbThat.Sheets("Sheet1").Copy After:=wbThis.Sheets(wbThis.Sheets.Count)
'
'~~> Close specific workbook when you are done
wbThat.Close (False)
Related
I have a workbook with many sheets. I'm trying to copy two sheets together to a new workbook.
I get
Run-time error 13 for type mismatch.
Sub CopyBillStatandCosts()
Dim MyBook As Workbook
Dim NewBook As Workbook
Set MyBook = ThisWorkbook
Workbooks.Add ' Open a new workbook
Set NewBook = ActiveWorkbook
Set MyBook = ActiveWorkbook
Sheets(11).Copy Before:=Workbooks(NewBook).Sheets(1)
Sheets(9).Copy Before:=Workbooks(NewBook).Sheets(1)
Workbooks(NewBook).Sheet1.Delete
End Sub
Update: I figured out the code. But how do I refer to the sheets by their code names, which is best practice? They are sheet9 and sheet 11.
Sub copyBillStatandCosts()
ThisWorkbook.Worksheets(Array("BillStat", "C")).Copy
End Sub
Your second
Set MyBook = ActiveWorkbook
was probably meant to be
MyBook.Activate
although an overall simpler way to do this would be
Sub CopyBillStatandCosts()
Sheets(Array("BillStat", "Costs")).Copy
End Sub
The Copy with no parameter makes the copy in a new workbook.
Copy Worksheets by Code Name in One Go
Sub copyBillStatandCosts()
ThisWorkbook.Worksheets(Array(Sheet9.Name, Sheet11.Name)).Copy
' To continue to work with the new workbook, do the following:
Dim NewBook As Workbook: Set NewBook = ActiveWorkbook
' e.g.:
' NewBook.SaveAs "C:\Test\Test.xlsx", xlOpenXMLWorkbook
' To continue to work with each new worksheet, do the following:
Dim bws As Worksheet: Set bws = NewBook.Worksheets(1)
Dim cws As Worksheet: Set cws = NewBook.Worksheets(2)
' e.g.:
MsgBox NewBook.Name & vbLf & bws.Name & vbLf & cws.Name
End Sub
Why use code names? Now you can rename the two worksheets in the tabs, and the code will still copy the right ones to a new workbook.
Why in one go? If there are references of the worksheets from one to each other they will still work in the new workbook i.e. will not refer to the worksheets in the source workbook.
If you wanna use programmatic names, then just use Name property:
ThisWorkbook.Sheets(Array(sheet9.Name, sheet11.Name)).Copy
I would like to copy a sheet from ActiveWorkbook, to a New Created workbook.
The New created workbook, will contains the copied sheet ONLY.
I also don't want it to open while copiying the sheet. I want to copy the sheet to the new created workbook silently.
If I do something like the following, the new created book is with 3 sheets, not one only, and it's opening while copiying. and also it's asking me if i want to saved it with Macro, while I only want to copy the sheet1, so no need for any macro with it, How to fix that to fits my needs ?
ThisWorkbook.Sheets("Sheet1").Copy
ActiveWorkbook.SaveAs "C:\DestinationWb.xlsx", FileFormat:=51
The newly created workbook will have to be open - otherwise how would you save it? - but toggling Application.ScreenUpdating might facilitate the "silent" copy you're looking for. Toggling Application.DisplayAlerts will also suppress alerts as needed.
Application.ScreenUpdating = False
Application.DisplayAlerts = False
ThisWorkbook.Sheets("Sheet1").Copy
ActiveWorkbook.SaveAs FileName:="C:\DestinationWb.xlsx", FileFormat:=51
ActiveWorkbook.Close
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Hello, I just tried the code you provided, it still opens the book for about 1-2 seconds and close it. the user will clearly see that the book is opened. is there any other way, not forcely the sheet.copy or it's the only way to copy ? – JustGreat 50 mins ago
The only way I can think of in such a scenario is to do the following.
Logic:
Use the .SaveCopyAs method to save a copy of the existing workbook. You can read more about .SaveCopyAs HERE
Create another instance of Excel and Hide it
Open the copy in that instance
Delete all sheets except the one which you want.
Save and Close and finally quit the Excel instance.
Code:
Sub Sample()
Dim thisWb As Workbook
'~~> New File Name
Dim NewFile As String
NewFile = "C:\Users\routs\Desktop\New folder\DestinationWb.xlsx"
'~~> Sheets that you want to copy across
Dim SheetToCopy As String
SheetToCopy = "Sidd"
Set thisWb = ThisWorkbook
'~~> Save a copy of the current workbook to the new path
thisWb.SaveCopyAs NewFile
'~~> Create a new Excel instance and keep it hidden
Dim tmpExcelApp As Object
Dim ws As Object, thatWb As Object
Set tmpExcelApp = CreateObject("Excel.Application")
tmpExcelApp.Visible = False
'~~> Open the copy file in hidden instance
Set thatWb = tmpExcelApp.Workbooks.Open(NewFile)
'~~> Delete all sheets except the one we copied
tmpExcelApp.DisplayAlerts = False
For Each ws In thatWb.Worksheets
If ws.Name <> SheetToCopy Then ws.Delete
Next ws
tmpExcelApp.DisplayAlerts = True
'~~> Save and close
thatWb.Close (True)
'~~> Quit Excel Instance
tmpExcelApp.Quit
MsgBox "Done"
End Sub
I have a workbook that I open with VBA, modify said workbook, and then close said workbook. So far what I have is:
Sub OpenandModify()
application.screenupdating = false
workbooks.open Filename:="FilePath\WkbkName.xlsm"
*Modify Workbook
Workbooks("WkbkName.xlsm").close SaveChanges:=True
application.screenupdating = true
End Sub()
If I run the macro with the workbook already open, the macro works correctly and closes the workbook mentioned above. However, if the workbook is not already open, then the file remains open after the modification (Note, the modifications take place so I do not think it is an issue with the Workbook.Open). Any ideas?
Thanks in advance.
After playing around more with my workbook. I seem to have found the issue. In the modify code portion, I have another subroutine that adds a worksheet from a workbook different than WkbkName.xlsm. If the sheet already exists it gets added as Sheet(2) and the workbook will not close. If the worksheet does not exist then the workbook opens and modifies correctly and shuts. I still do not understand why it acts like this so if anyone has any ideas it would be greatly appreciated.
For now, I just plan to add a check for duplicate worksheets and exit the sub if it happens.
Some of the problems you've encountered may be due to the code getting confused with which workbook it's working on.
Use a variable to hold a reference to your workbook and use only that throughout the code:
Sub OpenandModify()
Dim wrkBk As Workbook
Application.ScreenUpdating = False
'Open the workbook and assign it to wrkBk variable.
Set wrkBk = Workbooks.Open(Filename:="FilePath\WkbkName.xlsm")
'Modify Workbook
With wrkBk
.Worksheets("Sheet1").Range("A1") = "Modified!"
End With
wrkBk.Close SaveChanges:=True
Application.ScreenUpdating = True
End Sub
Really stuck with a macro I using at the moment. What I have at the moment is a marco that exports every worksheet into a separate workbook which is great.
My issue is I have columns linked to a another worksheet (“Mapping”) for data validations.
When I open the newly created workbooks the data validation links are all broken.
So I’m wondering is it possible to change this macro so when it exports each worksheet, it also exports the “Mapping” sheet into each of the newly created workbooks? Code I’m currently using below:
Option Explicit
Dim MainWorkBook As Workbook
Dim NewWorkBook As Workbook
Sub ExportWorksheet()
Dim Pointer As Long
Set MainWorkBook = ActiveWorkbook
Range("E2").Value = MainWorkBook.Sheets.Count
Application.ScreenUpdating = False 'enhance the performance
For Pointer = 2 To MainWorkBook.Sheets.Count
Set NewWorkBook = Workbooks.Add
MainWorkBook.Sheets(Pointer).Copy After:=NewWorkBook.Sheets(1)
Application.DisplayAlerts = False
NewWorkBook.Sheets(1).Delete
Application.DisplayAlerts = True
With NewWorkBook
.SaveAs filename:="H:\2017\Macro\" & MainWorkBook.Sheets(Pointer).Name & ".xlsx" 'you may change to yours
End With
NewWorkBook.Close SaveChanges:=True
Next Pointer
Application.ScreenUpdating = True
Range("D5").Value = ""
End Sub
Having played around abit I think you can change
MainWorkBook.Sheets(Pointer).Copy After:=NewWorkBook.Sheets(1)
To
MainWorkBook.Sheets(Array(Pointer, "Mapping")).Copy After:=NewWorkBook.Sheets(1)
Which preserves the Data Validation
I am trying to build a code which would switch to the immediate other open workbook and copy data from there.
I can use workbook(1) and workbook(2) ,but problem is this index changes by sequence of opening workbooks.
So I want to put if function in it ,but doesnt work. Below is the code.
If ActiveWorkbook = Workbooks(1) Then
Workbooks(2).Activate
Else
Workbooks(1).Activate
End If
but it gives error 438 ,object doesn't support property or method.
Can you help me debug this?
Try the code below, the last section of the Copy >> Paste is just an example how you copy Range("A1:E10") from "Sheet1" in DestWB to ThisWB "Sheet1" (without using Activate or Select) - you should be able to modify it quite easily.
Code
Option Explicit
Sub CopyThisWorkBOok()
Dim ThisWB As Workbook
Dim DestWB As Workbook
Dim wb As Workbook
Dim i As Long
i = Application.Workbooks.Count
If i <> 2 Then ' check if number of open workbooks is 2
MsgBox "You need to have 2 open workbooks, currently there are " & i & " open workbooks", vbCritical
Exit Sub
Else
For Each wb In Application.Workbooks ' loop through all open workbooks
If wb.Name <> ThisWorkbook.Name Then
Set DestWB = wb
Else
Set ThisWB = ThisWorkbook
End If
Next wb
End If
' from here you start the part where you copy >> paste, there is no need to `Activate` or `Select` anything
DestWB.Worksheets("Sheet1").Range("A1:E10").Copy Destination:=ThisWB.Worksheets("Sheet1").Range("A2")
End Sub
You can use names of target objects, for example:
Workbooks("MyBook.xls").Worksheets("Sheet1").Activate
Depending on what you are trying to do, the description is not very clear, you can use a variation of this code. You can define the workbook that contains the VBA as "ThisWorkBook" and go from there.
Dim source_worksheet As Worksheet
Set source_worksheet = ThisWorkbook.Worksheets("Sheet2")
Dim target_worksheet As Worksheet
Set target_worksheet = ActiveWorkbook.Worksheets("Sheet1")
'Defines what sheet you are copying
source_worksheet.Copy After:=target_worksheet