I am relatively new to the true power in Excel - Macros/VBA and have been tasked to set up the financial model for a million dollar project. I am able to set everything up and have it run smoothly, but there's too much manual input involved. I would like to seek simplification through the power of VBA.
This is my dilemma:
I need to be able to individually double-click on a specific set of cells (in a Row), which will open up a file window that allows me to select a EXL file.
Once I select the file, that file should be preferably opened in a temp status (not visible, but I can run functions and pull info from it).
I will then need the macro to go into that opened sheet, conduct a simple SUMIFS function, and record the outcome in a column of the current sheet I'm working from.
I've been doing some Excel tutorial on Lynda in hope to seek the answers there, but I think the complexity of this request demands the knowledge of a true master.
Any help will be greatly appreciated! I would imagine this could be a nice little challenge for those who seek it :)
Sincere thanks,
Try this:
Dim appExcel As Excel.Application
Set appExcel = CreateObject("EXCEL.Application")
Dim wkbk As Excel.Workbook
Set wkbk = appExcel.Workbooks.Open(sPathSrc, , False, , , sPassword)
' do EXCEL work here
If Not wkbk Is Nothing Then wkbk.Close True
Set wkbk = Nothing
If Not appExcel Is Nothing Then
appExcel.DisplayAlerts = False
appExcel.Quit
End If
Set appExcel = Nothing
This code is from an ACCESS application that invoked EXCEL to print some reports. I found it necessary to sprinkle some DOEVENTS calls around, but it was all a while ago; some details escape me at this moment.
Related
I am facing a very weird problem wherein, I am creating a new workbook using the below code, but the new workbook thus created, is not visible and it is not even showing up in the taskbar.
The code lies in a powerpoint file.
Dim wb As Workbook
Set wb = Excel.Workbooks.Add
Application.Visible = msoTrue ' Forcing this also doesn't solve
The same issue is happening with the code of opening an excel with the following code
Dim MyWorkbook As Workbook
Set MyWorkbook = Workbooks.Open(fullpath) ' full path is the path to existing excel file
Application.Visible = True ' Forcing this also doesn't solve
I can't figure out why this is happening. Any help is much much appreciated. Here is what I have tried
Made sure the excel library references is added.
Used the Application.Visible = True in code
Have even restarted the system multiple times.
Tried to set Excel -> Options -> Advanced -> Show All Windows in the Taskbar check box, as suggested in forums, but didn't find this option in excel though.
I bought a software (with a large database), and its output is a simple Excel workbook, not saved anywhere (no path), named generically "Book1", that simply pops up on my screen.
Every time I ask the software for this output, I need to copy the content of this workbook and paste into another workbook, a mother-workbook, as I named it, to consolidate all the data.
I have to repeat this action dozens of times a day, so I thought it would be a great idea to create some VBA code to automate this task.
So... I made a very simple one:
ActiveWorkbook.ActiveSheet.Range("A1:C32").Copy
Workbooks("Mother-Workbook.xlsm").Worksheets("Sheet1").Range("B6:D37").PasteSpecial Paste:=xlPasteValues
The problem is... Each time the software outputs a new workbook, it seems that it is created in a new instance of Excel, which my macro can't reach. I mean, I run the code, but nothing happens, because my mother-workbook doesn't find the generic, unsaved and located in another excel instance "Book1".
If I open the mother-workbook after the output is opened, OK, the code works, because both are in the same instance. But as I need to keep the mother-workbook open all the time, I can't do this. I don't want to save each new output file either. It would take me a lot of time.
I'm using the 2016 version of Excel, but already tried the 2010 as well. My OS is Windows 10 Pro.
Any thoughts?
This code should do it.
Dim xlapp As Object
Set xlapp = GetObject("Book1").Application
xlapp.ActiveWorkbook.ActiveSheet.Range("A1:C32").Copy
Workbooks("Mother-Workbook.xlsm").Worksheets("Sheet1").Range("B6:D37").PasteSpecial Paste:=xlPasteValues
xlapp.DisplayAlerts = False
xlapp.Quit
Note that you need to close "Book1" at the end of your code to make sure that the next time an Excel file is created it will also be called "Book1" and not "Book2". And might as well close the Excel instance while we are at it!
For more information on the GetObject function, you can have a look at this page
Thanks a lot, DecimalTurn and Patrick Lepelletier!
The GetObject really helped me. The "closing" command worked better like this:
Sub CollectA()
Dim oApp As Application
Dim oWb As Workbook
Set oWb = GetObject("Book1")
Set oApp = oWb.Parent
oWb.ActiveSheet.Range("A1:C32").Copy
Workbooks("Mother-Workbook.xlsm").Worksheets("Sheet1").Range("B6:D37").PasteSpecial Paste:=xlPasteValues
oWb.Close False
oApp.Quit
End Sub
Cheers!
When you have more than one Excel file open, and your VBA/VSTO code calls the Calculate function, or turns on Automatic Calculation, Excel will painfully recalculate all open Workbooks, not just the active Workbook.
This is a well-known and well-reported problem, which has been around for years, but Microsoft doesn't seem interested in fixing it.
Calculate only the active workbook before saving
Microsoft Excel wishlist: Workbook level calculation
Ridiculously, in both VBA and VSTO, Microsoft gives us the ability to:
recalculate a particular Worksheeet
recalculate all open Workbooks
...but there's no option to just recalculate one particular Workbook.
In the financial company I work for, this is a huge issue. Our actuaries have big, bulky Excel files, full of formulae, and when they click on Calculate on one Workbook or we perform a calculate before saving a file, they then have to wait several minutes for all other open Excel files to also get calculated.
There are two ways around this.
You could run some VBA like this:
Application.Calculation = xlManual
For Each sh In ActiveWorkbook.Worksheets
sh.Calculate
Next sh
..but this isn't guaranteed to work. Your "Sheet1" might contain formulae pointing to cells in "Sheet2", but other cells in "Sheet2" might have dependencies back on "Sheet1". So, calculating each Worksheet once might not be enough to perform a full calculation on your Workbook.
Alternatively, you could open each Excel file in a separate instance (by holding down ALT as you open the Excel icon). But then, you lose the full Excel cut'n'pasting functionality, as described here:
Can't fully cut'n'paste between Excel instances
So, my question is... has anyone found a workaround for this issue ?
I just want to recalculate the cells in the Active Excel Workbook.
I wondered if I could add some VBA or VSTO which sets all non-Active Workbooks to "read-only" before I kick off a Calculation on the Active Workbook, thus preventing other Workbooks from being able to be recalculated. But this isn't possible. The "Workbook.ReadOnly" can only be read, not programmatically set.
Or perhaps adding a handler to the Worksheet_Calculate event, which checks if that VBA code which is being run belongs to the Active Workbook, and if not, it aborts attempting to calculate...? But this event actually gets kicked off after that Worksheet has been calculated, so it's too late.
Our company can't be the only one suffering from this issue...
Any advice (other than upgrading to Lotus 1-2-3) ?
This method uses another instance of Excel to avoid multiple workbook calculations. A few lines of the code for using a new instance were taken from this SO question, which deals with a similar topic and may be of interest to you.
You will have to test this for speed in your specific case, since the closing/opening time might not out-weigh the avoided calculations!
Macro steps
Set calculation to manual
Save and exit the desired workbook
Open it in a new instance of Excel
Recalculate
Save, close and re-open in original instance of Excel.
Key point for running this script:
The macro cannot live within the workbook to be recalculated, since it gets closed (twice) during the process. It should be placed in some other "utility" workbook.
Code - see comments for details
Sub CalculateWorkbook(WB As Workbook)
' Store path of given workbook for opening and closing
Dim filepath As String
filepath = WB.FullName
' Turn off calculation before saving
Dim currentCalcBeforeSave As Boolean
currentCalcBeforeSave = Application.CalculateBeforeSave
Application.CalculateBeforeSave = False
' Store current calculation mode / screen update and then set it to manual
Dim currentCalcMode As Integer, currentScreenUpdate As Integer
currentCalcMode = Application.Calculation
currentScreenUpdate = Application.ScreenUpdating
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
' Close and save the given workbook
WB.Close savechanges:=True
' Open a new INSTANCE of Excel - meaning seperate calculation calls
Dim newExcel As Excel.Application
Set newExcel = CreateObject("Excel.Application")
' Could make it visible so that any problems don't leave it hidden in the background
' newExcel.Visible = False
' Set the calculation mode to manual in the new instance sothat the workbook isn't calculated on opening.
' This can't be done without an existing workbook object.
Dim tempWB As Workbook
Set tempWB = newExcel.Workbooks.Add
newExcel.Calculation = xlCalculationManual
newExcel.CalculateBeforeSave = False
' Open the workbook in the new instance of Excel
Dim newWB As Workbook
Set newWB = newExcel.Workbooks.Open(filepath)
' Calculate workbook once
newExcel.Calculate
' Close and save the workbook, tempworkbook and quit new instance
newWB.Close savechanges:=True
tempWB.Close savechanges:=False
newExcel.Quit
' Re-open in the active instance of Excel
Application.Workbooks.Open filepath
' Reset the application parameters
Application.CalculateBeforeSave = currentCalcBeforeSave
Application.ScreenUpdating = currentScreenUpdate
Application.Calculation = currentCalcMode
End Sub
Call the above sub by passing it the workbook object you wish to recalculate (this could be done from a button etc).
This has been tested on a very simple example workbook, and the concept works. However, please test on a copy of your workbook first, since it has not been fully robustness tested, and has no error handling.
The method I use for this in my FastExcel product involves setting WorkSheet.EnableCalculation to false for all the worksheets in all non-activeworkbooks and to True for all the worksheets in the active workbook.
This works but has the disadvantage of making the next calculation a Full calculation of the new active workbook when you change the active workbook: so its a tradeoff.
You can try this out in your situation by downloading the trial version of FastExcel from Download the 15-day full-featured trial of FastExcel V3 build 231.655.789.380
Then use FastExcel Calculation Options and check the Active Workbook checkbox in the Current Calculation Mode settings;
Disclaimer: I own, develop and market the FastExcel product. The FastExcel component that contains the Active Workbook Calculation code is FastExcel V3 Calc
I am responsible for updating an Excel spreadsheet which pulls its information from an Access database on a daily basis. All the data that i need for my excel spreadsheet is available for me and all that i need to do is open the document, provide the password, enable to content and click the refresh button.
The database is very large and updating this during normal working hours causes problems as it slows down other users on the network. How would i use Windows Scheduler to do this for me outside of working hours? I'm not sure how to set up my script to follow my steps required.
I've had to do something quite similar to this recently, and with the help of this forum I've found something that works for me, and by the sounds of it may work for you too!
I created a notepad file with the following .vbs script
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
oExcel.Visible = True
oExcel.DisplayAlerts = False
oExcel.AskToUpdateLinks = False
oExcel.AlertBeforeOverwriting = False
Set oWorkbook = oExcel.Workbooks.Open("Full Path of your file.xlsx")
oWorkbook.RefreshAll
oWorkbook.Save
oExcel.Quit
Set oWorkbook = Nothing
Set oExcel = Nothing
What this does, it opens the file, refreshes any data connections, then saves the file and exits.
I then put this as a scheduled task to run at an off peak time, so that when the user opens the workbook, it's up to date.
I hope this helps!
I managed to achieve this through the VBA
hit Alt - F11
right click ThisWorkbook and click view code.
the code is as follows:
Private Sub Workbook_Open()
Workbooks.Open ("location of your workbook"), Password:="whatever your password is"
ThisWorkbook.RefreshAll
End Sub
i save this document and ask the task scheduler to run it at a specific time.
So I'm importing data every day into Access to use for reporting. The data comes from several spreadsheets created by different individuals. Because those individuals like to format things incorrectly I created a macro that reformats their document so that it can be imported cleanly into Access for me to use. Works great but it gets tedious having to open up each Excel sheet to run this Macro.
What I'm trying to do is place the Excel Macro in Access and then run the formatting code before importing it all at once. I am a bit lost in approaching this. I'm aware of ways to run Macros already placed in Excel sheets but is there a way to run a macro that is stored in Access that works in excel. I also thought to maybe inject the Macro into the excel document and then run it.
To sum things up, what I'm hoping to do is from Access, store a macro, that can be used to alter Excel Files.
Is this at all possible? If so How? Is there another approach?
What you are asking to do is automate Excel from Access. Yes, you can do this. In Access, add a module, add a reference to the Microsoft Excel object model (Tools: References), and use this framework code to get you started:
Sub PrepExcelFileForImport()
Dim xl As Excel.Application
Dim wbk As Excel.Workbook
Dim wst As Excel.Worksheet
Set xl = CreateObject("Excel.Application")
With xl
.Visible = True
Set wbk = .Workbooks.Open("c:\temp\temp.xlsx")
Set wst = wbk.Worksheets("data")
With wst
' add your formatting code here, be sure to use qualified references, e.g.
.Rows(1).Font.Bold = True
End With
End With
wbk.Close SaveChanges:=True
xl.Quit
End Sub