Copy embedded text file from an Excel sheet with VBA - excel

I have an Excel sheet with an embedded txt file which I would like to copy into a certain target folder.
I used the following code which works fine if I use it from my computer:
'copy oleobject
ActiveSheet.OLEObjects(1).Copy
'paste to activeworkbook's path
CreateObject("Shell.Application") _
.Namespace(ActiveWorkbook.path) _
.Self.InvokeVerb "Paste"
However, some of my colleagues did receive the text file which was embedded in the Excel sheet with an additional line beforehand which included the file save path in the temporary folder.
I could just delete this line with VBA but I would like to understand why this happens with other computers and not with mine.
Please help!
Thanks

OK so here is the issue:
txt file is a template and VBA is supposed to read it in again in a string file and change it. Until now it was just saved in a different folder and that worked fine but for mobility reasons (to be used by many other users) it would be a great advantage if it could be handled with just one file.
It is possible to do this with txt file embedded in Excel, but embedded files are not really well-supported by VBA automation. Most files only have a few methods available, and if I remember correctly with TXT file type, the available method is to open the file.
ActiveSheet.OLEObjects(1).OLEFormat.DoVerb 1
I mentioned a similar problem that I had (in PPT, instead of Excel, but the issue is the same). The route we chose initially was given here:
Extracting an OLEObject (XML Document) from PowerPoint VBA
Invoke the .OLEFormat.DoVerb 1 to open the file in Notepad
Use WinAPI functions to read the contents of Notepad into a string
variable
Use WinAPI functions to close Notepad
Use FileSystemObject to write/modify a new text file
Embed the new, modified text file
The functions to find and read Notepad contents are documented here and require some use of WinAPI functions (all noted in the link):
http://www.excelforum.com/excel-programming-vba-macros/729730-access-another-unsaved-excel-instance-and-unsaved-notepad-text.html
This is a LOT of work for not much benefit, instead you could simply open a file dialog prompting user to choose the text file (located on a shared network drive, etc.). This would be much more reliable.
Alternatively, depending on the size of the text file, you can store the contents inside a Shape (and you can put the shape on a hidden worksheet, etc.), either in the .TextFrame or another property that allows text. Ultimately we abandoned the solution in the links above in favor of storing the contents inside a Shape's .AlternativeText property. This worked very well for us, in storing XML contents of about 500,000 to 1 million characters per file.
The reason we chose not to go the Notepad route is that there was a lag while the file is being read and user could accidentally interrupt the procedure, corrupting the file(s), etc. and that Notepad doesn't fully support automation, etc.
I also thought of using a text field but if the oleoobject would work I thought I could also embed other file types like pictures.
Pictures are easy to work with because they have a built-in .Export method.

Related

Excel behaves strange with XSLX file created manually

Based on knowledge gained through working with the OpenXML SDK, I have implemented an Excel generator in JS (using TypeScript with ReactJS and a custom JSX factory generating plain XML). The files generated open fine in Excel and one can also edit and save them fine in Excel, no errors.
However, if one tries to copy cells (even a single one) from such a generated Excel file to another worksheet in the same Excel instance, it fails with the error "The command cannot be used on multiple selections.". Just saving and reopening the file is enough to fix the problem. Copying to other applications (e.g. Notepad) works fine.
It seems that this particular error is shown by Excel in several edge cases where the data is not exactly meet the expected format, for instance I found reports of that happening when a sheet is hidden when manipulating it via VBA. However, in my case I'm not sure what could be causing the issue.
Just saving the file in Excel unfortunately significantly alters its parts, so that I couldn't get a meaningful diff out of it. I did not see what could be causing the problem. Maybe someone has some experience with the internals of Excel?
To get a sample file, copy the following into your browser address bar and save it as xlsx file:
data:application/vndopenxmlformats-officedocumentspreadsheetmlsheet;base64,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
Well, I don't know the particulars of how you are generating the xml file, but I can tell you how to edit the underlying xml files so that it will work, and then perhaps you can figure out how to use your implementation to change the property that's gunking things up.
First, an xlsx is a set of xml files. I'm sure you know that, but I'm just starting at the beginning. You can change the extension to zip and then extract the files, and then rezip them and change the extension back to xlsx.
So do this:
take the generated xlsx
change the extension to .zip
extract the files
find xl\worksheets\sheet1.xml
open it and find this property: worksheet>sheetViews>sheetView:tabSelected
set it to 0
save the file
go back to the unzipped folder
select all files and send to zip
change the extension on the new zip file to .xlsx
You should now be able to open the newly created xlsx, add a new sheet, and copy freely.
If this works for you, then you have diagnosed the problem, one property set to true when it shouldn't be, and it should be relatively simple for you to modify your export procedure.
I've had this issue multiple times in the past.
The way I solved it was by filling out (populating) a template (file, previously created in Office) with the exported data rather than generating a file from scratch. Office unfortunately does not fully comply with OpenXML, and for more complex exports you might even be unable to open the file.
I would also recommend Beyond Compare (now Scooter Software) for comparing the two files instead of just doing a diff.

