Saving a different workbook that is opened - excel

I have a workbook (WorkbookA.xlsm) that I open. Upon being opened, this opens WorkbookB.xlsm.
'ThisWorkbook code of WorkbookA.xlsm
Private Sub Workbook_Open()
Dim wb As Workbook
Application.ScreenUpdating = False
Set wb = Workbooks.Open(Filename:="C:\WorkbookB.xlsm")
wb.Windows(1).Visible = False
End Sub
After "B" being opened, a script is called that also sets off a timer.
The script in B changes some data on A. I want to add something after the script is called to automatically save WorkbookA.xlsm as it is (without any prompts).
'ThisWorkbook code of WorkbookB.xlsm
Private Sub Workbook_Open()
Call Script
'looking for something in here to save WorkbookA
End Sub

Since you know the name of the workbook you want saved ("WorkbookA.xlsx"), you can reference it directly with a save method:
Workbooks("WorkbookA.xlsx").Save

You can use the Workbook.Save method to save your workbook. It'll be something like
wb.Save
or
ActiveWorkbook.Save
if you know that your current workbook is the active one. Save doesn't let you change the filename - if you want that, use SaveAs instead.

Try something similar to this:
For each w in Application.Workbooks
If w.Name = "WorkbookA" Then
w.Save
Exit For
End if
Next w
You need to find the workbook you want or set it prior in your code since you want the save code to be called from workbookB. If you were to call it from workbookA, you could use ActiveWorkbook.Save

Related

Open/Close Workbook in Userform

In a Userform I want to open another workbook (than the active one)
Part of my code:
Private Sub cmbKontoPos1_Change()
Workbooks.Open Filename:=filename1
'Here should of course be some code, but it is not now
Workbooks(filename1).Close SaveChanges:=False
Open-command works.
But the Close-command gives error:
Error no '9'
Index out of bounds
(I get the error-message in Swedish, hope I translate correct)
What is it I do not understand?
Quick fix is to have a global Workbook Variable so you can assign it on Open and use it on other UserForm Events, the example below has two Buttons and one opens while the other one closes the Workbook. Tested and working.
You can see the Dim secondWorkbook outside the UserForm buttons this is to make it global. On the first button I assign the Opened workbook to that Variable and i can close it later.
Dim secondWorkbook As Workbook
Private Sub CommandButton1_Click()
'Open WB
Dim filename1 As String
filename1 = "F:\WorkbookPath\WBName.xlsx"
Set secondWorkbook = Workbooks.Open(filename1)
End Sub
Private Sub CommandButton2_Click()
'Close WB
secondWorkbook.Close False
End Sub
You can also use this variable to make changes to the workbook like: secondWorkbook.Worksheets(1).Range("A1").Value = "Test" as long as it is still open of course.

How to detect that an Excel cell has been changed by formula and write data to a CSV file

