Excel/VBA: Open New Workbook In New Window - vba

I am using Excel 2010, and am looking for a VBA script that will open a new workbook in a new window (such that I could, for example, place one workbook on each of 2 monitors).
I'd then place this VBA/macro on the ribbon and assign it a shortcut key. Thus, it'd work like CTRL+N, but the new workbook would open in a separate window/instance of Excel, instead of the same.
I've tried just using Shell ("excel.exe"), but I suppose since it is running from my PERSONAL.XLSB workbook, it then asks if I want to Read Only or Notify.
I just want CTRL+N functionality, but with the new window addition.
Thank you!

You can use this:
Sub NewApp()
With CreateObject("Excel.Application")
.Workbooks.Add
.Visible = True
End With
End Sub
but be aware that any automation of this sort won't load startup workbooks and add-ins by default.

Alternate way to do the same thing, includes selecting the file you want to open:
Sub tgr()
Dim strFilePath As String
Dim xlApp As Object
strFilePath = Application.GetOpenFilename("Excel Files, *.xls*")
If strFilePath = "False" Then Exit Sub 'Pressed cancel
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
xlApp.Workbooks.Open strFilePath
End Sub

Related

Using Workbooks object with absolute address while the workbook is not opened [duplicate]

I want to search through existing Excel files with a macro, but I don't want to display those files when they're opened by the code. Is there a way to have them open "in the background", so to speak?
Not sure if you can open them invisibly in the current excel instance
You can open a new instance of excel though, hide it and then open the workbooks
Dim app as New Excel.Application
app.Visible = False 'Visible is False by default, so this isn't necessary
Dim book As Excel.Workbook
Set book = app.Workbooks.Add(fileName)
'
' Do what you have to do
'
book.Close SaveChanges:=False
app.Quit
Set app = Nothing
As others have posted, make sure you clean up after you are finished with any opened workbooks
If that suits your needs, I would simply use
Application.ScreenUpdating = False
with the added benefit of accelerating your code, instead of slowing it down by using a second instance of Excel.
To open a workbook as hidden in the existing instance of Excel, use following:
Application.ScreenUpdating = False
Workbooks.Open Filename:=FilePath, UpdateLinks:=True, ReadOnly:=True
ActiveWindow.Visible = False
ThisWorkbook.Activate
Application.ScreenUpdating = True
Using ADO (AnonJr already explained) and utilizing SQL is possibly the best option for fetching data from a closed workbook without opening that in conventional way. Please watch this VIDEO.
OTHERWISE, possibly GetObject(<filename with path>) is the most CONCISE way. Worksheets remain invisible, however will appear in project explorer window in VBE just like any other workbook opened in conventional ways.
Dim wb As Workbook
Set wb = GetObject("C:\MyData.xlsx") 'Worksheets will remain invisible, no new window appears in the screen
' your codes here
wb.Close SaveChanges:=False
If you want to read a particular sheet, need not even define a Workbook variable
Dim sh As Worksheet
Set sh = GetObject("C:\MyData.xlsx").Worksheets("MySheet")
' your codes here
sh.Parent.Close SaveChanges:=False 'Closes the associated workbook
Even though you've got your answer, for those that find this question, it is also possible to open an Excel spreadsheet as a JET data store. Borrowing the connection string from a project I've used it on, it will look kinda like this:
strExcelConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & objFile.Path & ";Extended Properties=""Excel 8.0;HDR=Yes"""
strSQL = "SELECT * FROM [RegistrationList$] ORDER BY DateToRegister DESC"
Note that "RegistrationList" is the name of the tab in the workbook. There are a few tutorials floating around on the web with the particulars of what you can and can't do accessing a sheet this way.
Just thought I'd add. :)
A much simpler approach that doesn't involve manipulating active windows:
Dim wb As Workbook
Set wb = Workbooks.Open("workbook.xlsx")
wb.Windows(1).Visible = False
From what I can tell the Windows index on the workbook should always be 1. If anyone knows of any race conditions that would make this untrue please let me know.
The problem with both iDevlop's and Ashok's answers is that the fundamental problem is an Excel design flaw (apparently) in which the Open method fails to respect the Application.ScreenUpdating setting of False. Consequently, setting it to False is of no benefit to this problem.
If Patrick McDonald's solution is too burdensome due to the overhead of starting a second instance of Excel, then the best solution I've found is to minimize the time that the opened workbook is visible by re-activating the original window as quickly as possible:
Dim TempWkBk As Workbook
Dim CurrentWin As Window
Set CurrentWin = ActiveWindow
Set TempWkBk = Workbooks.Open(SomeFilePath)
CurrentWin.Activate 'Allows only a VERY brief flash of the opened workbook
TempWkBk.Windows(1).Visible = False 'Only necessary if you also need to prevent
'the user from manually accessing the opened
'workbook before it is closed.
'Operate on the new workbook, which is not visible to the user, then close it...
Open the workbook as hidden and then set it as "saved" so that users are not prompted when they close out.
Dim w As Workbooks
Private Sub Workbook_Open()
Application.ScreenUpdating = False
Set w = Workbooks
w.Open Filename:="\\server\PriceList.xlsx", UpdateLinks:=False, ReadOnly:=True 'this is the data file were going to be opening
ActiveWindow.Visible = False
ThisWorkbook.Activate
Application.ScreenUpdating = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
w.Item(2).Saved = True 'this will suppress the safe prompt for the data file only
End Sub
This is somewhat derivative of the answer posted by Ashok.
By doing it this way though you will not get prompted to save changes back to the Excel file your reading from. This is great if the Excel file your reading from is intended as a data source for validation. For example if the workbook contains product names and price data it can be hidden and you can show an Excel file that represents an invoice with drop downs for product that validates from that price list.
You can then store the price list on a shared location on a network somewhere and make it read-only.
Open them from a new instance of Excel.
Sub Test()
Dim xl As Excel.Application
Set xl = CreateObject("Excel.Application")
Dim w As Workbook
Set w = xl.Workbooks.Add()
MsgBox "Not visible yet..."
xl.Visible = True
w.Close False
Set xl = Nothing
End Sub
You need to remember to clean up after you're done.
In excel, hide the workbooks, and save them as hidden. When your app loads them they will not be shown.
Edit: upon re-reading, it became clear that these workbooks are not part of your application. Such a solution would be inappropriate for user workbooks.

