PDA

View Full Version : Outlook 2010 - macro "Print 1st page" - Problem with Num Lock turning off



Jarvster
02-20-2014, 03:07 AM
I posted a thread here about a macro to print the first page of an email in Outlook 2010:

Sub PrintOnePage()
SendKeys "%FPR"
SendKeys "%S"
SendKeys "1"
SendKeys "{ENTER}"
End Sub

This works fine but there is a known issue with multiple SendKey commands turning off Num Lock (I am not allowed to post the Microsoft KB link here but it is Microsoft KB 179987)

I have tried the DoEvents solution but this just effectively makes the steps manual again.

I have seen suggested solutions using the toggle and GetKeyboardState but the code I have seen appears to involve other macros and I am unable to tie it into the above.)

Does anyone have any ideas about how to workaround the NumLock issue? Thanks for your help in advance!



64 bit Optiplex 3010 - Win 8.1 - Office 2013 (with Outlook 2010)

westconn1
02-20-2014, 04:18 AM
did you try
sendkeys {NUMLOCK}
to see if it will toggle it back?

personally i avoid sendkeys, as it will not work with uac turned on, best to use some alternative

Jarvster
02-20-2014, 08:11 AM
I like that idea but the only problem (which I failed to mention) is that the issue is intermittent (about 50/60% of the time).

The benefit of being able to print out the first page of an email chain for our staff is greater than the annoyance of keep checking number lock but it would be nice to have an alternative to Sendkeys.

Jarvster
02-21-2014, 03:00 AM
Elsewhere on the web, I located a user who had the same problem (multiple send key commands turning off the NumLock but with a different macro). In response, someone posted the following code which apparently worked. Since I am not a coder - I do not know how to adapt this but it does appear to feature some code which looks like it is checking if NumLock is off or on and then taking appropriate course of action. I did try to extract and meddle with my code but it just broke my macro. Can anyone see anything that might work in this?


Private Declare Sub keybd_event Lib "user32" ( _
ByVal bVk As Byte, _
ByVal bScan As Byte, _
ByVal dwFlags As Long, _
ByVal dwExtraInfo As Long)
Private Const VK_NUMLOCK = &H90
Private Const KEYEVENTF_KEYUP = &H2
Declare Function GetKeyState Lib "user32.dll" ( _
ByVal nVirtKey As Long) As Integer

Sub test()
'NUM_Off
NUM_On
End Sub

Sub NUM_TOGGLE()
'Toggle NUM-Lock key state
keybd_event VK_NUMLOCK, 1, 0, 0
keybd_event VK_NUMLOCK, 1, KEYEVENTF_KEYUP, 0
End Sub

Sub NUM_On() 'Turn NUM-Lock on
If Not (GetKeyState(vbKeyNumlock) = 1) Then
keybd_event VK_NUMLOCK, 1, 0, 0
keybd_event VK_NUMLOCK, 1, KEYEVENTF_KEYUP, 0
End If
End Sub

Sub NUM_Off() 'Turn NUM-Lock off
If (GetKeyState(vbKeyNumlock) = 1) Then
keybd_event VK_NUMLOCK, 1, 0, 0
keybd_event VK_NUMLOCK, 1, KEYEVENTF_KEYUP, 0
End If
End Sub

westconn1
02-21-2014, 03:08 AM
just call num_off from your code after the endkeys

using keybd_event is more reliable than sendkeys anyway

Jarvster
02-21-2014, 05:15 AM
Thanks for your continued help but I am not sure I quite understand.

