Excel Sheet Project References - excel

I am programatically opening excel workbooks under a folder tree to check for some project references using the following code -
workbook = app.Workbooks.Open(fileName,false,true,Missing,Missing,.....);
foreach(Reference r in workbook.VBProject.References)
{
//check for a specific reference here
}
This works fine but my folder structure is very deep and I have over 20,000 spreadsheets stored in them. Sometimes depending on the size of the excel file, the call to Workbooks.Open() takes a long time (over 5 minutes per call on some files). Is there a faster more efficient way to do this?
Thanks for the help

It seems like whenever you have to hit the Excel object model, you're going to take a performance hit. I agree with the previous poster, that if you want to speed up performance, you'll need to read the Excel files directly.
As a side note, since Excel 2007 files (*.xlsm, *.xltm) are essentially *.zip files, you would need to find and access the vbaProject.bin file directly. A quick look points to the path as (I changed the extension so I could browse the file):
..\Book1.zip\xl\vbaProject.bin
Obviously you could dig through that bin file manually and find particular references (as suggested by the previous poster), but if you're looking to loop through all of the references in a project, you'll need to use the API calls IStream/IStorage. There's a great article about reverse engineering the Office BIN files here: http://www.codeproject.com/KB/cs/office2007bin.aspx. To access references in vbaProject.bin, look for the section titled "Reading or updating vbaProject.bin parts". There is also a sample C# code project that demonstrates how to read an OLE container. I just took a peak at the code sample, so I can't attest to it's effectiveness, but it certainly seems in order.
Hope that helps!

I don't think you can increase the Workbooks.Open performance. However if your main intention is just to check if a particular reference is used by the Spreadsheet or not, then consider opening the Excel file in binary mode and searching for the dll string.(The path of the dll providing the functionality, which can be seen in the Location part of the References Window).
This would be very crude way, but if the Workbook.Open performance is really a bottleneck then you can definitely give it a try.

Related

Referencing VBA code in .vb files (with UiPath Invoke VBA activity)

So I'm not sure if this question requires knowledge on the UiPath software in order to be answered or not. I have been developing a lot of Excel macros for my company, and as I get more and more macros, it's harder to manage them.
We have been working on some robots as well within the company, and I notice that the robot has an activity where you can invoke VBA code within an Excel application scope. This activity reads a .vb file with code and invokes whatever method you specify within that file as a macro in the activated Excel application.
Ideally I would want to extract all my VBA code into separate files, and have the robots execute the macros through this activity. This would make it a lot easier to manage the code.
My question is then, if it is somehow possible for me to also extract the modules I've created that contain utility methods that I repeat throughout many macros into a .vb file, and reference this in the other macro files?
I don't know exactly how this activity invokes the code and what restrictions are placed on it. Within Excel, I can store re-usable methods in modules and call on them from other modules. This is what I want replicated on a file level. If there was some way of adding import statements to the top of the code to retrieve methods from other modules, so I could call them within the file.
My worries (and assumption) is that the activity simply reads it as a text file, and just imports it as a macro right into Excel. That if I wanted to reference any modules within my method, the modules would have to already exist in the Excel application.
I could always paste the utility methods into every .vb file, but that sort of defeats the purpose of making it easier to manage.
Is there anything I can do here?
Thanks,
TRS
You definitely can reference external assemblies (.dlls) in UiPath. I haven't done it with VB.Net Projects, but I have done it with C# Projects which is in this case, the same thing.
Please, follow this tutorial: https://www.uipath.com/kb-articles/how-to-include-external-dll
To be able to generate the .dll, you will need to download Visual Studio Community Edition and follow a couple of tutorials on how to compile VB code.
All your VB code will exist in this .dll. This would be your general repository or main library that you would access every time that you need it. As I understand, this is your main goal anyway right? "To access utility methods".
I don't know if inside your macros, you use specific Excel references that could lead to compilation issues. So, be ready to reference everything that you need inside the code.
At the end, to access your custom methods, you would need to reference the .dll and use the activity called: Invoke Method.
I hope this helps.

