Two parallel tasks in VBA, Is it possible? - excel

I have a requirement, where I search an excel. Since I am looping through all the rows and columns ( many rows and columns), its taking time. I want to display a message box while the search operation is going on.
Is it possible to do in VBA?
Thanks,
Yogesh

doevents interrupts the current thread and allows the user environment to be updated.

One of the eternal issues with VBA is its limitation of threads. VBA was conceived as a single-threaded model. Ever since, it remained so. Building a macro with multithread in native VBA is impossible.
Few workarounds are to build DLLs with COM interface and summon them in VBA or create worker scripts in VBS and use them from VBA.
This limitation of single thread widely annoys developers when it comes to display progress bar in excel. There is no API to communicate with the inbuilt progress bar of the Excel.
If you are looking to visually notify the user about some work that is under progress and they need to wait, all you are left with is either statusbar text or wait cursor. Another approach and bit intricate, because of their modal and non-modal styles, is to use UserForms. One more method, but very clumsy, unstable and non-native, is to use Internet Explorer object and update its HTML.
vba code :http://ashuvba.blogspot.in/2014/10/ajax-style-progress-display-in-vba.html

VBA is single-threaded, so the boring answer is "nope, can't be done".
Also, displaying a messagebox would block your only thread, so using one should be out of the question.
You have several alternatives.
Report progress in the host application's status bar. This can make your long-running task run even longer though, because now on top of the actual work, you need to refresh a UI element - DoEvents can help a bit here.
Report progress in a custom userform. This can be tricky, because you probably don't want that form to actually own the code/logic that performs whatever it is that your long-running task does; you'll need to encapsulate that logic in a class/object, and let the form call into that object - the object exposes some Public Event UpdateProgress, and then the form needs to declare some Private WithEvents myLogic As MyObject to handle that event.
Wrap a .NET BackgroundWorker into a COM-visible library, and let .NET create the background thread for you.

This is how I mimic progressbar when the code runs long:
add separate hidden sheet like that:
(white background, range B2:G2 merged and formatted as %, all other rows/columns hidden)
apply conditional formatting to B2: Data bars - Lowest value: 0, Highest value 1, choose progressbar background color
when the code starts running, unhide and activate it, on progress change B2 value (0->0%, 1->100%), and call DoEvents to invalidate
hide this sheet and activate the main sheet on completion

Related

Who is calling VisualStateManager.GoToState behind the scenes?

I am a newbie to xaml and windows app dev so sorry if this question might seem silly.
I created a textbox and in the designer I right clicked it and selected edit template=>edit a copy and put it into my custom dictionary.
In the control template for this textbox I saw visual states like disabled,focused and so on. And I modified them and run the mobile app and observed that my changes work like changing border color when textbox is focused.
But in order for this to work somebody has to call
VisualStateManager.GoToState("Focused")
when the textbox is focused so who is calling this because I don't see any visual transitions in the control template so how is this happening?
The code in the control itself is calling VisualStateManager.GoToState(...) .
When you start implementing your own custom controls, you might subscribe to events you have available and transition states based on your own logic. Here is an example of a custom control with its own two custom states.
https://github.com/xyzzer/WinRTXamlToolkit/blob/master/WinRTXamlToolkit/Controls/WatermarkTextBox/WatermarkTextBox.cs
XAML is a compiled language, and if you've looked extra close, what happens under the hood, is that the class behind your xaml has the same namespace as your xaml code.
This means (for no practical purpose) that compiling your program turns all of that XAML into C# code before then going over to MSIL and eventually execute as a binary program.
Much of the state changes that happen are event based, and TextBox, like all other user controls, will transmit a message and listen to messages. The Page that contains the TextBox will probably be the one that transmits a state change whenever one of it's children gets focus, and as a good control, the TextBox listens for this event and reacts to it.

Visual C Multi-Threading (Please Help)?

I have written a .NET program, using Windows form Application.
My application is fairly simple.
Basically, I have two simple buttons on my form.
When the form is first loaded, I set up a global variable (bool run = true).
And my first button is essentially a very simple while loop.
while(run)
{
// do some code
}
And what I want to do, is have the second button set the value of the boolean to false (bool run = false).
But, once I clicked the first button, I cannot even touch the second button!
I have read quite about this, and I think my solution is to use a multi-threading.
I have found some example codes on line for multi-threading, and I tried to incorporate those, but I don't know why I cannot get it to work. Once I click button #1, there is no way for me to be able to click button #2.
Your UI thread should not have any infinite or a wait-on-something - never! You must not block the UI for anything (other than simple calculations, validations, user confirmation etc). You should make a thread for performing length task, and let that thread communicate to UI thread using asynchronous (or synchronous, if you prefer) communication.
On native Windows GUI application, you can use PostMessage (async), or SendMessage (sync). For .NET GUI applications, you can use Control.BeginInvoke (async), or Control.Invoke (sync).
Please read this article on how this is done.