Retrieve data from server and operate a GUI

I just want to know if this is possible using VBA, if it is possible, I will try to code it and if not I should look for another platform where it is possible.
Let me explain:
We have 1 main excel file. There`s a header name and a bunch of different values and settings we need to use.
We have a online server where the code has to look for the header name and just click on the name. This will automatically download to the download folder and we can copy this file in the same folder as the main excel file. There is no search function inside the online server. It is just a webpage where there is a list of names.
Inside the downloaded file is an xml file that we can open with notepad and we need to compare the settings inside the notepad with the settings from the main excel file (this I know it can be coded)
Then a GUI has to be opened (we dont have access to the server behind it), it should fill in the header name in the textbox from the GUI, click upload and then it should save it in the same folder as the main excel.
we also need to move a lot of folder based on the info from the main file but this is also basic coding.
Since Im quite new with the VBA coding, I only wish to know if this is possible in excel. I dont want to wast time searching for codes and then realize it is not possible , especially with the GUI operating.

Updating "text connection" path using provided string and preserve text to column settings

I have an Excel file with several sheets connected to many external csv files. This has worked fine for now working on my own, but now I'd like to be able to move the Excel file and/or csv files, or hand them off to someone else, and not break the connections.
The method here works for updating the file name based on a provided string:
Editing "text connection" paths
...but it doesn't preserve the text to columns settings after updating the path. Since I'm dealing with csvs, I need the import to come in as comma delimited. Since I'm dealing with a lot of connections in a single file, I'd also like to be able to let the user define a single path somewhere, and have it automatically use that path to find the files.

File that normally opens our application, but will fall back to Excel

Our application exports snippets of databases in XLSX format. We wrote our own code on top of System.Packaging as it is many (many!) times faster than using the Excel objects.
Right now we save these files with a .xlsx format, and that works OK. However, it would be much nicer if double-clicking one of these opened our app instead, but failed back to Excel on machines without it.
I know that SpreadsheetML has a feature to do this. If you insert this near the top of the file:
<?mso-application progid=""Excel.Sheet""?>
some sort of magic occurs that causes Excel to open on Win machines. While this might work in SML files, it does not appear to work in "real" xlsx files - I tried adding this line to various parts of the workbook structure but it remained unrecognized.
So is there a similar mechanism we can use in "true" XLSX files generated by System.Packaging? Or some other Windows mechanism we should use in these situations?

Matlab: open files 'outside Matlab' by default

I'm looking for a way to have Excel files in my Matlab folder open 'outside Matlab' (i.e., by MS Excel in most cases) directly by double-clicking the file, rather than right-clicking and selecting 'Open Outside Matlab'.
The .xls files reader built in Matlab can be terribly slow for large files, and an unwanted double-click on a file can cost quite some time in which Matlab is unresponsive.
Thanks.
When you click something in the Current Folder tab, it's actually running the open command, which itself calls finfo to determine what it means by "open" for a given extension. You can see this by creating a breakpoint in open.m directly after the line [~, openAction] = finfo(fullpath); and double clicking - when it hits the breakpoint you'll see it returns openAction as uiimport.
In theory, you can create custom methods for extensions by creating on the path a function openabc where abc is the extension, which should be returned as the openAction.
However, if I look at my finfo.m it first searches for said functions and then regardless of whether or not it finds them if there is an inbuilt method it overwrites them with the standard behaviour. There's even a comment:
% this setup will not allow users to override the default EXTread behavior
If you are willing to muck about in the inbuilts, you may be able to do it like this (backup first! - this could affect other things). I did it temporarily by shadowing the existing finfo like this:
edit finfo.m (Now save a copy to the current folder)
Add these lines after the loop that defines the openAction (in my version, around line 85):
if any(strcmp(['.' ext], matlab.io.internal.xlsreadSupportedExtensions))
openAction = 'winopen';
end
From the folder containing your edited finfo.m, type which finfo -all. You should see two copies, the MATLAB one labelled as shadowed. Opening something from the current folder window should now open Excel externally.
I don't believe there's any straightforward way to do that. It's built in to MATLAB that Excel files will open in the import tool when you double click on them, and there's no way to change that.
You might be able to get around it by changing the file extension on your Excel files to something other than .xls or .xlsx. That would stop MATLAB from opening it in the import tool. Then in Windows, you could associate the new file extension with Excel.

Resources