Open an Excel file in VBA without loading add ins? - vba

I have some code that opens a file, copy/pastes some cells into a merged sheet, closes the file; then loops for all the files in a folder. Something like this:
Set SourceFile = Workbooks.Open(FilePath & FileName)
Set Ltab = SourceFile.Worksheets("Sheet1")
Ltab.Cells.Copy
NewTab.Cells.PasteSpecial xlPasteValuess
SourceFile.Close
Is there a line I can add that will stop Excel from loading add ins every time a file is opened? There are a lot of files and loading the add ins adds a good 5-10 seconds every time.
This didn't really answer my question, as I need a way to do it in VBA.
Thanks

So if you dont wana to disable all addins without naming them, and Installed = false is correct aproach try to iterate them with for each
Sub runWithoutAddins()
Dim var As AddIn
For Each var In AddIns
var.Installed = False
Next var
End Sub
I dont need to know their name, but this will loop every object in AddIn collection and set their atribute Installed to false. (which if im understanding it well, will disable them)

Related

Update an excel file by multiple users at same time without opening the file

Scenario
I have an excel file that contains data. There are multiple users accessing the file at the same time.
Problem
There will be problem if multiple users tried to input data to that excel file at the same time due to only one user is allowed to open the file at one time
Question
Is there any way whereby I can update the excel file (Eg: add a value to a cell, delete a value from a cell, find a particular cell etc) without opening it so that multiple users can update it at the same time using excel VBA?
I went to the direction of using shared files. But later found out to be excel shared files are very buggy. If use shared file, excel/macro can be very slow, intermittent crashes and sometime the whole file may get corrupted and could not be opened or repaired afterwards. Also depends on how many users use the file, the file size can grow quite big. So it is best not to use shared workbook. Totally not worth trying. Instead if need multiple users to update data simultaneously, it is better to use some database such as MSAccess, MSSql (Update MSSQL from Excel) etc with excel. For my situation since number of users are less, I didn't use any database, instead put a prompt for the user to wait until the other user close that file. Please see the codes below to check if a file is opened and if so, to prompt user. I got this code from stack overflow itself and I modified to suit my needs.
Call the module TestFileOpened as below.
Sub fileCheck()
Call TestFileOpened(plannerFilePathTemp)
If fileInUse = True Then
Application.ScreenUpdating = True
Exit Sub
End If
End Sub
Here plannerFilePathTemp is the temporary file location of your original file. Whenever an excel file opened, a temp file will be created. For example, your original file location is as below
plannerFilePath = "C:\TEMP\XXX\xxx.xlsx"
Thus your temporary file location will be
plannerFilePathTemp = "C:\TEMP\XXX\~$xxx.xlsx"
or in other words, temporary file name will be ~$xxx.xlsx
The following codes will be called upon Call TestFileOpened(plannerFilePathTemp)
Public fileInUse As Boolean
Sub TestFileOpened(fileOpenedOrNot As String)
Dim Folder As String
Dim FName As String
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(fileOpenedOrNot) Then
fileInUse = True
MsgBox "Database is opened and using by " & GetFileOwner(fileOpenedOrNot) & ". Please wait a few second and click again", vbInformation, "Database in Use"
Else
fileInUse = False
End If
End Sub
Function GetFileOwner(strFileName)
Set objWMIService = GetObject("winmgmts:")
Set objFileSecuritySettings = _
objWMIService.Get("Win32_LogicalFileSecuritySetting='" & strFileName & "'")
intRetVal = objFileSecuritySettings.GetSecurityDescriptor(objSD)
If intRetVal = 0 Then
GetFileOwner = objSD.Owner.Name
Else
GetFileOwner = "Unknown"
End If
End Function
I encountered Out of memory issues also when used shared files. So during the process, I figured out the following methods to minimize memory consumption
Some tips to clear memory

is it possible to create an image that will load via URL with EPPlus?

I need to embed images into an Excel spreadsheet using EEPlus. There 1000's of rows, so embedding these as Pictures is not an option since this file gets generated via a website and the file would be huge and slow to create.
It would be nice if there were a way to set the URL of an image and have it load when the document is opened. Is this possible?
If you are staying within the confines of excel, the only way I can think of doing it is with using vba with something like this:
How to get images to appear in Excel given image url.
Can then have it resave itself as non-macroed workbook. Something like this:
//add the macro to call sub that applies the url on open
workbook.Worksheets.Add("newworksheet");
var sb = new StringBuilder();
sb.AppendLine("Private Sub Workbook_SheetCalculate(ByVal Sh As Object)");
sb.AppendLine(" ApplyUrlsSub");
sb.AppendLine(" Application.DisplayAlerts = False");
sb.AppendLine(String.Format(" ActiveWorkbook.SaveAs \"{0}\", xlOpenXMLWorkbook", file.FullName.Replace("xlsm", "xlsx")));
sb.AppendLine(" Application.DisplayAlerts = True");
sb.AppendLine("End Sub");
pck.Workbook.CreateVBAProject();
pck.Workbook.CodeModule.Code = sb.ToString();
(adpated from: EPPlus Pivot Table - Copy Values to New Sheet)
But the user still needs to enable allowing the initial xlsm to run with macros which sould be a problem is there are security concerns.

PowerPoint 2013 macro keeps file locked open after close command