Open another workbook with vba that contains all the macros

Instead of having all the macro's stored in each workbook, we would like to have them stored in one global one. We tried using Personal.xlsb file, however every time excel crashes or system administrator forced restart with excel open it created personal.v.01 ....v.100 files, and they interfered with each other, got corrupted etc.. So instead we are trying to add a small macro to each excel workbook we make which then should open a global excel workbook with all the macros, however it does not open it(normal.xlsb), where is the problem? If I manually run it it works fine, it just does not autorun..
Option Explicit
Public Sub Workbook_Open()
Dim sFullName As String
Dim xlApp As Excel.Application
Dim wbReturn As Workbook
sFullName = "Z:\Dokumentstyring\normal.xlsb"
Set xlApp = GetObject(, "Excel.Application") 'need to do so to open it in same instance otherwise the global macros can not be called.
Set wbReturn = xlApp.Workbooks.Open(filename:=sFullName, ReadOnly:=True)
If wbReturn Is Nothing Then
MsgBox "Failed to open workbook, maybe z drive is down?"
Else
ThisWorkbook.Activate'Dont know how to pass object to modules, so instead activate it and in createbutton set wb= activeworkbook..
Application.Run ("normal.xlsb!CreateButtons")
End If
End Sub
Public Sub Workbook_BeforeClose(Cancel As Boolean)
Dim wb As Workbook
For Each wb In Application.Workbooks
If InStr(UCase(wb.Name), "PARTSLIST") > 0 And wb.Name <> ThisWorkbook.Name Then Exit Sub
Next wb
On Error Resume Next
Workbooks("normal.xlsb").Close
Workbooks("filter.xlsx").Close
End Sub
You create your addin, as just an empty workbook, holding nothing but the code
Like this
Then you add a reference to it, in the workbook that you wish to use, in VBA, like this. My Documents, is a folder on a network drive, not "my documents" local.
And then you can call like so.
So based on input from #Nathan_Sav and #Ralph I have come to a partly good solution:
I have called my addinn Normal and saved this on Z:Dokumenstyring\Normal.xlam
I then removed all the code in Thisworkbook of Normal:
Private Sub Workbook_Open()
Dim ExcelArgs As String
Dim arg As String
ExcelArgs = Environ("ExcelArgs")
'Call deleteMacros.deletePersonalFiles
'MsgBox ExcelArgs
If InStr(UCase(ExcelArgs), "CREO,") > 0 Then
Application.DisplayAlerts = False
If Len(ExcelArgs) > Len("CREO,") Then
arg = Split(ExcelArgs, ",")(1)
Call Creo.addNewPartToPartslist(arg)
End If
Application.DisplayAlerts = True
End If
If InStr(UCase(ExcelArgs), "DOKLIST,") > 0 Then
Application.DisplayAlerts = False
If Len(ExcelArgs) > Len("DOKLIST,") Then
arg = Split(ExcelArgs, ",")(1)
Call ProsjektListen.dbDumpDocOut(arg)
End If
Application.DisplayAlerts = True
End If
and put this in a new workbook called Z:Dokumenstyring\Creo.xlsm
I have so edited all my bat files(which previously were using personal.xlsb):
echo "Launch excel"
Set ExcelArgs=CREO,ADDPART
"C:\Program Files (x86)\Microsoft Office\OFFICE16\Excel.exe" /x /r "z:\Dokumentstyring\Creo.xlsm"
So when I run the bat file it adds a parameter to enviroment, start creo.xlsm, which then starts the addin which launch my userform.
So if I now want to update the look of that that userform I do this by modifying the Z:Dokumenstyring\NormalDebug.xlam, then i save a copy which i write over Z:Dokumenstyring\Normal.xlam and I also told every user to not copy the addin to the default location in excel but keep it in Z:Dokumenstyring\Normal.xlam.
My shapes in my excel sheets seems to work with just the macro name in the procedure, however there might be an conflict if two procedures have the same name, but located in different procedures. So I also altered this to
ws1.Shapes(tempName).OnAction = "Normal.xlam!Custom_Button_Click"
However every click starts a new instance of the addin, how to avoid this?

