Verifiy if an xls file contains VBA macros without opening it in MS Excel - vba

I have a big set of .xls (Excel 97-2003 Workbook) files. A few of them contain VBA macros inside, I would like to find a way to filter them out automatically without opening them one by one in MS Excel.
There is an old post which is similar to my question, I have downloaded the OLE Doc viewer, but cannot open the .zip file, it seems that it is out of date...
Does anyone know if there is any API or tool to check if an .xls file contains VBA macros without opening it in MS Excel? In the first place, I don't bother to know the content of the macros.
PS: for a .xlsx or .xlsm file, we can change their file extension to .zip which contain some .xml files and eventually vbaProject.bin for VBA macros. However, this approach does not work for .xls file, renaming it does not make a valid .zipfile.

Here is a simple Python 2.7 solution I've cooked for you:
It depends only on the OleFileIO_PL module which is availble from the project page
The good thing with OleFile parser is that it is not aware of the "excel-specific" contents of the file ; it only knows the higher level "OLE storage". So it is quick in analyzing the file, and there is no risk that a potentially harmful macro would execute.
import OleFileIO_PL
import argparse
if __name__=='__main__':
parser = argparse.ArgumentParser(description='Determine if an Excel 97-2007 file contains macros.', epilog='Will exit successfully (0) only if provided file is a valid excel file containing macros.')
parser.add_argument('filename', help="file name to analyse")
args=parser.parse_args()
# Test if a file is an OLE container:
if (not OleFileIO_PL.isOleFile(args.filename)):
exit("This document is not a valid OLE document.")
# Open an OLE file:
ole = OleFileIO_PL.OleFileIO(args.filename)
# Test if known streams/storages exist:
if (not ole.exists('workbook')):
exit("This document is not a valid Excel 97-2007 document.")
# Test if VBA specific streams exist:
if (not ole.exists('_VBA_PROJECT_CUR')):
exit("This document does not contain VBA macros.")
print("Valid Excel 97-2007 workbook WITH macros")
I tested it on a couple of files with success. Let me know if it's suitable for you

Related

Word VBA Documents.Open deleting files in folder when falsely passing that folder's path instead of file path

I encountered the following issue:
When accidentally passing a folder path to the Documents.Open function in VBA Word I get the runtime error 5174 as one would expect.
However all files with names that begin with an underscore get deleted in that moment from that folder.
To replicate:
Assume folder C:/Test/
In said folder have two files:
test.txt
_test.txt
In Word VBA execute the command:
Documents.Open("C:/Test/")
(As part of a subroutine or in the immediate window.)
Result: Runtime Error 5174 and _test.txt is now missing.
Note: Passing a nonexisting file like "C:/Test/abc.txt" or a wrong folder path like "C:/Test" (without the last slash) will not have this effect and won't cause the runtime error.
I have only tested this on one system on a network drive under windows 10 with Microsoft Professional Plus 2019. It's entirely possible that it's an issue with the file system. Does anyone have any suggestions as to why is this happening? I now included the workaround to check if I'm passing a folder, but it's still unnerving.
The Documents.Open method opens the specified document and adds it to the Documents collection. It is designed to take the file path, not a folder. If you want to allow users to pick file(s) you may consider using the file open dialog. The FileOpenDialog triggered by your code which opens a folder for picking files allows specifying file formats that should be supported and visible via the dialog window.
Set dlgSaveAs = Application.FileDialog(msoFileDialogFilePicker)
dlgSaveAs.Filter = "Text Files (.txt)|*.txt|Word Documents (.docx)|*.docx|Word Template (.dotx)|*.dotx|All Files (*.*)|*.*"
dlgSaveAs.ValidateNames = true
Res = dlgSaveAs.Show

Error in *.xlsm file when writing strings using xlsm

I am using openpyxl (2.3.2) to write out an xlsm file. I can write the numeric values correctly but the string values are corrupting the xlsm file. In the code example below, the xlsm file is corrupted but the xlsx file works well
When I open the xlsm file , I get a error
we found a problem with some content in samp2.xlsm
On continuing, I see only the numeric values are written and not the string values. This does not happen with the xlsx file.
This is a strange problem
PS The "Samp.xlsm" and "Sample.xlsx" Files are new files saved with these names. They do not have any content.
Appreciate any suggestions/feedback

Which file types are associated with an Excel workbook that has a file format with a value of 63?

Does anyone know which file types are associated with an Excel workbook that has a file format with a value of 63? I have already looked at the MSDN article about the "XlFileFormat Enumeration", but I have not found the value of 63 there. Can anyone help or share a useful web link?
Update to deliver a Minimal, Complete, and Verifiable example:
Create a new blank .txt file and encode it as UTF-8 with BOM (you can use a program like Notepad++ for that task)!
Open Microsoft Excel (I used Microsoft Excel 2010 32-bit for Windows)!
Within the opened Excel application open the newly created .txt file with "File" --> "Open"!
Within Excel create the following VBA macro and execute it to get the "XLFileFormat" value for the currently active workbook or rather the opened .txt file!
Public Sub ShowFileFormatOfActiveWorkbook()
MsgBox ActiveWorkbook.FileFormat
End Sub
If you have followed the above instructions correctly, you should get a value of 63 (from Excel 2010, but a value of 64 from Excel 2013/2016).
Repeat the above instructions with an UTF-8 encoded .csv file! You will get a value of 63 (or 64 depending on the Excel version you use) again.
Do just UTF-8 encoded text-based files (e.g. .txt, .csv, .html) have a "XlFileFormat" value of 63 or do exist some more file types which match the mentioned "XlFileFormat" of 63?

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.

Forcing to save xlsx format in client side from xlsm file in server side

I have myfile.xlsm formate file in server side as read only in that i wrote some VBA to file columns in excel.When client access that file i'm just showing the filled file.While client tend to save the file it goes to SaveAs because it read only.It saving as myfile.xlsm in client side.Now my problem is :)
if client tend to save the file from saveas option it is suppose to save only as myfile.xlsx formate as ordinary xml file not macro enabled file.
What i have to do in VBA to do this action (may be write some thing in before save event)..??
I have created the one private method and add this line `ActiveWorkbook.SaveAs Filename:="Formula.xlsx", FileFormat:=xlOpenXMLWorkbook` and calling this method .. ha it worked !!