automate excel file processing in perl and avoid dialog/UI interactions - perl

How can a I guarantee that no pop-up dialogs will appear when I automate Microsoft Excel through OLE? I'm using a Perl module (Win32::OLE). I can avoid most dialog pop-ups using the following code:
use Win32::OLE;
use Win32::OLE::Variant;
use Win32::OLE::Const;
my $excel_symbols = Win32::OLE::Const->Load('Microsoft Excel');
my $excel = Win32::OLE->new('Excel.Application', sub { $_[0]->Quit();} );
$excel->{'Visible'} = 0;
$excel->{'DisplayAlerts'} = 0;
$excel->Workbooks->Open('c:\some_excel_file.xls',
{ 'UpdateLinks' => $excel_symbols->{'xlUpdateLinksNever'},
'ReadOnly' => 1,
'IgnoreReadOnlyRecommended' => 1
});
However for some files, I continue to get a dialog with the following text:
This file is not a recognizable
format.
If you know the file is from another program which is incompatible with
Microsoft Excel, click Cancel, then
open this file in its original
application. If you want to open the
file later in Microsoft Excel, save it
in a format that is compatible, such
as text format.
If you suspect the file is damaged, click Help for more information about
solving the problem.
If you still want to see what text is contained in the file, Click OK.
Then click Finish in the Text Import
Wizard.
OK Cancel
Sometimes a similar dialog appears that contains 'OK', 'Cancel' and 'Help' buttons.
I cannot control the quality of files that are provided to the scripts.

You could consider using Spreadsheet::ParseExcel (albeit it may lack features you need) or Apache POI (albeit it will need some wrapping to use in a Perl script) instead of calling the Excel engine over OLE. That way you won't get any Excel-generated dialogs.

I revisited this issue and found a solution.
Copy the file before processing to a temporary location. Then save the file before closing it in Excel:
File::Copy::copy('c:\some_excel_file.xls', 'c:\temp\SFO3jfd.xls');
my $book = $excel->Workbooks->Open('c:\temp\SFO3jfd.xls',
{ 'UpdateLinks' => $excel_symbols->{'xlUpdateLinksNever'},
'ReadOnly' => 1,
'IgnoreReadOnlyRecommended' => 1
});
$book->Save();
$book->Close();
Why this works:
Excel 2003 automatically recalculates the formulas in documents that were created in an older version of Excel. Furthermore, macros could be invoked when the document is opened. All of this means that there could be changes made on a document, even though your script doesn't perform any such operations.
By saving the document before closing, you avoid the dialog requesting that you save the file. Using a temporary file ensures that the original file does not get changed during the validation operation. If you aren't concerned about this, you might consider validating in-place.

Here is full documentation for Open method. I wonder if CorruptLoad parameter is what you need.

If you are trying of process all xl files in the tree, some of them may be open by other users and have the ~ prefix.

Related

Word addin, set filename

If one starts a blank file on Word you can usually see in the top bar a name such as "Document1", "Document2" and so on.
Yet, if you attempt to open a file using the Word JS API like this:
Word.run((context) => {
context.application.createDocument(documentB64).open()
return context.sync()
})
The top bar comes out like this:
No filename is set.
To set a filename/handle(?), I tried using the code given here Office JS - Add customProperty to new document but that didn't help.
My addin is usually used in conjunction with another (VSTO) add-on and that add-on can't work properly with the documents opened by my addin and I believe the lack of a filename (/handle?) explains it to some extent.
Is there something I can do about this?
Thank you
Currently you can't do this because the newly created document is just a temporary file and not saved. can you try to call the following code to make sure the newly created file is saved?
const documentCreated = context.application.createDocument(externalDoc);
documentCreated.save();
documentCreated.open();

How to upload a file in a test through Open Windows using Selenium::Remote::Driver Perl package