VB.net manage opened excel file on the fly

In my current project, i need to modify an excel file that is already opened. That mean, i need to see the change in the excel file whenever i modify it.
Since opened file is locked and vb cannot access that file, my solution is to open another excel file, modify its content and then copy to the original file using excel vba, as excel vba can be used to copy data between opening sheets.
Here is the vb code in my other excel file (called TTHT.xlsm):
Private Sub Worksheet_CHANGE(ByVal Target As Range)
Application.ScreenUpdating = False
If Sheet1.[B5].Value = "#" Then
Application.DisplayAlerts = False
With Workbooks.Open(ThisWorkbook.Path & "\PCN.xlsm")
With ThisWorkbook.Sheets("TTHT").[B5]
.Parent.Range("B4").Copy
Sheets("PCN").[B4].PasteSpecial 7
End With
End With
Application.DisplayAlerts = True
End If
End Sub
Runs fine between my 2 opening excel file ( that TTHT one and PCN.xlsm ).
Now all I need to do, is to fill the data into TTHT, and put a "#" into B5 by my code. I think it will work, but it's not..
Private Sub btnUpdate_Click(sender As System.Object, e As System.EventArgs) Handles btnUpdate.Click
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
oExcel = CreateObject("Excel.Application")
oExcel.DisplayAlerts = False
oBook = oExcel.Workbooks.Open(TTHTPath)
oSheet = oBook.Worksheets("TTHT")
oSheet.Range("B4").Value = txtValue_Needed.text
oSheet.Range("B5").Value = "#"
oBook.Save()
'System.Diagnostics.Process.Start(DuongDanPhieuCongNghe)
oSheet = Nothing
oBook.Close()
oBook = Nothing
oExcel.Quit()
oExcel = Nothing
End Sub
Result is, if i open the PCN file and click button, it won't change. If I close the PCN and click button, it will change..
But i need to see the change on the fly, not by close and reopen each time i need to update.
Can someone shed me some light, as to how, or which function ... either vba or vb.net, should i use ?
If the file is already opened and has focus then you can try looking it up in the running objects table.
Dim ExcelApplication As Excel.Application
ExcelApplication = GetObject("C:\Folder\ExcelWorkbook.xls")
Then you can just make your modifications on the instance which you referenced while trying to avoid disrupting the user.
The getobject() function is great; here's a link.
https://msdn.microsoft.com/en-us/library/e9waz863(v=vs.71).aspx

