Changing the window style of a shelled program - excel

In Excel VBA, is it possible to change the window style of a shelled program?
Here's the situation in detail:
At the click of a command button, the user should be able to load a third-party scanning program. The software path and file are specified in a named cell called settings_scanningsoftware, as you can see below. However, I'm using the Shell program, which doesn't wait for the third-party software to load before continuing. If it did, my life would be easier. For that reason, I throw up a dialog box in Excel telling the user to wait for the software to load and then ready the item to be scanned before they click Ok. And, since I throw up a dialog box, I load the scanning program minimized so they can see the dialog box (instead of it being hidden behind the software window and they're wondering why nothing's happening). With me so far?
However, once they click Ok, I want Excel to give control to the scanning software and give it a regular-sized window. There's my problem: once the software is loaded minimized, I can't seem to change the window style to give it a regular window.
Here's my code:
On Error Resume Next
Dim ScannerShell As Integer
ScannerShell = Shell(Range("settings_scanningsoftware").Value, **vbMinimizedNoFocus**)
If (ScannerShell <> 0) Then
Dim MessageBoxValue As Integer
MessageBoxValue = MsgBox("When you're ready to scan the receipt, click Ok.", vbOKCancel, "Scan receipt")
If (MessageBoxValue = vbOK) Then
ScannerShell = Shell(Range("settings_scanningsoftware").Value, **vbNormal**)
AppActivate ScannerShell, False
SendKeys ("{TAB}{TAB}{TAB} ")
End If
End If
Notice I've got the vbMinimizedNoFocus bolded above so that the software loads minimized and the user can see the upcoming dialog box. Once they click Ok, though, the software's window should be normalized. But Excel won't do me that favour.
Is there a way to change the window style after it's loaded?
Never mind the SendKeys command. I put that in there to get the scanner to automatically scan once everything is in place (the key sequence is incomplete, but one problem at a time). I know SendKeys is not a great way of sending commands to a program, but I'll figure that out once I get this window style thing fixed.
Does anyone have any solutions for me? Thanks.

Related

Allow "Mouse Click" event or "switch Excel tab" when a macro is running

I have a macro that extracts data from Microfocus RUMBA Mainframe Display and puts in Excel rows one after the other. I have created a Global Mainframe object and that is used for extraction to Excel. But when the process is running and if user decides to stop the processing he cannot click on Stop button on Excel or go to different tabs to see the data being pasted. He has to clicks like 6 times before tabs are switched or stopped.
I see that DoEvents allows mouse click events in the loop to do things but the code is written in a way that there is a lot of lines with in the loop and a function with no loop, and placing DoEvents after everyline seems irrational. I have a feeling there is a better to do that but not sure what that is. Can anyone please help?.
VBA is single threaded. So you can't have one VBA action interrupt another. If you had a cancel button, for example, and the user was allowed to click it via a DoEvents processing the cancel action would still run after the currently running procedure.
In Excel this single threaded nature ends up being a good thing because you generally don't want the user interacting with the workbook while you are making programmatic changes. If this was allowed you would get undefined behavior.
Your best course of action would be to make a .NET application that uses the Excel Interop extensions to move the data from the mainframe to Excel. If you use VB.NET then you will find the code is quite similar to VBA. In fact, the Excel.Application object model is identical so the macro code you already have ports cleanly over.
There is an add-in that will help RUMBA development here:
https://www.microfocus.com/documentation/rumba/desktop951/RumbaSystemAdminGuide/GUID-DDB7571D-6167-4F8B-876E-E7450F3030B2.html

Can't make Application.DisplayAlerts = False in Excel 2016 VBA