Below are the additional bullets :
I can get my "button" with following code :
$elem = $driver->find_element('//*[#id="file_uploader"]/div/div/div/div[1]/div[1]/div/span');
$driver->mouse_move_to_location(element => $elem); # xoffset => x, yoffset => y
$driver->click_ok('LEFT');
$driver->pause(3000);
But after that, I can't get anything in Opened Window which appears . How is it possible to upload a file?
PS: Here screenshot of my Developper Tools.
In Blue
Thanks in advance !
Selenium can not deal with OS dialogs. Therefore there is no way to deal with this dialog. This means you need to upload a file without opening it.
Luckily Selenium allows the user to send the filepath to the file input. This will upload the file.
In order to make it work you first need to find the input element instead of the button. It'll look something like:
<input type='file'>
Once you've found this element you can send the filepath to it like you would send any text to a textfield. I'm not sure how to do this in perl, but in Python you can achieve it like this:
element.send_keys('path/to/file')
You'll probably know yourself what the perl equivalent is.
In fact, it's more specifical. I have two ways to upload a file in my web application :
First user can use a button 'select file'.
Second you can drop directly file .
By second way, and using "upload_file" method in Selenium::Remote::Driver package as it was proposed here, it's possible. I do that :
my $fname = "D:/dev/tests/selenium/phantomjs-2.1.1-windows.zip";
my $remote_fname = $driver->upload_file( $fname );
my $element = $driver->find_element( '//*[#id="file_uploader"]/div/div/div/div[1]/div[2]/input[#class="dx-fileuploader-input"]' );
$element->send_keys( $remote_fname );
But not with my "button".
How is it possible ? I'm forwarding you additional screenshots here :
In red 'button' and blue 'drop file'

Getting OLE Exception while closing document in Perl

I am getting following exception in perl. Also i am now to perl technology.
Exception is :
Win32::OLE<0.1709> error 0x800a1423
in METHOD/PROPERTYGET "Close" at getWordComments.pl line no 350
here is the sample code of getWordComments.pl where exception is comming.
A) Following code for opening the document
#Open the document in MS Word
use Win32::OLE;
{
no warnings;
use Win32::OLE::Const 'Microsoft.Word'; # wd constants
}
$word=Win32::OLE->new('Word.Application');
$word->{Visible} = 1;
$word->{DisplayAlerts} = 0;
$Document=$word->Documents->Open({Filename => $filename, ReadOnly => 1});
B) Then i am reading the comment.
C) Following code for Closing the document.
$Document->{Saved}=1;
$Document->Close;
undef $Document;
#Close Word
$word->Quit;
undef $word;
is this problem with office version?
because document is with .docx. its working properly for .doc.
Please help me to solve this issue.
I am reading the comment form the document and saving the document on server. Its working fine for rest of the document with extension *.docx and *.doc
Also can you please provide me like how i can do this in perl.
i want to close the document for 2003 office and 2007 office version.
Does this is Version issue?
Thanks and regards
Arvind Porlekar
Wait! You're opening it ReadOnly and then marking it as Saved?? That right there throws flags in my mental processor.
The documentation that I can find seems to indicate that this is an issue regarding saving to a different format. That might account for the it-works-in-one-but-not-the-other case.
Also, I've seen indications that this is a COM error. It helps to know something about COM. Likely doc and docx are completely different implementations of the same interface defined by the previous doc logic. And it might be the case that the older implementation (doc) is okay with saying that you want to open it ReadOnly, but then wanting to mark it as saved, while the new implementation has the idea that you really should not do this.
As you can see here, one of the arguments handled is OriginalFormat, and it could be that if you don't specify that argument it defaults to a doc format, which then throws the exception that you are trying to save in a different format without explicit instructions. As well another of the arguments is SaveChanges.
So it could be that you are implicitly telling it to save changes in a default doc format, which works in the the doc format, but complains about trying to save it in a different format in the docx format. (understandably)

how to stop macros running when opening a Word document using OLE Interop?