I tried this (but it didn't work - gave a compile error)

Sub PrintOnePage()
SendKeys "%FPR"
SendKeys "%S"
SendKeys "1"
SendKeys "{ENTER}"
NUM_On
End Sub

Then I tried adding this after my code (but it didn't work either)


Sub test()
'NUM_Off
NUM_On
End Sub

Sub NUM_TOGGLE()
'Toggle NUM-Lock key state
keybd_event VK_NUMLOCK, 1, 0, 0
keybd_event VK_NUMLOCK, 1, KEYEVENTF_KEYUP, 0
End Sub

Sub NUM_On() 'Turn NUM-Lock on
If Not (GetKeyState(vbKeyNumlock) = 1) Then
keybd_event VK_NUMLOCK, 1, 0, 0
keybd_event VK_NUMLOCK, 1, KEYEVENTF_KEYUP, 0
End If
End Sub

Sub NUM_Off() 'Turn NUM-Lock off
If (GetKeyState(vbKeyNumlock) = 1) Then
keybd_event VK_NUMLOCK, 1, 0, 0
keybd_event VK_NUMLOCK, 1, KEYEVENTF_KEYUP, 0
End If
End Sub

westconn1
02-21-2014, 01:40 PM
you should probably have added a new module and copied all the additional code to the new module
then your code should work
the first 9 lines have to be right at the top of a code pane, so if you add to your existing, put above

Jarvster
02-24-2014, 09:21 AM
Ok So now my code looks like this. I tried again but the NumLock turns off when I run the macro :(. Is this what you meant?

11331

westconn1
02-24-2014, 01:07 PM
looks fine
try like

Sub PrintOnePage()
SendKeys "%FPR"
SendKeys "%S"
SendKeys "1"
SendKeys "{ENTER}"
num_on 'add this line
End Sub

Jarvster
02-28-2014, 06:46 AM
Strangely, this produces a result where the Num Lock still turns off intermittently but if I then leave Num lock turned off, it intermittently turns back on when I use the macro! So its definitely an improvement but still not quite the silver bullet.

Thank you for your continued assistance - much appreciated.

westconn1
02-28-2014, 02:00 PM
try doevents before num_on

Jarvster
03-05-2014, 08:09 AM
Had a go but it didn't work :(

westconn1
03-06-2014, 01:47 AM
as using your sendkeys code, neither prints anything nor turns off numlock on my machine, i can not test further to know what might work

it is possible that converting the whole code to keybd_event may resolve the issue, but on the other hand it may not work at all

try like

keybd_event VK_MENU, 1, 0, 0
keybd_event 46, 1, 0, 0

keybd_event 46, 1, KEYEVENTF_KEYUP, 0
keybd_event 50, 1, 0, 0
keybd_event 50, 1, KEYEVENTF_KEYUP, 0
'keybd_event 52, 1, 0, 0
'keybd_event 52, 1, KEYEVENTF_KEYUP, 0
keybd_event VK_MENU, 1, KEYEVENTF_KEYUP, 0
keybd_event VK_MENU, 1, 0, 0
'keybd_event 53, 1, 0, 0
'keybd_event 53, 1, KEYEVENTF_KEYUP, 0
keybd_event 47, 1, 0, 0

keybd_event 47, 1, KEYEVENTF_KEYUP, 0

keybd_event VK_MENU, 1, KEYEVENTF_KEYUP, 0
keybd_event 31, 1, 0, 0
keybd_event 31, 1, KEYEVENTF_KEYUP, 0
keybd_event VK_RETURN, 1, 0, 0
keybd_event VK_RETURN, 1, KEYEVENTF_KEYUP, 0

define the extra constants
Private Const VK_RETURN = &HD
Private Const VK_MENU = &H12

Jarvster
03-13-2014, 04:08 AM
Thanks - I have tried to incorporate your code (see pic below) but it is giving me a compile error.

11394

westconn1
03-13-2014, 01:33 PM
all the code except the constants, need to be within a procedure (Sub)

Jarvster
03-14-2014, 03:52 AM
Apologies - you need to bear with me - I am truly a novice with this sort of thing. I have tried again putting this in a procedure and replacing the original code. I put the constants in a separate module. Don't know if I needed to. Still getting an error:

11396

westconn1
03-14-2014, 10:41 PM
I put the constants in a separate module.constants (or functions) in a separate module need to be declared public rather than private
you also need the module you were using before with the keybrd_event function and the other constants defined, you can add the 2 additional constants there

Jarvster
03-24-2014, 04:45 AM
Ok so now it looks like the pic. I think I have interpreted your instructions correctly about declaring "public" and I put them in the other module. Still getting an error though11439

westconn1
03-26-2014, 01:22 PM
as you will see in image in post #8
functions and constants need to be defined at the top of the code module
as i can not see the top of the module, i assume that the other constants and functions are at the top, if not they need to be, and all privates need to be made to public

Jarvster
03-27-2014, 07:58 AM
Ahhh - sorry - I missed that text. Ok - so the VB coding now looks like this.

11465

No errors this time - I tried to use it by clicking on an email and activating the macro but it appears to be activating a "clean up conversations" command.

EDIT: Ok so I presume the VK Menu command is the ALT button? So I would need - ALT, H (for the home) and then Y3 for my macro button on the ribbon. Would that work?

westconn1
03-27-2014, 01:28 PM
Would that work?ty it and see

Jarvster
04-03-2014, 03:32 AM
Not sure I know how all the 0,0,1 bits work though :(

westconn1
04-03-2014, 05:03 AM
each key has to be pushed down, then released
like


keybd_event 50, 1, 0, 0
keybd_event 50, 1, KEYEVENTF_KEYUP, 0 where 50 is i believe the P key

WallIT
07-28-2014, 04:13 AM
each key has to be pushed down, then released
like


keybd_event 50, 1, 0, 0
keybd_event 50, 1, KEYEVENTF_KEYUP, 0 where 50 is i believe the P key

Hi,

I have an identical problem. Was using SendKeys until people reported their Numlock turning off. Have been reading this thread and have tried to use Num_Off and Num_On before and after the sendkeys, but Num_On doesn't work. It seems to be ignored and the numlock ends up off when the print job has run.

Did you have any luck with mapping each key stroke to a "keybd_event"?

Jarvster
07-28-2014, 05:56 AM
I must admit that due to other work commitments - I never had the chance to sit down and try and work through this. I am moving on from my job tomorrow so I may not get the opportunity to find out!

Big thanks to Westconn1 though for all his/her help! :)

WallIT
07-28-2014, 08:30 AM
Hi,

No probs. Thanks for the reply anyway. I did some further digging around and finally worked out the combination needed. It took a while as a lot of the resources on the net refer to c++ and not VBA.

This is my code, which I put in a new module on it's own.


Private Declare Sub keybd_event Lib "user32" ( _ByVal bVk As Byte, _
ByVal bScan As Byte, _
ByVal dwFlags As Long, _
ByVal dwExtraInfo As Long)
Private Const VK_NUMLOCK = &H90
Private Const KEYEVENTF_KEYUP = &H2
Private Const VK_ALT = &H12
Private Const VK_TAB = &H9
Declare Function GetKeyState Lib "user32.dll" ( _
ByVal nVirtKey As Long) As Integer


Sub Print1()
keybd_event VK_ALT, 0, 0, 0 'Key press ALT
keybd_event 70, 1, 0, 0 'Key press F
keybd_event 70, 1, KEYEVENTF_KEYUP, 0 'Key release F
keybd_event VK_ALT, 0, KEYEVENTF_KEYUP, 0 'Key release ALT
keybd_event 80, 1, 0, 0 'Key press P
keybd_event 80, 1, KEYEVENTF_KEYUP, 0 'Key release P
keybd_event 82, 1, 0, 0 'Key press R
keybd_event 82, 1, KEYEVENTF_KEYUP, 0 'Key release R
keybd_event VK_ALT, 0, 0, 0 'Key press ALT
keybd_event 83, 1, 0, 0 'Key press S
keybd_event 83, 1, KEYEVENTF_KEYUP, 0 'Key release S
keybd_event VK_ALT, 0, KEYEVENTF_KEYUP, 0 'Key release ALT
keybd_event 49, 1, 0, 0 'Key press 1
keybd_event 49, 1, KEYEVENTF_KEYUP, 0 'Key release 1
keybd_event 13, 1, 0, 0 'Key press ENTER
keybd_event 13, 1, KEYEVENTF_KEYUP, 0 'Key release ENTER
End Sub

Here is a helpful article which shows the key mapping [scroll down a bit] http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_24088649.html

This works for me and my numlock stays on throughout!