How to copy-paste from DOS application to Excel using SendKeys? - excel

I'm trying to simulate this action:
activate another application,
send keystroke ctrl+c,
go back to Excel,
send key stroke ctrl+v
and have that value in a cell.
It's a DOS window style application, so keystroke is the only way to manage it.
I managed to activate and to input keystrokes such as ENTER into that DOS style application, but when I try ctrl+C it is not seen to do anything.
I tried simulating it in Excel VBA with:
Range("E7").Select
SendKeys "^c"
Range("G7").Select
SendKeys "^v"
The E7 value is not copied, but G7 (paste destination) is highlighted as if it was selected for copying.
Note: I am not trying to copy things from Excel to Excel, but to execute keystrokes using Excel.

I ran into the same issue today.
I solved it by waiting a bit after sending CTRL-C to the application. It seems nothing is copied if you immediately execute another script line.
SendKeys "^c"
WScript.Sleep 100 ' wait a bit after CTRL+C (otherwise nothing is copied)
In fact, the same issue seems to happen when switching to another app and sending CTRL+V.
Again, I solved it by waiting a bit:
AppActivate "Microsoft Excel"
WScript.Sleep 100 ' wait a bit after making window active
SendKeys "^v"

The problem is that copying and pasting takes some time and VBA is not waiting for it.
First you need to specify second argument of send keys method which is "Wait". Set it to true. Thus VBA execution is waiting for until sending keys is completed.
Secondly you need to wait until process of copying data to clipboard is completed. "Wait" in sendkeys is not doing it because it's not about sendking keys by VBA but it's about Windows working with clipboard. To do it please use my function IsCopyingCompleted.
Here's how final can look like:
SendKeys "^a", True 'Select all
SendKeys "^c", True 'Copy
Do
DoEvents
Loop Until Me.IsCopyingCompleted()
YourSheet.Paste
Function IsCopyingCompleted() As Boolean
'Check if copying data to clipboard is completed
Dim tempString As String
Dim myData As DataObject
'Try to put data from clipboard to string to check if operations on clipboard are completed
On Error Resume Next
Set myData = New DataObject
myData.GetFromClipboard
tempString = myData.GetText(1)
If Err.Number = 0 Then
IsCopyingCompleted = True
Else
IsCopyingCompleted = False
End If
On Error GoTo 0
End Function

I had this same problem - I developed code and it worked on my computer - SendKeys "^v"...but it did not work on another user's computer! I was trying EVERYTHING...delays, appreciate, accessig access from Excel, having the user check various settings, selection.paste...no good. Finally I noticed different syntaxes...we were using the same office version, I'm not sure about Windows. But I entered 6 different syntaxes and had it skip over if it failed....SendKeys with a capital v, enclosed in squigley brackets, each component in squigleys separated by a plus sign, etc. IT WORKED! 2 of the commands put the ^V in the body of outlook...I remove those 2 and I'm golden.

Related

Excel VBA - Copy and Paste each cell Individually to another program

I'm fairly new to VBA but know my way around it a bit (sorta). What I'm needing to do is get a Macro set to copy data in one cell, switch to another program (2315), enter "6", [ENTER], paste the data, [ENTER] switch back to Excel, select the next row, copy, switch, paste, switch, until it reaches the end of the column. This is what I have, which works for the first cell. I just need to figure out how to loop it until it reaches the end. Thanks for any help/suggestions!
Range("A2").Select
Selection.Copy
AppActivate "2315"
Application.SendKeys "6~^V~"
Application.SendKeys "%{TAB}"
Thanks Again!
I doubt that this works, but you say it does and your question is about the loop. Here is the loop.
Dim R As Long
For R = 2 To Cells(Rows.Count, "A").End(xlUp).Row
Cells(R, "A").Copy
AppActivate "2315"
Application.SendKeys "6~^V~"
Application.SendKeys "%{TAB}"
Next R
For Excel's sake you don't need to select anything. The above code will loop through all the used cells in column A of the active tab. If your app "2315" needs the selection, add Cells(R, "A").Select before the copy instruction.
My doubt is based in the fact that you can't use VBA to send parameters to app "2315". This includes the instruction to "2315" to surrender control back to Excel and its VBA. Perhaps you have found such a way via the SendKeys. If so, the code will work. If not, it will get stuck after the first loop.
Logically, the code should run until AppActivate "2315", meaning the SendKeys are never sent until the other app has returned control. If that is what's going on there must be better ways to express whatever your two instructions get done. But that shouldn't be your immediate concern. If you can get "2315" to surrender control back to Excel with a simple command like Enter, and if the above macro really resumes work where it left off, most of your problem should be solved. This I hope for :-)

Excel VBA - SendKeys "{F2}" - keeps toggling num-lock

