SaveAs Template With External Data Connections - excel

I have been hunting for an answer to this for almost an hour now with no luck. I have an Excel Macro Enabled Template which saves the template as a new name (still as a .xltm) but unfortunately this new file becomes corrupt because my template contains external data connections and I am using Application.DisplayAlerts = False to bypass any prompts upon saving. I do not want users to have to deal with a prompt, but when saving a template file with external data connections a prompt appears stating "This workbook contains external data. Do you want Microsoft Excel to clear the data before saving the template, and then automatically refresh the data whenever the template is opened?" with Yes, No and Cancel buttons. What I need is for the No to be selected so the user does not see this prompt and the template is saved without that feature. Is this possible?
Note: If I just leave the Application.DisplayAlerts as False, when the new template file is opened an error message is received stating the file is damaged because that external data prompt was never addressed. Not what I want to see at all.
Example of code:
Application.DisplayAlerts = False
Dim strSaveTool as String
strSaveTool = [TL_Loc] & "\New Template Name.xltm" 'where [TL_Loc] holds the directory path
ThisWorkbook.SaveAs Filename:=strSaveTool, FileFormat:=53

#PEH I am using sendKeys "N" ... Using your code add SendKeys "N" before the line that raises the prompt. DisplayAlerts needs to be on otherwise the prompt assumes Yes.
To figure out what Key to send experiment on the prompt concerned .. for the - 'This workbook contains external data etc' prompt ... Typing N is accepted in place of clicking NO
Application.DisplayAlerts = TRUE ' False
Dim strSaveTool as String
strSaveTool = [TL_Loc] & "\New Template Name.xltm" 'where [TL_Loc] holds the directory path
SendKeys "N"
ThisWorkbook.SaveAs Filename:=strSaveTool, FileFormat:=53

Related

How to deal with co-authoring while editing an Excel file in Sharepoint via VBA

I have an excel file stored in Sharepoint (which is also accessible with Microsoft Teams), with the path: https://organization.sharepoint.com/PathOfFile/myFile.xlsx
The file can be edited by multiple at the same time with the co-authoring feature in Sharepoint.
I want to use another excel file stored locally in my computer to access and modify the one in Sharepoint. This local file has a button with this VBA code in it:
Sub UpdateSP():
f_name = "https://organization.sharepoint.com/PathOfFile/myFile.xlsx"
Workbooks.Open f_name
Workbooks("myFile.xlsx").Activate
ActiveWorkbook.Sheets("sheet1").Activate
Range("A" & Rows.Count).End(xlUp).Offset(1).Select
ActiveCell.Value = 9999
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = 0000
ActiveWorkbook.Close SaveChanges:=True
End Sub
In principle it works, the file in Sharepoint is modified. But things go wrong if there's someone editing the file while I run the code, then two versions of the file seem to be created, one for the online-live editing, and the one for my code.
If this happens, the online version of the file won't show the changes made by the code, and whenever the file is opened with the excel app, a pop-up will show asking which version of the file should be kept, losing all the changes done in the disposed version.
I have tried to use the CanCheckOut and CheckOut methods, but CanCheckOut always returns False for whatever reason (there are some questions here with the same issue but I havent been able to find a solution).
Can someone suggest a solution to this issue? Thanks.
I'm not 100% sure it will work on SharePoint, but in theory, ADODB is a library for VBA that has the syntax of objects to use Microsoft's Jet Engine so you can open files AdLockOptimistic---ally. ((look up lock types in ADO.net))
This works on a file directory basis, so if the DB being modified is open, it will handle the update.
Instead of using Excel's Application to open the file, you would establish an ADO connection, and then specify the type of Lock in order to access the Excel's sheets and tables inside it.
This works for shared / network drives, so I'm guessing since SharePoint can be mapped as a file explorer drive, then ADO should work and is worth a try.
Here's a basic example to get you started: ADO question
Try enabling the autosave after activating the workbook.
To do so, add this line:
ActiveWorkbook.AutoSaveOn = True
after the Workbooks("myFile.xlsx").Activate line.
I have had similar issues with collaborative files and making sure the autosave is enabled has solved it.
To be able to incorporate changes that way your code must run inside a coauthoring context.
Instead of opening the document from another doc or local copy, the code must be running inside the same document being opened from the same source URL (Sharepoint or OneDrive), that way the add-in or macro can make changes that Excel itself will handle on a coauthoring context.
I recommend taking a look at Coauthoring in Excel add-ins of the Office Dev Center, including the linked articles inside (specifically "coauthoring", redirecting to the support center, and "About coauthoring in Excel (VBA)" at the bottom with more samples).
CanCheckOut will always return false if a workbook is open. Thus you must check before you touch it. The CheckOut command will not open the file so we must also have an open statement after CheckOut.
Using your example it would look like this;
Option Explicit
Public Sub UpdateSP()
Dim fName As String
fName = "https://organization.sharepoint.com/PathOfFile/myFile.xlsx"
If Workbooks.CanCheckOut(fName) Then
Workbooks.CheckOut fName
Dim myFile As Workbook
Set myFile = Workbooks.Open(fName)
Dim mySheet As Worksheet
Set mySheet = myFile.Sheets("Sheet1")
Dim startRange As Range
Set startRange = mySheet.Range("A" & mySheet.Rows.Count).End(xlUp).Offset(1)
startRange.Value = 9999
startRange.Offset(0, 1).Value = 0
myFile.Close SaveChanges:=True
Else
MsgBox fName & " can't be checked out at this time.", vbInformation
End If
End Sub