I have an Excel file that is updated every few seconds by an application. Using the data delivered by the application, several cells in the worksheet (called "TSdata") are calculated using various formulae. If the value of a specific cell (B41) changes, the macro should write the contents of the worksheet to a CSV file.
With the help of one of the guys on superuser.com, I created a version based on Worksheet_Change that worked perfectly if the content of the cell was manually updated. I created a version using Worksheet_Calculate that I expected to work the same way when the cell value was changed by the formula.
This is the code I used:
Private Sub Worksheet_Calculate()
If Worksheets(“TSdata”).Range(“B41”).Value<>prevval Then
Call ExportWorksheetAndSaveAsCSV
End If
prevval = Worksheets(“TSdata”).Range(“B41”).Value
End Sub
Public Sub ExportWorksheetAndSaveAsCSV()
Dim wbkExport As Workbook
Dim shtToExport As Worksheet
Set shtToExport = ThisWorkbook.Worksheets("TSdata") 'Sheet to export as CSV
Set wbkExport = Application.Workbooks.Add
shtToExport.Copy Before:=wbkExport.Worksheets(wbkExport.Worksheets.Count)
Application.DisplayAlerts = False 'Possibly overwrite without asking
wbkExport.SaveAs Filename:="C:\TSCSV\TSCSV1.csv", FileFormat:=xlCSV
Application.DisplayAlerts = True
wbkExport.Close SaveChanges:=False
FileCopy "C:\TSCSV\TSCSV1.csv", "C:\ChartInfo\Data\TSCSV2.csv"
End Sub
I know from the earlier test using a manual update that the Public Sub works OK (It's copied from another query regarding writing CSV files) but when I launch the macro, it seems to attempt multiple updates (the screen blinks several times) and then crashes Excel. So, obviously something in the Private Sub is incorrect, but I've based it on other responses to similar questions, so I'm at a loss to figure out what's wrong/missing.
Note: the FileCopy at the end of the Public Sub is so that another program can work on the CSV without disrupting the Excel updates.
Thanks in advance for any help.
Copying a worksheet to no location creates a new workbook with a single worksheet that is a copy of the original.
Public Sub ExportWorksheetAndSaveAsCSV()
Dim fn1 As String, fn2 As String
fn1 = "C:\TSCSV\TSCSV1.csv"
fn2 = "C:\ChartInfo\Data\TSCSV2.csv"
'copying a ws to no location creates a new workbook with a single worksheet
ThisWorkbook.Worksheets("TSdata").Copy 'Sheet to export as CSV
Application.DisplayAlerts = False 'Possibly overwrite without asking
With ActiveWorkbook
.SaveAs Filename:=fn1, FileFormat:=xlCSV
.Close SaveChanges:=False
End With
Application.DisplayAlerts = True
On Error Resume Next
If CBool(Len(Dir(fn2))) Then Kill fn2
FileCopy fn1, fn2
On Error GoTo 0
End Sub

Workbook will not close with VBA unless opened manually

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

Activate different workbook to run macro

I created a macro in my workbook using an active worksheet from another workbook. I would now like to run my macro, but use yet another different active workbook to get my data.
I have this line 20 times in my macro...
Windows("IFS_round_1").Activate
...so I do not want to change it (ex. IFS_round_2) each time I open a new workbook to run the macro. Is there something I can add so the macro just uses whichever active workbook I have open?
Thanks!
Create a variable to refer to the workbook. For example:
Sub Macro1()
Dim wb as Workbook
Set wb = ActiveWorkbook
wb.Activate
'DO CODE HERE
End Sub
Does this help?
I don't know if you are opening the other workbook programatically, but this solution works. basically you just save the handle to the other workbook as soon as you open it.
sother_filename = "IFS_round_1"
'saves the name of the current workbook
curr_workbook = ActiveWorkbook.Name
'opens the new workbook, this automatically returns the handle to the other
'workbook (if it opened it successfully)
other_workbook = OpenWorkbook(sother_filename)
But what fun is that? one more solution to automatically get the workbook name when there are only two workbooks open and then simply use that to call the other workbook
Function GetOtherWBName()
GetOtherWBName = ""
'if we dont have exactly two books open
'we don't know what to do, so just quit
If (Workbooks.Count) <> 2 Then
Exit Function
End If
curr_wb = ActiveWorkbook.Name
'if the active workbook has the same name as workbook 1
If (StrComp(curr_wb, Workbooks(1).Name) = 0) Then
'then the other workbook is workbook 2
GetOtherWBName = Workbooks(2).Name
Else
'then this is the other workbook
GetOtherWBName = Workbooks(1).Name
End If
End Function
So now in the workbook that has the macro make a button and assign a macro to it similar to this
Sub ButtonClick()
'first we save the current book, so we can call it easily later
curr_wb = ActiveWorkbook.Name
other_wb = GetOtherWBName()
If Len(other_wb) = 0 Then
MsgBox ("unable to get other wb")
Exit Sub
End If
'now to call the other workbook just use
Workbooks(other_wb).Activate
'all the rest of your code
End Sub

stop task from running when file is open

I am trying to schedule a task in Window's Task Scheduler that opens an excel file and auto run the macro in it.
The macro part is all done, but one problem I have is when the file is already open and the scheduled task runs. Whenever this happens, it will ask you if you want to reopen the file, if i accidentally click yes, which actually happened, then the data I was working on will all disappear.
So what I want is for the task to not run when file is open. Do I need to run a script? create a batch file with the code? If possible can you provide me a code that can do this as I am not familiar with another language aside from VBA
Note.
Just to clarify, I have a file that constantly pull data form Live Bloomberg. What I want to do is to save it as another workbook for reference everyday at 4:30pm. There is a few problem.
Here is how what I wrote in ThisWorkbook for easier understanding what I want to accomplish
Private Sub Workbook_Open()
Application.OnTime TimeValue("16:30:00"), "MyMacro"
End Sub
1)If I didn't open that excel that day, Workbook_Open() simply won't run.
2)Even if I did open the excel, if I close Excel before 4:30pm the macro won't run
So what I want is to have windows task scheduler constantly open the excel file for me that will always run on time regardless of what happens.
There are other problems too. I always write comments and stuff to the Live Data File, so if Task Scheduler tries to open the data file which in turn activating the Workbook_Open() while I am using it, a popup will come up asking if I want to reopen file. Of course I simply need to press "no" then the task will stop and everything is fine. But what if I wasn't there to press the button? Also on a few occasion I accidentally press "yes", which wiped out all the comments I wrote.
Therefore what I wanted to ask is that if The Live Data File is already open, simply make it so that the task in Task Scheduler won't run.
Have you considered using the Workbook.ReadOnly Property? This won't exactly tell you if the file is open but it will tell you if you have write-access. Try:
Public Sub OnlyRunWithWriteAccess()
Dim oBook As Workbook
Set oBook = Application.ActiveWorkbook
If Not oBook.ReadOnly Then
'Your processing code goes here...
End If
Set oBook = Nothing
End Sub
First of all thanks Steve S for your input.
I already did a workaround. Instead of having the LiveData file to run the macro, I put the macro on a clean excel template and have task scheduler open that file instead. This way is much more reliable and skips all the "Scripting in task scheduler" thing.
Here is my updated code:
'In ThisWorkbook
Public Sub Workbook_Open()
Run "AutoSaveAs"
End Sub
'In Module1
Public Sub AutoSaveAs()
Application.ScreenUpdating = False
Dim LDSP As String
Dim IsOTF
Dim LDS, TWB As Workbook
'Set LiveDealSheet file path
'Check if LiveDealSheet is already open
LDSP = "I:\LiveDealSheet\LiveDealSheet.xlsm"
IsOTF = IsWorkBookOpen(LDSP)
'Set quick workbook shortcut
Set TWB = ThisWorkbook
If IsOTF = False Then
Set LDS = Workbooks.Open(LDSP)
Else
Workbooks("LiveDealSheet.xlsm").Activate
Set LDS = ActiveWorkbook
End If
'Copy all data from LIVE Deals to TWB
LDS.Sheets("LIVE Deals").Cells.Select
Selection.Copy
TWB.Sheets(1).Cells.PasteSpecial (xlValues)
TWB.Sheets(1).Cells.PasteSpecial (xlFormats)
TWB.SaveAs FileName:="I:\LiveDealSheet\" & Format(Date, "yyyymmdd") & " LiveDealSheet", FileFormat:=52
If IsOTF = False Then
LDS.Close False
TWB.Close False
Else
TWB.Close False
End If
Application.ScreenUpdating = True
End Sub
Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function

Resources