I have a PowerPoint VBA function that opens presentations, copies slides into the active presentation, then closes the source presentation. It worked fine in 2010, but fails in 2013 (all on Windows 7) if it tries to open the same presentation more than once. It appears to me that after the presentation.close command is issued, the window is closed, but the file remains locked open until the VBA code exits. So if the code attempts to open that file again it returns the error:
"Method 'Open' of object 'Presentations' failed"
Here's a simplified form of the function I'm running that behaves the same way. I've had a colleague test this again in PowerPoint 2010 and it runs fine. I've also had a colleague test it under his 2013 to make sure it's not something with my particular installation.
Sub testopen()
Dim ppFile As Presentation
Dim i As Integer
Const fpath = "C:\test.pptx"
For i = 1 To 2
Set ppFile = Application.Presentations.Open(fpath)
ppFile.Close
Set ppFile = Nothing
Next i
End Sub
The file test.pptx is just a blank presentation. In debug mode I can see the file opens and closes on the first loop, then on the second loop the open command fails and I can see in Windows explorer that the hidden temporary file still exists, indicating the file is still open, until I exit the VBA code. I also verified that the file is held open by adding in a function to check the file open status.
I've spent probably an hour googling this and cannot find any other descriptions of this problem. I'm sure I can implement a workaround but it's driving me crazy that I can't find any other reports of seemingly such a simple issue. Any suggestions are greatly appreciated! Thanks.
The Best way that I have achieved this is to simply create a VBS file and in the VBS file I call out the desired VBA code. It's little more hassle than to write the VBA code, but it's the solution that worked for me.
For example in the VBS file:
Dim args, objPP
Set args = WScript.Arguments
Set objPP = CreateObject("Powerpoint.Application")
objPP.Open "C:\path\to\file.ppx"
objPP.Visible = True
objPP.Run "The_Macro"
objPP.Save
objPP.Close(0)
objPP.Quit
Or better yet, have the entire code within the VBS file and have it copy the desired slides.
Hope this helps you achieve your result.
Setting the file as Read Only resolved the issue. The open command is now:
Set ppFile = Application.Presentations.Open(fpath, msoTrue)
Also, saving the file before closing it resolved the issue. For that, add:
ppFile.Save
Interestingly, I had already tried setting the Saved property to True (ppFile.Saved = msoTrue), which does NOT work. Thanks to Michael for his suggestion on the VBS script. That does work and I had never run an external VBS script so I learned something new. In this case, I'd prefer to stick with a VBA solution.

Batch add a macro to word documents?

I have several hundred .doc word documents to which I need to add a macro which runs when the .doc file is opened and creates a header for said document based on the file name. Is there a way to do this as a batch? I have been individually opening each document and going into visual basic --> Project --> This Document then inserting a .txt file which contains the code. Is there a fast way to do this for multiple documents?
As a learning exercise, put this into the "ThisDocument" part of Normal (the Normal.dot template) in the VBE
Open a word document and watch what happens.
I don't think you need to put your code in every single file, I think you should be OK with using the Document_Open event in Normal.dot.
Just make sure it shows up as a reference in your word documents that you open but I don't see why it wouldn't
If you absolutely need it in every file then it can be done but the problem is if you make one small change to the code, you have to go through all this again. The idea with code is to write it once, use it many times.
You can write VBA code that alters the VBA code in other documents, but you need to "Trust access to the VBA project object model" in the Trust Centre options. This could open you up to viral code if you download Word documents with malicious VBA code in them. What you want to do, essentially, is write a VBA virus. There are legitimate reasons for doing this, and also malicious ones, I leave the ethics of the uses of these techniques up to the user. Knowledge itself is not malicious.
Here's the meat, you will need to write your own code to loop through the documents and possibly save them as .docm files.
Sub ReplaceCode()
Set oDoc = ActiveDocument
Set oComponents = oDoc.VBProject.VBComponents
For i = oComponents.Count To 1 Step -1
If oComponents(i).Type = 100 And oComponents(i).Name = "ThisDocument" Then
With oComponents(i).CodeModule
.DeleteLines 1, .CountOfLines
.AddFromFile "C:\ThisDocument.cls"
End With
End If
Next i
End Sub
Also, if you create your code file by exporting from VBA, you will need to remove this from the top of the .cls file:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Personally, I would drive this from Excel, maybe using a worksheet to hold a list of the files or locations to update, and another sheet for the code to populate with a list of files updated.

VBA fails to find a file

I have a VBA script used to process Word documents. The first thing the program does is to create an index of the documents in a defined set of folders. It then goes through the list processing each of the indexed documents.
The problem I am having is that it will sometimes decide that a particular document cannot be found, even though it previously indexed the document and a quick spot check shows the document to be in the correct place.
Can anyone shed some light on why VBA should display this behaviour?
The script is using the Dir$ function to index the files, and the Documents.Open function to open each word document for processing.
Sample code:
ChangeFileOpenDirectory (folderName)
inputFileName = Dir$(folderName & "*.doc")
Do While inputFileName <> ""
... call various functions here ...
inputFileName = Dir$
Loop
One of the functions called in the block has the following line:
Set currentDoc = Documents.Open(fileName:=docFileName, AddToRecentFiles:=False, Visible:=False)
This is the point at which the code is failing.
One of the most annoying things I have found is that recent files links are returned as the files themselves with Dir. You can use the FileSystemObject to check the file type.
I copy/paste your code and it works correctly.
However, it leaves all the files open (and hidden), and when you run it in another directory, additional files are opened and added to the open projects (take a look in the VBA editor).
My only guess is that after a while you're hitting the maximum allowable number of open files.
Try adding
currentdoc.Close
just before
inputFileName = Dir$
A few reasons, some duplicated from other answers:
If the path+ filename is long enough ... (you already answered in a comment)
If you are writing new files to same directory, Dir$ may get corrupted (happened to me)
If you have filenames with non-std chars (ex. "#")
Files locked by other processes
Files deleted while the macro is running
You may also try this code ...
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(file) Then ....
First enable the Microsoft Scripting reference in the VBE