Read textBox.Text in BackGroundWorker

I am using background worker to do a long process on some files. I take the address of a directory from textBox1 and the address of a file that is used for the processing function from textBox2. I also have a ComboBox. Based on the selected value of the ComboBox the program chooses a different function through a simple switch case.
Now the problem is that I can not access the values of these textBoxes and the ComboBox in the BackGroundWorker_DoWork. I of course get the exception of accessing a control from a thread it wasn't created on. I have searched a lot about delegates and all that. The examples I have seen so far are all about assigning a text to the textBox inside the program. While what I want to do is to read the text that the user has inserted into the textBox. Since I'm not quite familiar with the concept of delegates, I want to know how I can read and use the Texts of textBoxes and the ComboBox and process them in the BackGroundWorker?
Sorry I cannot post the code here due to security policies.
/MoNoo
You don't say if this is WinForms, WPF or Silverlight, but in WPF you would do this using the Dispatcher property of the combobox, something like this:
string theText;
myComboBox.Dispatcher.Invoke( DispatcherPriority.Normal,
new Action( delegate()
{
theText = myComboBox.Text;
}
));
That will marshal the call onto the main thread and back again.

Pre-loading browser clipboard for testing pasting into fields with watir-webdriver

Our web application has some event code to "format" any text with pasted into a field so that any HTML styles do not break our data.
What would be a good way to pre-load the browser clipboard so that I can test pasting into the input field?
Is there any way to do it programmatic-ally or would I have the test script visit "a source page" and copy text before moving onto our application?
Any ideas or code snippets would be welcome.
Working with the clipboard will depend on your platform. E.g. on OS X, you can use pbcopy and Command-V:
open('|pbcopy', 'w') { |io| io << 'some text' }
browser.text_field(:name => 'q').send_keys([:command, 'v'])
I know there are equivalents on Linux (xclip?). Not sure about Windows.
I would consider using the .value= method to set the value. If it's been implemented the same as in watir, then it causes no events to be fired and sets the value directly, and then follow that up by sending an appropriate event (depending on what if any events are being monitored) such as onKeypress. I tried to figure out from the Watir-webdriver rdoc for textfield, if this distinction between .set and .value= has been maintained, but the way the doc describes them (at least there) makes them seem interchangable.. (Jarib can you clarify???)
Potentially you might need to first fire something like onFocus depending on the controls you are using. For example, as described in this SO case Setting a text field that has a JQuery mask on it for a jquery mask, they had to end up firing an unmask event to be able to even set the field.
This is a good case for utilizing the techniques described here How to find out which JavaScript events fired? and in the SO item linked in the comments for that question, to figure out just what events are fired when you manually paste something into a field. (note I would slueth it with both using the mouse, but also using something like tab to move between fields and set the focus, events common to those two methods are the ones most likely to be implemented by the controls.
I presume you have some kind of client side javascript that needs to check what was pasted into the field, and thus the reason for this test. If you are using standard HTML fields, with no javascript stuff, then I would consider this particular test case to be effectively the same as 'testing the browser' since supporting cut and paste in input fields is a standard browser function. In that case, you are sort of 'off the reservation' and I'd not bother with such a test case.

Cocoa Stop Button

I load a file from the disk, chunk by chunk, and I would like to grant the user the opportunity to click on a button and stop loading. I already know how to do that with threads (e.g. detachDrawingThread) but here I wouldn't use that way. The loading method in facts should return a bool value, it's called from different points and it's usually followed by many other lines of code. So I can't launch the thread and leave it work in a separated thread. And I can't split my code so easily. It's really complicated.
I just need to detect if the user clicked on a given button. That's all.
Is a quick and simple way to do that without rewriting my whole app?
Your loading routine must be using some sort of loop. Create a boolean and in your loop test for the condition of the boolean. Then in your button selector, set the selector to change the status of the boolean. Once your loop goes around again, it will exit and stop loading data.
First rule of good Mac apps:
Don't block the main thread
Some options:
Do the work on a background thread. Sounds like you don't want to/can't in this case
Use something like NSURLConnection to process the data in small chunks on the main thread as it's read in, rather than running a continuous loop
Run the event loop periodically while loading data so UI events can be processed
Thanks, I usually use threads, but in this case in order to use a thread I should almost re-write my app... So I have found a quick solution. Within the loop I added:
while(event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]){
[NSApp sendEvent:event];
}
So when the user clicks on the button to stop the loop, I post a notification and exit the loop. It works well.

Resources