Excel Macro generated file copy keeps links to original files - excel

I have sales global sales data in very large files which I need to filter by country and product and then analyze. Since I will need to perform this same analysis over and over again with different country/product combinations I am trying to do this with a macro.
This is what the macro does:
Open the source files with global data;
Filters the data;
Copies it and pastes it into a workbook which houses the macro;
Recalculates and refreshes the workbook and;
Saves a copy of the file to another folder.
The macro appears to run fine and the files are being saved, however I am running into 2 problems on steps 4 and 5:
The pivot tables do not seem to be refreshing - this may be because the second problem:
All pivot tables in the saved copy still refer to the original file
I'd prefer to fix both problems by generating the copied file without links, but I'm also open to any bandaids that might allow me to force the copied file to link to itself (this doesn't seem to work when I do it manually).
I have the full code if you want to see it all, but because I suspect the issue is in how I'm saving the file I'll just paste that piece here. Let me know if you need to see another part of the macro. Any help would be much appreciated, thanks in advance.
Save Function:
Public Sub SaveAsCopy(filePath As String)
Dim updateStatus As Boolean
'Check current status of Alerts
updateStatus = Application.DisplayAlerts
'Turn off alerts
Application.DisplayAlerts = False
ThisWorkbook.Sheets.Copy 'creates new workbook without macros"
'The New workbook copy is now the Active workbook
'Delete Control Sheet
ActiveWorkbook.Sheets(1).Delete
'Save Macro free version and close
ActiveWorkbook.SaveAs Filename:=filePath, FileFormat:=51
ActiveWorkbook.Close
'Revert back to origional alert status
Application.DisplayAlerts = updateStatus
End Sub
Function Call:
Call SaveAsCopy(filePath)

Will share the workaround I developed since I didn't get any bites on a more elegant solution:
Public Sub SaveAsCopy(filePath As String)
Dim updateStatus As Boolean
'Check current status of Alerts
updateStatus = Application.DisplayAlerts
'Turn off alerts
Application.DisplayAlerts = False
'Hide Control Sheet
ActiveWorkbook.Sheets(1).Visible = False
'Save Macro free version and close
ActiveWorkbook.SaveAs Filename:=filePath, FileFormat:=52
'Unhide
ActiveWorkbook.Sheets(1).Visible = True
'Revert back to original alert status
Application.DisplayAlerts = updateStatus
End Sub
At the end of the parent function I close the current file, reopen the original, and loop through the new workbooks to remove macros.

Related

Excel VBA Copying sheet from closed workbook to current workbook, but copies outdated sheet

I am on Excel 2003 should that make a difference.
I have a small function that opens a file by path, copies over its first (and only) sheet to the current workbook. Closes the opened template and renames the newly created sheet.
The thing is when it does this the new sheet that is made is and older version of the template file?
The file is located at "E:\Cascade\RunSheet-Heath Edition\CH54\CH54_Template.xlt"
Sub LoadTemplate2()
'disables the refreshing of the screen to speed up the script
Application.ScreenUpdating = False
Application.DisplayAlerts = False
directory = "E:\Cascade\RunSheet-Heath Edition\CH54\"
templateName = "CH54_Template"
fileExt = ".xlt"
bookName = ActiveWorkbook.Name
Debug.Print (bookName)
filePath = directory & templateName & fileExt
Dim wb As Workbook
'opens the template
Set wb = Workbooks.Open(filePath)
'copy over the template sheet
Sheets(1).Copy _
Before:=Workbooks(bookName).Worksheets(1)
'closes the template
wb.Close
' renames the newly created sheet
Sheets(1).Name = "RunSheet"
'Resume updating the screen
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
I am about to try to select a range and try copying that over, but seems odd that this is happening anyway.
It seems like a weird cache thing to me. as if the Front end excel interface shows the true data but for whatever reason the VBA script pulls from an older version of the template file.
I have saved both workbooks and closed them, even restarted the computer, the template is as it should be. Not what it is currently pasting. What it is pasting is not even saved on the computer as a file anymore, nor is it opened when I go line by line step through in the code. The correct file is being opened.
I should note that when I open up the template but just clicking the file on Windows the excel header is CH54_Template1.xlt, and not just "CH54_Template.xlt" as the file is named.
I start with one workbook open:
I run the code which opens:
this file
The code finished and I am left with
which is from something I had made a month or so ago and since deleted.

VBA code to copy range of data from closed file in SharePoint to open file

This question has been asked in different chats and I have tried to incorporate the varying solutions but without success. I am attempting to open a SharePoint file and copy data from the file to the open file that has the macro within. The below solution is the last attempt I tried that did open the SharePoint file but would not select the desired range. A Run-time error '9' Subscript out of range was returned. If it makes it easier, my goal is to simply copy the entire sheet from the closed file into the open file. Code used is below. Any direction and or suggestions are appreciated.
Private Sub CommandButton1_Click()
Dim x As Workbook
Dim y As Workbook
Set x = Workbooks.Open("http://employee.xtra.net/sites/Ops/Support%20Launch%20Docs/ep_timing_wb_report.xlsx")
Set y = ThisWorkbook
x.Sheets("ep_timing_wb_report 1").Range("A:AA").Copy
y.Sheets("ep_timing_wb_report").Range("A:AA").PasteSpecial
x.close
End Sub
Bruce was correct with the recommendation of simply using a Hyperlink in the cell. This was attempted earlier but I must not have linked properly.
See if this works for you (comments included).
Sub OpenAndCloseWBFromSharePointFolder()
'If nobody has the file checked out
If Workbooks.CanCheckOut("http://excel-pc:43231/Shared Documents/ExcelList.xlsb") = True Then
Application.DisplayAlerts = False
'Open the file on the SharePoint server
Workbooks.Open Filename:="http://excel-pc:43231/Shared Documents/ExcelList.xlsb", UpdateLinks:=xlUpdateLinksNever
'Close the workbook
Workbooks("ExcelList.xlsb").Close
Application.DisplayAlerts = True
Else
Application.DisplayAlerts = False
'Open the File to check if you already have it checked out
Workbooks.Open Filename:="http://excel-pc:43231/Shared Documents/ExcelList.xlsb", UpdateLinks:=xlUpdateLinksNever
'See if doc can be checked in
If Application.Workbooks("ExcelList.xlsb").CanCheckIn Then
'Check In, Save and Close
Application.Workbooks("ExcelList.xlsb").CheckIn SaveChanges:=True, Comments:="Checked-In before Delete"
'Open the file again
Workbooks.Open Filename:="http://excel-pc:43231/Shared Documents/ExcelList.xlsb"
'Close the workbook
Workbooks("ExcelList.xlsb").Close
End If
End If
End Sub

Create temporary sheets in excel to perform calculations

First of all, I have searched and read similar threads and I have tried the solutions that were proposed and solved the other people's problem but it hasn't worked in my case.
I basically want to create temporary excel sheet where I want to do all the calculations in the back-end and display only the output to the user in the front-end sheet.
Can anyone tell me how do I go got creating the temporary sheets and deleting them as soon as numbers are copied in the front-end sheet i.e. the sheet that user will see.
My main motive is not let the user see the various calculations that are happening in the back-end.
you can create a temp sheet in VBA by using
Sheets.Add.Name = "Temp Sheet" or any other name really
and after you calculations done on it, delete it with
Sheets("Temp Sheet").Delete
bear in mind if your alerts are on it will prompt user to agree to delete the sheet, you can avoid that by using Application.DisplayAlerts = False before deleting and follow by Application.DisplayAlerts = True after
I'd suggest to hide one sheet to perform calculations instead of creating temporary sheet.
Let's say you have input sheet, where user input his data. Another sheet is hidden. There the calculations are performed.
How to hide Sheet?
Go to VBA Code editor window (ALT+F11). Select sheet you want to hide. In a "Properties" window choose option: SheetHidden. Now, you can copy data from hidden sheet into destination sheet via using macro.
ThisWorkbook.Worksheets("HiddenSheetName").Range("A1:C56").Copy
ThisWorkbook.Worksheets("VisibleSheetName").Range("A66:C106").PasteSecial xlValues
Note: i wrote above code straight from my head. Didn't tested!
Sample code to create temp sheet:
Sub Sample()
Dim TempSheet As Worksheet
Application.ScreenUpdating = False
On Error Goto ErrorHandler:
Set TempSheet = ThisWorkbook.Worksheets.Add
TempSheet.Visible = xlSheetHidden
'Do the calculations
Application.DisplayAlerts = False
TempSheet.Delete
Application.DisplayAlerts = True
ErrorHandler:
Application.ScreenUpdating = True
End Sub

Open Excel file for reading with VBA without display

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
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.
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. :)
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.