How to create excel 2013 timeline from access

It's my first question here so please be easy on me..
I'm trying to create an excel report from a dataset i've created in MS Access as part of a MS-Access based large project.
This project has to run on many machines and to avoid reference errors i use late-binding.
My problem is that when i try to create (from Access) a Timeline using the "Slicercaches.add2" method my code fires error "5". As a test i've created the timeline from Excel-vba and i found that if i use the "XlTimeline" constant it works, but if i use the "2" value not . Is there a way to use the Xltimeline constant inside Access-Vba without reference to excel libraries??
Thanx in advance
MF
First off, welcome to Stack Overflow. Without seeing your VBA code, answering your question would mostly be speculation. As a common practice, it is always beneficial to show the code you're working with (same concept as a picture is worth 1000 words). With that being said, working with Excel objects (or any other office application) requires that you import the necessary libraries. With the Excel library imported, you can essentially do anything to an excel file using the Excel object. Is there a particular reason you would like to refrain from using the Excel library?

User option in Access to select unique filepath for Excel source data

I am working off of a great solution created by #MattHall from 2011 to a question that I also shared about importing a dynamic range from Excel into Access.
Specific to that--though in general for future VBA's--my question is whether there is an additional way to be able to point to the Excel source file if it is moved without having to go into the VBA editor every time?
For my specific needs, I am trying to work on these Access and Excel files with others through a shared BOX that has a different file path for whoever is working on it.
USER 1 may be: C:\Users\USER1\Box Sync\filename.xlsx
USER 2 may be: C:\Users\USER2\Box Sync\filename.xlsx
...and so forth for any other users. I am curious how we can all work off this when the file path used in the VBA created and used by USER1 is not accessible by USER2? Could there be some code that allows for the every user to locate the file each time through their own filepath?
It would be a pain to do that but I also do not know a better option as we are not working off a shared server and this is unfortunately limited to Box share at the moment.
EDIT: If anyone could also suggest how to integrate their recommendation into the 'Dynamic Range' code in solution from #MattHall in the linked Stackoverflow, that would particularly helpful to my request.

ms office file extensions

I made a discovery some time back. Just follow these steps:
Create a .doc/.xls/.ppt file in office 2003. Keep some test data in there and close the file. Now rename the file to change it's file extension to a random string, taking care that it is unassociated, like test.asdfghjkl etc.
Double click the file and it opens seamlessly in the parent application.
Now AFAIK, windows checks the file extension of the file and uses it to do an action, viz open an application and pass the file to it to open. Then how does the office suite manage to do this?
EDIT: How about the case when the extension is changed to one that is associated with another application. Is there a priority algorithm in place for handling that ?
Do you have the "View extensions for known types" option on?
EDIT: #Comments....
Yes, its a stupid/insulting question, but when troubleshooting a problem I have learned to assume nothing, and trust the users 0%.
BUT, I tried it, and you're right. Its stupid that MS has this kind of behavior, and it can only lead to security vulnerabilities, which led me on a search for your answer.
From the posts at http://seclists.org/fulldisclosure/2007/Jan/0444.html
"You have stumbled on an age-old
quirky behavior of Windows. Office
document formats are based on a
standard Windows container format, OLE
structured storage files, also known
as "docfiles". A docfile's name and
extension are irrelevant - the file
is, conceptually, a serialization of
an OLE object, and like all
serialization formats it contains the
identifier of the application that
produced it, in the form of an OLE
class id (in GUID format) in this
case. You can easily verify that it
doesn't work with the newer Office XML
formats"
Indeed it doesnt work for the 2007 *X file types, but 2K3 is still a problem. To solve this problem... Upgrade! =)
And here at security focus under TOC point 2.
So, there you go.
I can't seem to make this happen now, but I know I saw Windows reading XML processing instructions a few years back. Maybe that is what's going on?

How best to export native data to Excel without introducing dependency on Office?