AutoNew macro not working

I'm trying to get Word to open an Excel document whenever a document based on a specific template is created.
Here is my macro
Sub AutoNew()
Dim oExcel As Excel.Application
Dim oWB As Workbook
Set oExcel = New Excel.Application
Set oWB = oExcel.Workbooks.Open("E:\Letters.xlsx")
End Sub
When I double-click the template, it brings up a document based on the template just fine, but the macro doesn't run.
It shows up in the list of macros in the template, but attempting to run it doesn't do anything.
As has mentioned KazJaw, make app visible
Sub AutoNew()
Dim oExcel As Excel.Application
Dim oWB As Workbook
Set oExcel = New Excel.Application
Set oWB = oExcel.Workbooks.Open("E:\Letters.xlsx")
oExcel.Visible = true
End Sub
A disadvantage is, that excel application is launching as a new task (see tak manager) in case of another calling the macro - every document is opened in its own task.
The correct way is use API for launching a document in registered application, for example here: http://access.mvps.org/access/api/api0018.htm
Or one-row workaround, ugly, but works great:
Shell "cmd.exe /c start D:\a\test.xlsx"
Note that template with macro must have extension .xltm, not .xltx.

Is it possible to run a macro in Excel from external command?

Let's say I want to program a VBA code in an external program that opens an Excel file, runs a macro, saves (and say yes to any pop up windows), and close Excel. Is it possible to do so? If so, how would I go about implementing it?
You can launch Excel, open a workbook and then manipulate the workbook from a VBScript file.
Copy the code below into Notepad.
Update the 'MyWorkbook.xls' and 'Sheet1' parameters.
Save it with a vbs extension and run it.
Option Explicit
On Error Resume Next
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("C:\MyWorkbook.xls")
xlBook.Sheets("Sheet1").Cells(1, 1).Value = "My text"
xlBook.Sheets("Sheet1").Cells(1, 1).Font.Bold = TRUE
xlBook.Sheets("Sheet1").Cells(1, 1).Interior.ColorIndex = 6
xlBook.Save
xlBook.Close
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
This code above launches Excel opens a workbook, enters a value in cell A1, makes it bold and changes the colour of the cell. The workbook is then saved and closed. Excel is then closed.
Depending on what you are trying to achieve you may also 'control' Excel via (OLE) Automation from another application such as Access or Word or from your own application written in another environment such as Visual Basic (6). It is also possible to achieve this via .Net using a language of your choice (although some are easier to implement than others).
Are you wanting to control Excel from an external application or simply trigger a VBA macro in an existing workbook from the outside?
Again, depending on your intention, the workbook could have an Auto Open macro which could be conditional run based on an external value (say an ini file or database value).
I can think of several ways to do this.
You can start excel by creating a file with NotePad or a similar text editor.
Here are some steps:
Launch NotePad
Add the following line of text. Replace test.xlsm with the name and path for your file:
start Excel.exe "C\test.xlsm"
Save the file as "Test.bat".
Run the batch file.
The batch file should launch Excel and then open your file. The code in your workbook should run
OR
Again, using Notepad.
Option Explicit
On Error Resume Next
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("C:\MyWorkbook.xls", 0, True)
xlApp.Run "MyMacro"
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
Or, this.
'Code should be placed in a .vbs file
Set objExcel = CreateObject("Excel.Application")
objExcel.Application.Run "'C:\Users\Ryan\Desktop\Sales.xlsm'!SalesModule.SalesTotal"
objExcel.DisplayAlerts = False
objExcel.Application.Quit
Set objExcel = Nothing
Now, this isn't 'an external command', but the Windows Task Scheduler will do a nice job of opening that file for you, and once it is opened, you can run a tiny script like the one you see below.
Private Sub Workbook_Open()
Call CommandButton1_Click
End Sub
https://www.sevenforums.com/tutorials/11949-elevated-program-shortcut-without-uac-prompt-create.html