How to open a macro enabled Excel file on a SharePoint in edit mode from an Excel vba?

I have an macro enabled Excel file on a SharePoint that when a user opens it from the SharePoint the file opens programmatically another macro enabled Excel file on the same SharePoint. The file being opened by the vba macro needs to be edited, and must be editable by multiple users at the same time. However I can't get it to even open in edit mode. Using Office 365
I've tried << ActiveWorkbook.LockServerFile >> but always get an error message << Run-time error 1004: Method 'LockServer' of object'_Workbook' failed >>.
The code that I show below is in the Excel file that is opened manually by the user and that opens automatically the other Excel file. The other Excel file when opened works fine (if I remove the LockServerFile command), all it's macro's work fine, but it is open in read only and changes cannot be saved. Again this file should be editable by multiple users simultaneously.
' this code is in the "ThisWorkbook" tab
Sub workbook_open()
Set DB = Workbooks.Open(DBname, 3, False, , , , True)
ActiveWorkbook.LockServerFile ' this is where is crashes
'more code...
End Sub
' Note: DB is declared in a module
Public DB as Workbook
Public Const DBname As String = "https://ledvance365.sharepoint.com ... .xlsm"
Looks like << ActiveWorkbook.LockServerFile >> wasn't working because the SharePoint settings was not on "Open Documents in Client Applications by Default"
But once I got the SharePoint owner to change the SharePoint settings to "Open Documents in Client Applications by Default" the << ActiveWorkbook.LockServerFile >> command worked.
Maybe check out the following link to check if the file is already locked.
https://www.mrexcel.com/forum/excel-questions/906983-vba-support-checking-if-file-locked-sharepoint.html
Also in general it helps if you use your objects when you set them.
Dim DB as Workbook
Set DB = Workbooks.Open(filename:=DBname, editable:=True)
DB.LockServerFile
I had a similar issue. The code crashes at the same point you highlighted.
ActiveWorkbook.LockServerFile
Seems to fail when the document is already editable.
On Error Resume Next
ActiveWorkbook.LockServerFile
Fixes the issue I was experiencing since the code will continue on when the file is already editable and similarly makes a file editable if it wasn't previously.

Runtime error 424 VBA excel

I've had a some success creating a project script that throws up some dialogues to take information, place it on a worksheet (activex box) and then print.
My code runs fine when located in Sheet1 object with the VB editor. However, I want it to run on excel open, so I paste it into the thisworkbook object within workbook_open(), but nothing works.
Can anyone explain to me how I can get this script to run upon excel open, or cease to receive the 424 error when running it from workbook_open()?
The debugger doesn't like my labelbatch and labelexpiry objects (but only when in thisworkbook), but it works fine otherwise.
Private Sub Workbook_Open()
ActiveWorkbook.Sheets("sheet1").Activate
'Clears label fields prior to data entry
labelbatch.Caption = ""
LabelExpiry.Caption = ""
'Auto input of batch code into batch field using input text.
BatchNo = InputBox("Enter batch code", " ")
labelbatch.Caption = BatchNo
'Auto input of expiry date into expiry field using input text.
ExpiryDate = InputBox("Enter expiry date", " ")
LabelExpiry.Caption = ExpiryDate
'Show print dialog box
Application.Dialogs(xlDialogPrint).Show
'Close without saving changes
ActiveWorkbook.Close False
End Sub
Assuming labelbatch and labelExpiry are objects on the worksheet, when the code is moved to ThisWorkbook VBA doesn't know where to look for those objects. Use e.g.
thisworkbook.worksheets("Sheet1").labelbatch
to refer to them.
When you use a method or property name without all its parents, VBA will either throw an error or will use a default depending on the context. For example, for Cells(), Range() and the like, that default is Application.ActiveSheet. That is generally risky: it's very hard to be sure what the active worksheet will be if you later change your code (or even if a user switches sheets while your code is running). Better to specify which worksheet you want.
This does make references to objects longer, but you can always use With...End With to help readability and save typing.