As the title suggests, I have a .Net application which uses interop to open documents in Word. I have set
app.AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityForceDisable
before opening the document. According to the documentation, thhis "Disables all macros in all files opened programmatically, without showing any security alerts"
However, when I attempt to open one specific document I get a dialog box on the screen that says "could not load an object because it is not available on this machine". It's a customer document but I believe it contains a macro with references to a COM object which I don't have installed.
Am I doing something stupid? is there any way to actually disable macros when opening a Word document?
Try:
WordBasic.DisableAutoMacros 1
Bizarrely, this relies on a throwback to pre-VBA days, but still seems to be the most-reliable way to ensure that no auto macros are triggered (in any document - you may want to turn it back using the parameter "0").
I recently had a project where I had to process 6,000 Word templates (yes, templates, not documents) many of which had oddball stuff like macros, etc. I was able to process all but 6 using this technique. (I never did figure out what the problem was with those 6).
EDIT: for a discussion of how to call this from C#, see: http://www.dotnet247.com/247reference/msgs/56/281785.aspx
For c# you can use
(_wordApp.WordBasic as dynamic).DisableAutoMacros();
The whole code I'm using is:
using Word = Microsoft.Office.Interop.Word;
private Word.Application _wordApp;
...
_wordApp = new Word.Application
{
Visible = false,
ScreenUpdating = false,
DisplayAlerts = Word.WdAlertLevel.wdAlertsNone,
FileValidation = MsoFileValidationMode.msoFileValidationSkip
};
_wordApp.Application.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;
(_wordApp.WordBasic as dynamic).DisableAutoMacros();

Joomla template parameters and params.ini - file becomes unwritable after save

I am using wamp on Win XP SP3 and creating a Joomla template with changeable parameters.
initially the message is
The parameter file \templates\ssc_2010\params.ini is
writable!
once I make changes everything works as expected, except now i get the message:
The parameter file \templates\ssc_2010\params.ini is
unwritable!
One solution is to brows to the directory, right click the file, select properties, and uncheck read-only. Again the file is writable but once I modify the parameters again it becomes read only again. I'm quite lazy and would like to prevent this from happening again, I've notice this happening in past projects, but now I have to work a lot with parameters so it becomes quite boring doing manual labor like that :P
There is a bug in Joomla 1.5 that causes the message to be displayed.
A security feature was added that makes the template files unwritable until just before save, where they are made writable, saved, then made unwritable again.
Try to make a change, then go back and check the preview. You will see that the change was actually made.
If you want to fix the annoying unwritable message, add the following code to
administrator/components/controller.php around line 179, just after setting the FTP credentials:
$file = $client->path.DS.'templates'.DS.$template.DS.'params.ini';
// Try to make the params file writeable
if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0755')) {
JError::raiseNotice('SOME_ERROR_CODE', JText::_('Could not make the template parameter file writable'));
}
This will make the file writable during the edit load process, and before the file's status is posted in the template.
Then for security, in case the edit screen is closed without saving, search for the following lines:
require_once (JPATH_COMPONENT.DS.'admin.templates.html.php');
TemplatesView::editTemplate($row, $lists, $params, $option, $client, $ftp, $template);
and paste the following code just AFTER these lines but before the closing brace:
// Try to make the params file unwriteable
if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0555')) {
JError::raiseNotice('SOME_ERROR_CODE', JText::_('Could not make the template parameter file unwritable'));
}
That will make the file unwritable again.
This is the same code that is used in the saveTemplate() function. We are just doing it again before we display the status of the file on the edit screen. If the process fails because of your web server's configuration, you will get warning messages, BEFORE you've made a bunch of changes to your template. :)
P.S. Remember to save a copy of this file separately, so that you can redo the changes when you upgrade Joomla! (if they haven't fixed this themselves yet.)
This sounds like a user rights problem within Windows - have a look a the security permissions for the directory in which the file you are editing is located, and check that the user "IUSR_xxx" (where xxx is the name of your computer) has full control.
If this doesn't work, then can you tell us what version of Windows you are running as this may help...
Matt