After using setting a cell to select and then using SendKeys "{F2}" (So that the cell is ready for input) it likes to toggle num-lock every time this is ran.
I have seen people say to use SendKeys "{NUMLOCK}", True after the SendKeys "{F2}" but tat did nto help. even tried adding Application.Wait Now + TimeValue("00:00:01") between the two comands, but it still keeps toggling.
I have also read its a bug with Excel/VBA.
Is there a better solutions? I need to select the cell and then force it into edit mode in order for some validation checks to work properly, else it bypasses the check if it just selects the cell, the could continue on, forcing it into edit make it so they have to make a change if not and they leave the cell the validation kicks in again.
I also found this code and tried, but that doe not work, it just keeps toggling
Dim wshshell As Object
Set wshshell = CreateObject("WScript.Shell")
wshshell.SendKeys "{NUMLOCK}"
Set wshshell = Nothing
Even tried this and replaced with F2 but it still toggled numlock.
I need numlock to stay on at all times. is there another way to invoke the edit cell instead of F2?

VBA .SetText and .PutInClipboard putting two symbols in clipboard instead of desired data

Using Excel 2016 and a reference to the Microsoft Forms 2.0 Object Library, I'm trying to copy the ActiveCell's contents to my clipboard. Instead, the resulting contents of my clipboard are the following 2 symbols (if they'll actually show up in this text field.
��
��
(In case those symbols aren't rendering, in the StackOverflow website's text editor they look like white rectanges. Depending on the text editor I'm pasting it in, they've also resembled a question mark, a black diamond containing a white question mark, and just a blank space as if the space bar was pressed.)
I'm not trying to copy symbols of any kind, it's plain English. I've used code similar to this in other macros and it's always worked until today. The code itself is below. I hope you can help!
Dim clipboard As New MSForms.DataObject
clipboard.SetText ActiveCell.Value
clipboard.PutInClipboard
Debug.Print clipboard.GetText(1)
Set clipboard = Nothing
The Debug.Print command prints out the desired text, but after the macro finishes, the desired text is not there and instead there are the 2 symbols again.
In Windows 10, if file explorer is open the putinclipboard does not work. Go figure.
https://www.mrexcel.com/board/threads/copy-cell-address-to-clipboard-issue-putinclipboard-not-working.983442/
One way that worked for me is;
-Close Excel and File Explorer.
-Reopen Excel test the functionality of PutInClipboard /paste
-Open Window 10 File Explorer
-Test again.
*I work for me why? I don't know but it seems that excel has to be open prior to File Explorer.
The effect seems version dependent, whether the explorer window is opened before or after Excel. It also depends on what is in the explorer window - if it is a 'system location' such as "This PC", then putinclipboard still works normally.
I had tried various options for ages, but eventually found one workaround - acting as if copying manually...
In this case, the text to be copied to the clipboard is in the active cell, but the approach can be adapted for other circumstances:
Sub AACopyText() 'has to be called from Excel workbook (ie not from the VB window!)
SendKeys "{F2}^a^c{ESC}"
End Sub
F2 activates the contents of the cell, ^a selects the entire contents, ^c copies the contents to the clipboard; {ESC} is then required or the cell contents remain active.
if the required text is not the activecell content, for example is in a variable eg MyTextToCopy then the activecell can be temporarily over-written:
AppActivate ActiveWorkbook.Name
SendKeys "{F2}^a" & MyTextToCopy & "^a^c{ESC}"
These lines activate the activecell in the active workbook (so can be used in a procedure called from a form, etc), selects the contents, overwrites the contents, copies the new contents, then returns the original contents.
Alternatively, use can be made of Notepad; the following routine will work in programs other than Excel:
Function clip(ClipText As String)
On Error Resume Next
Dim WasntOpen As Boolean
AppActivate ("Notepad")
If Err Then
WasntOpen = True
Err.Clear
x = Shell("Notepad.exe", vbNormalFocus)
AppActivate ("Notepad")
End If
SendKeys "^a" & ClipText & "^a^c^z"
If WasntOpen Then SendKeys "%Fx"
End Function
where 'ClipText' is the text you want to save
eg In your routine, the line
Clip("1234")
will put "1234" on the clipboard

Turning off the warning message about large amount of data on the clipboard

I am copying rows (sometimes as little as 8 X 17) of data from multiple Excel files into one worksheet in another Excel file using these commands:
wksInput.Range(strInputRange).Copy
wksOutput.Range(strOutPutRange).PasteSpecial xlPasteValues
I receive a warning message stating "There is a large amount of information on the Clipboard. Do you want to be able to paste this information into another program later?".
Application.DisplayAlerts = False, does not work.
Is there a way to turn off this warning message?
This is not an excel specific issue as I've seen the Clipboard warning whenever you copy large data from other applications as well.
However, when using excel, you might have a few ways to work around it using VBA.
There are several methods for preventing the display of this warning message. The quickest manual method is to press the ESC key just before you close the workbook.
In an automated scenario that uses a Visual Basic for Applications macro to cut or copy cells, you may not consider it an acceptable option to press the ESC key to prevent the warning. In that case, use any of the following programmatic methods to prevent the warning.
Method 1: Copy A Single Cell
If you are using Visual Basic for Applications macro to cut or copy cells, insert the following line immediately before the line that closes the workbook:
ActiveSheet.Range("A1").Copy
The warning message is not displayed if the Clipboard contains 100 or fewer cells.
Method 2: Exit from CutCopyMode
If you are using Visual Basic for Applications macro to cut or copy cells, insert the following line immediately before the line that closes the workbook
workbook.Application.CutCopyMode = False
where "workbook" is your workbook object.
NOTE: By setting CutCopyMode to True or False, Excel may cancel Cut or Copy mode.
Method 3: Save the Workbook
If you are using Visual Basic for Applications macro to cut or copy cells, insert the following line immediately before the line that closes the workbook
workbook.Save
where "workbook" is your workbook object. When you save a workbook, Excel is no longer in Cut or Copy mode.
Original article can be found on this Microsoft support page
Did you already try something like this:
wksOutput.Range(strOutPutRange).Value = wksInput.Range(strInputRange).Value
(Maybe you might need to loop over all cells in the ranges)
Like this, you don't need the clipboard, so you won't be bothered by the message.
This appears as soon as you close the workbook. So use
Application.CutCopyMode = False after you close the workbook.
The code should look something like this:
wbk.close False 'code for closing the workbook in vba
Application.CutCopyMode = False 'Code for removing the cutcopymode and the warning

VBA - Closing or clicking OK in MsgBox from another workbook,

Hi I the following code in Excel VBA,
Sub A ()
Workbooks.open ("A.xls")
ActiveWorkbook.Worksheets("1").Select
ActiveSheet.CommandButton1.value = true
End Sub
I'm opening another workbook (the code inside is protected so I can't modify the workbook "B") and clicking a run button on the worksheet, and it returns a MsgBox with OK button.
I want to know how I can use VBA to close this MsgBox or clicking "OK" ...I tried to use,
`application.DisplayAlert = false`
before opening the workbook "B" but this does not work..
Thanks for your help!
There might be an approach using SendKeys -- but SendKeys is notoriously temperamental. Here is a more reliable approach:
1) If you don't already have it organized like this, have the click-event handler of the button a 1-line sub that looks like:
Private Sub CommandButton1_Click()
Process
End Sub
Where Process is the sub which actually does the heavy lifting. In general, I think it a good idea to have event handlers mostly functioning as dispatchers to subs.
2) Change the code for Process (or whatever you choose to name it) in the following way:
a) Modify the first line to look like
Sub Process(Optional Verbose As Boolean = True)
b) Where Process has something like
MsgBox "Processed!"
replace it by
If Verbose Then MsgBox "Processed!"
3) In the code you gave above, replace the line
ActiveSheet.CommandButton1.value = true
by the line
Application.Run "A.xls!Process", False
This approach will bypass the button entirely and run the code which the button normally triggers, but run it in silent mode.
On Edit: To use SendKeys you could do the following. Put the line
Application.SendKeys "~"
before the line
ActiveSheet.CommandButton1.value = True
~ is the character shortcut for Enter. SendKeys doesn't itself send the keystroke, instead it puts something on the Windows Message Queue. VBA doesn't have any direct control about exactly when this message will be processed. In this case the lack of control is a benefit. The VBA interpreter moves onto the next line, which triggers the MsgBox. By the time the SendKeys message is processed the default Okay button on the message box has the focus hence receives the enter key. This can even happen before the box is painted, making it seem that the MsgBox was never there -- but that is better to think of it as being destroyed before you have time to see it.
The reason why it is necessary to have the SendKeys line before the line which clicks the button is that once the message box appears it will cause the VBA interpreter to wait until it is closed -- hence the calling code will suspend its execution until after the message box is closed, hence the SendKeys wouldn't be processed until it is no longer needed.
I don't really trust SendKeys. I suspect that sometimes when you run the code what will happen is that A1 in the newly activated sheet will receive the enter key (shifting the selection from A1 to A2) before the message box appears. I'm not sure if this can happen, but if it does a workaround might be to move the SendKeys to a VBScript program. Launch this program (with window minimized and not waiting for return) before the button is clicked. The VBScript program can have say an 0.5 second pause before it uses SendKeys. The script will be running in a different thread so it won't be blocked by the message box.

Resources