Simple SaveAs Excel Macro query - Need script updating to incl. filename and .xls extension

I have a excel worksheet order form that once completed, I need the end-user to click a button to save the worksheet, before then clicking an email link for sending.
I pulled a simple save script which works fine in bringing up a Save As dialog box, but I now need to add to it:
a) the name of saved file so I can save it as Trans_Order.xls
b) to save it as an .xls so the finished worksheet ideally doesn't contain the macro when sending over email to a 3rd party
Current code is:
Sub SaveAs()
Application.Dialogs(xlDialogSaveAs).Show
End Sub
Hope you can help - would be grateful for any assistance!
The xlOpenXMLWorkbook bit saves the file as a macro-free workbook. Application.DisplayAlerts = False suppresses an alert that fires saying that the Macro elements won't be saved. It will also suppress alerts about overwriting.
Application.DisplayAlerts = False
ThisWorkbook.SaveAs CreateObject("WScript.Shell").specialfolders("Desktop") _
& "\Trans_Order.xlsx", xlOpenXMLWorkbook
Application.DisplayAlerts = True
N.B. You may need to include the full path to the workbook in the double-quotes, or it will save back to the folder of your current workbook.

Get table data in Excel 2007 from query in Access 2007

I have an automated process that is mostly run in Access. But, in the middle, it puts some data in Excel to scrub it into the correct form (it's much faster than doing it in Access), and at the end it opens another Excel file and puts data from some Access queries into the Excel file. For these connections from Excel to Access, I accomplished them all by going into Excel and doing Data --> Get External Data --> From Access, then selecting the Access file and the query I want to get the data from and tell Excel to make it into a Table.
So, I do that one time and then I want to be able to run this automated process that simply refreshes the data. To do this refreshing of the data, I do a line like:
Worksheets("Data").Range("A1").ListObject.QueryTable.Refresh _
BackgroundQuery:=False
The problem is, half the time (and I can't figure out why it does it one time and not another), it says "Do you want to connect to path\filename?" Of course I do, how else would the table refresh? So, this stops the automation. Even if I click Yes, I still can't get it to continue on. If I click Yes, it opens up the Data Link Properties. After I click OK for that, it opens a window titled "Please Enter Microsoft Office Access Database Engine OLE DB Initialization Information". It has info in it, including the path and name of the data source I want to access, but if I click OK, it says, sorry that didn't work, would you like instead to connect to (and then it lists the exact same path and file name it just said didn't work). It repeats the steps I just mentioned, and after that it errors out.
In case it matters, here is the (basic idea) code I use to connect to Excel from Access:
Public Sub ExportToExcel()
Dim ObjXLApp As Object
Dim ObjXLBook As Object
Dim ExcelFilePath As String
ExcelFilePath = CurrentProject.Path & "\"
Set ObjXLApp = CreateObject("Excel.Application")
Set ObjXLBook = ObjXLApp.Workbooks.Open(ExcelFilePath & "filename.xlsm")
ObjXLApp.Visible = True
' Runs the "DataSetUp" macro in the Excel file.
ObjXLApp.Run ("DataSetUp")
' The DataSetUp macro saves the Excel file
' Quit Excel
ObjXLApp.Quit
' Free the memory
Set ObjXLBook = Nothing
Set ObjXLApp = Nothing
End Sub
I have no idea how to fix this! Any help would be much appreciated.
This may be happening because your access database is still open from which the new excel file needs to input data back into. The database cannot be open when this takes place, hense the reason why excel errors and asks for another location to connect to.
So, I would work on generating the needed scrubbing via vba inside access probably.

Resources