I have been chasing my tail for weeks, with more hours "Googling around than I want to admit.
I have a large, complex analytical app within an Excel 2016 spreadsheet that captures SQL table data, queries email data and does a lot of stuff that I think is pretty cool. Users see sales force automation performance metrics and charts. All is well except for one thing. I cannot stop the "save data?" dialog box from appearing no matter what I do.
As a workaround I've put the spreadsheet on on a network ride and given users a shortcut that runs a VBscript to copy this spreadsheet to a hidden drive on the local PC and runs it. So if they save it, there's no worries as they aren't working with the original data. But as one would easily imagine, the load time is necessarily longer than it need be and users are confused by a message when I am telling them they can't save the data.
Net of a lot of different experiments, it seems like I've uncovered a bug in Excel (yeah, I know, this sounds lame even to me) as I cannot make the Application.DisplayAlerts = False. It just will not take.
See image here:
enter image description here
The image above (or at the above link as I haven't submitted enough question yet to embed images) is obviously taken from the Immediate Window when I was running the app. I entered the steps in the exact order shown. Note that I set Application.DisplayAlerts = False and then checked the value immediately afterwords and it was True.
Very weird. Is this a bug?
One last aside that is probably irrelevant; I was using .XLSB format because of the smaller footprint, much shorter load time and to get around PC setup issues with macros. But I've switched back to .XLSX to simplify the experiment.
To clarify: the code temporarily halts after each single-step in the debugger, resulting in Excel setting it back to True while idle. Here’s a way to verify this behavior:
In the VBE code-development window, open the Immediate window (Ctrl-G).
Temporarily insert the following code somewhere in your routine:
Debug.Print "..."
Application.DisplayAlerts = False
Debug.Print "Application.DisplayAlerts: " & Application.DisplayAlerts
Stop
Using the “Set Next Statement” tool (or Ctrl-F9), set the Debug.Print "..." statement to be the next one to execute.
Run the code form there by pressing F5 (Continue).
You should see this displayed on the Immediate window:
...
Application.DisplayAlerts: False
Now, with the code stopped at the Stop statement, type “?Application.DisplayAlerts” in the Immediate window, and press the [Enter] key. You will get:
?Application.DisplayAlerts
True
because Excel has reset it to True while the code is suspended.
Remove the experimental code.

Excel - Countdown Message box until Macro is Complete

I have a Macro which takes 45 seconds to complete. When the macro starts I want a Countdown timer to pop up like a message box which will countdown until Macro completion. I have searched but so far cant find any answers to this. Is this possible?
As #Thrum correctly mentioned in his comment this is not possible with a message box.
A MsgBox is modal and therefore blocks the entire Excel application. Nothing else can happen / be done while that message box window is open and waits for you to close it. Actually, you can even make message boxes system-wide modal. In that case no other Windows application will respond unless you close that little message box in Excel (check the option vbSystemModal within the VBA help regarding MsgBox).
However, with forms on the other hand you have a choice. You can make the form not modal.
UserForm1.Show (False)
In that case the code continues to run in the background while the form is shown to the user and permits the running VBA code to make changes to the form while it is shown to the user.

Automatically closing an excel popup prompt using VBscript

I have an excel file that is supposed to access a remote monitoring server through a web query. Since the data in the file has to be periodically refreshed and saved, I have written a .vbs script to do it. It works fine, but since the server uses basic authentification security, which cannot be turned off, each time it runs, excel throws a popup "Windows Security" window asking for the username and password. There is an option to "Save credentials", but it still requires for the user to click "OK" to proceed, but the system requires there to be no user interaction.
Googling around I found this stack exchange post and other similar approaches, so I modified the script for my needs:
Set wshShell = CreateObject("WScript.Shell")
Do
ret = wshShell.AppActivate("Windows Security")
If ret = True Then
wshShell.SendKeys "{enter}"
Exit Do
End If
WScript.Sleep 500
Loop
The script does trigger when the window appears and even registers an "enter" keypress on whatever window I have focus at that time, but it cannot focus on the popup window itself. It works perfectly fine on other applications such as "Notepad" or "calculator". Is this somehow specific to popup windows? How can I modify the script to focus on the "Excel" popup? Are there other, simpler or more reliable alternatives?
Thanks
Unfortunately, AppActivate and SendKeys don't seem to always work so well on popup and dialog windows.
There is a command-line utility called nircmd that can do what you need, however. It's a great tool to have anyway and you'll probably find various other uses for it.
Download it and throw it in the same folder as your VBScript. Or, save it in your System32/SysWow64 folder or any other folder included in your %path% environmental variable. Then include the following statements in your VBScript:
With CreateObject("WScript.Shell")
.Run "nircmd dlg """" ""Windows Security"" click ok"
End With
The dlg command has the following arguments:
dlg [Process Name] [Window Title] [Action] [Parameters]
We'll leave [Process Name] blank ("""") and just supply the [Window Title]. Note that the quotes here are doubled because they're within a VBS string literal. For the final argument, you need to specify the control ID of the button you want to push/click. For typical dialog buttons (OK, Cancel, Yes, No, etc), you can try using nircmd's predefined control IDs: ok, cancel, yes, no, etc. Otherwise, you'll need to use a tool like Spy++ to determine the button's control ID and pass that instead.

Excel automation: PDF export causes "Printer setup" popup

I am developing an application for automatic Excel to PDF generation. Every now and then (and without any apparent cause, the following popup comes up while the program runs:
Print driver host for 32bit applications stopped working.
and, shortly after, this one:
Printer setup
What, if anything, do I need to do here? My application is not overly complex. The error always (100%) happens on this line:
_application.ActiveWorkbook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypePDF,
pdfTemplatePath, Excel.XlFixedFormatQuality.xlQualityStandard,
_, _, 1, pdfPrintAreaEnd);
where the variables in question are:
Excel := Microsoft.Office.Intertop.Excel
_application := Excel.Application
_ := System.Type.Missing
pdfPrintAreaEnd := int 6
The exception message is as follows:
System.Runtime.InteropServices.COMException (0x800A03EC):
Exception from HRESULT: 0x800A03EC
What is happening here? And, more importantly: Why is it only happening every one in a while?
Okay, so after some research into this matter, I encountered what I believe is one of the most confuzzling things about Excel automation I have encountered so far.
The error message is consistent with other cases of Excel usage that are both automated and not. The common denominator in all these cases is (buckle up!) that a network printer was set as default printer.
That's right - having a network printer as default, even when you print using a completely different printer or no printer at all (as in the case of exporting to PDF, which is not the same as printing to e.g. Adobe PDF Printer, right?) it will cause this error to sometimes on some machines pop up.
I changed the default printer to something internal, like Microsoft XPS Document Printer, tried again and I can now export hundreds and thousands of PDFs without a single occurrence of the error message.
I had a similar issue on my work laptop. The printer setup would pop-up when trying to execute ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:="\directory\MyFile".
The network printer was set as default. So I navigated to the printer in windows explorer. This prompted me to enter my network password. When I re-ran the code it worked splendidly.(You can find the location of the printer in Windows 10 by typing 'printer' in the windows search bar. Click on Printers And Scanners, navigate to your network printer and then click on manage -> Select Hardware Properties. The location will be displayed next to the image of the printer. In my case the printers location was specified in its name).
In summary, ensure you have access to the default printer. A simple test is trying to print something with your default printer.
If you don't mind changing your default printer follow #F.P solution above.
Someties it,s needed to close your workbook and reopen it.
In my case, when I opened an excel file, it prompted me to click the "Enable Editing" button in the picture below:
When I clicked on it, the excel file wants to open again and Excel splash screen shown again and I closed it immediately. And then I was not to able to save as a PDF both with "Print" button and "VB" code.

Resources