Our product has the requirement of exporting its native format (essentially an XML file) to Excel for viewing/editing. However, what this entails is having a dependency on Excel (or Office) itself for our product build - something that we do not want.
What we have done is export the data from our native format to a csv file which can be opened in Excel. If user selects an option to open the generated report as well, we (try to) launch Excel application to open it (ofcourse it requires Excel to be already present on the client system).
The data for most part is flat list of records.
Is there a better format (or even a better way) to handle this requirement? This is a common requirement for many products - how do you handle this?
Excel versions, both 2007 and several previous, have native XML formats. 2007, obviously, is XML by default, and earlier versions have the ability to save as XML. This SO question deals with the issue. I'd guess a little inspection would give an idea of what's required. I don't know if a XSD/DTD exists for older versions, but a little creative Googling might yield something.
As other people pointed out, it is reasonably easy to generate Excel XML files. You can do this in multiple ways. For example:
By creating a template Excel XML document, and then using XML DOM to stuff your data into the template, or
Converting the template Excel XML into an XSLT, and then simply passing your proprietary XML as input to XSLT.
I'm using ExcelPackage to create spreadsheets in one of my side projects. Works pretty good, but (at least the version I'm using) its a bit limited when it comes to styling and calculations.
ExcelPackage lets you create OOXML docs (.xslx files) that are natively compat with 2k7, but you can download a plugin for previous versions of Office from MS.
We export our data either using Excel objects (COM based code) on client side or CSV file (usually on server side, but can be used on client side too). And we allow copy data from grids in simple html format, what can be pasted into Excel without problems.
For one customer we even had to export data [from sql stored procedure] into csv-like tab-separated format, but named file like xxxxx.xls - this way excel opened that file in more correct way than csv file. Ugly hack, but worked well.
CSV is most compatible format (no dependencies on external applications or libraries), but customers don't like it. Maybe we need to incorporate some XLS export code, this way all users will be happy :)
If .csv isn't formatted enough, you could create a template in Excel, and use a little bit of VBA code to import the CSV and format it appropriately. This way your app is only concerned with generating the .CSV, and will use the same .XLS for each export.
If you're careful, you should be able to get this to work with most versions of Excel seamlessly.
With Perl there are several modules that can be used to produce .xlsx files without requiring an Office installation. Among those :
https://metacpan.org/pod/Excel::Writer::XLSX is the most well-known, with support for many Excel features like colors, formatting, etc.
https://metacpan.org/pod/Excel::ValueWriter::XLSX (I'm actually the author) has less features but is optimized for fast writing of large amounts of data
If you are working in Java, Checkout the POI project from APACHE.
http://poi.apache.org/
Simple, nice, complete, powerful.
We started with Office on the server, but that's not very nice. We had to kill processes that hung, and had quite a bit of a performance dip. We thought about putting it on a different machine, but didn't bother after trying and using Aspose (commercial). We don't have a very large number of simultaneous users, but complex documents. Simple ones can be handled easier with csv.
I've used FlexCel Studio for a couple of projects now. It's very functional and fast. 100% managed code, no dependencies. Sounds like you'd use the "Reports" feature which allows you to define an empty report template in Excel, then pass datatable and volia, it's populated with your data.
TMS Software
We use a combination of OleDB and Interop. We found that Interop was much faster and used less memory, but it's a pain for compatibility issues, especially when using different language installs of Office.
OleDb has the advantage that you don't require Excel to be installed on the client machine. Both Interop and OleDb support multiple sheets (tables) per workbook which you cannot do with csv.
If you're using C# or VB.Net, and your data is in a a DataSet, DataTable or List<>, then you can use my free "Export to Excel" class.
It uses the free Microsoft OpenXML libraries (so you don't need to have Excel on your server), and lets you export your data into a "real" .xlsx file with just one line of code, eg:
DataSet ds = CreateSampleData();
CreateExcelFile.CreateExcelDocument(ds, "C:\\Sample.xlsx");
All source code is provided on the following page along with a demo project, completely free of charge (and popups !)
http://mikesknowledgebase.com/pages/CSharp/ExportToExcel.htm
Hope this helps !

Resources