Excel VBA macro to track changes in separate sheet

I am trying to write a VBA macro to track changes to a workbook in a separate sheet.
If you do this manually, the sequence of commands is Tools > Track Changes > Highlight Changes, taking the option Separate Worksheet. You have to do two iterations of the command, one to activate tracking inline, a second to move the tracking to a separate sheet.
Using the macro recorder, I got to this piece of code:
With ActiveWorkbook
.Save
.KeepChangeHistory = True
.HighlightChangesOptions When:=xlAllChanges
.ListChangesOnNewSheet = True
.HighlightChangesOnScreen = False
.Worksheets("History").Select
End With
When I run this, I get the error HighlightChangesOptions method fails. Any suggestions?
The HighlightChangesOptions method will only work if the workbook is already shared. In the UI, turning on HighlightChange will share the workbook automatically, but not so in VBA.
Application.DisplayAlerts = False
With ActiveWorkbook
.SaveAs , , , , , , xlShared
.KeepChangeHistory = True
.HighlightChangesOptions When:=xlAllChanges
.ListChangesOnNewSheet = True
.HighlightChangesOnScreen = False
.Worksheets("History").Select
End With
The DisplayAlerts call will prevent Excel from warning you that you are overwriting an existing workbook - itself. You may want to comment that line out just to see what's going on.
Note that this code cannot live in the shared workbook. Once you share the workbook, the code stops executing and errors. It has to live in a different workbook or add-in.

Resources