Attempting to automate text-entry into a number of text fields in an uncontrolled (manually-opened) webpage in Chrome or Edge - excel

I'm attempting to automate a repetitive data-entry task on a webpage. I need to enter text into a series of text fields that appear in a sidebar, which means that I have to
click on the visible text field
send text data from Excel to that text field
click on a button so that the next text field is displayed
repeat 1-3
The problem is that in this particular case I have to log in to the webpage manually, so Excel doesn't have control of the browser, which means that I can't use most of the Selenium commands.
I managed to enter some of the data into different region of the webpage using the AppActivate statement and a series of SendKeys commands:
AppActivate ("Title")
Dim cellValue As Variant
cellValue = Range("B2").Value
SendKeys cellValue, True
SendKeys "{DOWN}"
cellValue = Range("B3").Value
SendKeys cellValue, True
SendKeys "{DOWN}"
I tried to rig up something like this for the text fields mentioned above, but SendKeys won't TAB over to the sidebar (despite the fact that I can TAB over manually).
I don't care at all if the solution is odd or inelegant, as long as it works! I'm new at this, so I may be making obvious mistakes and/or overlooking an obvious solution.

Related

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

Change Axis Label font size in a funnel chart (Excel 2016)

I want to change font size on axis xlCategory. I am running the code like below but it is failing. I am stuck in finding workarounds. Chart is "Funnel" type 123. On the other types of chart code is running fine.
With ActiveChart.Axes(xlCategory).TickLabels.font
.size = 12
.Name = "Arial"
End With
I get the error:
"object doesn't support this action"
I was also trying to run the othe code but also without any success.
ActiveChart.Axes(xlCategory).Select
With Selection.Format.TextFrame2.TextRange.font
.size = 12
End With
I get the error:
"method textframe2 of object chartformat failed"
This is a very peculiar bug!
I guess it has to do with the fact that the XlCategory axis becomes vertical when you are using the "Funnel" chart type:
I've tried all the standard VBA ways I could think of and this doesn't seem to work. I even tried to see if we could save a funnel chart as a template and then use VBA to apply this template, but "Save as Template" is not available for some reason...
So, the reason why I'm explaining all this instead of writing a solution is because there is a workaround, but this kind of thing should only be used as a last resort. And if you haven't guessed it, I'm talking about using the SendKeys method.
Disclaimer: As always, using SendKeys is somewhat tricky and can lead to unexpected results. I would recommend reading some articles to get yourself familiar with it before using it. This article would be a good starting point.
Furthermore, to avoid any issues, don't run a macro that has the SendKeys method using the Run button in the VBE since the keystroke must be sent to the Excel window and not the VBE window. I suggest launching the macro using a shortcut to launch your macro. For example, you could use the Application.OnKey method by runnning a macro similar to this:
Sub SetShortcut()
'Set the shortcut for the macro to be CTRL+ALT+m
Application.OnKey "^%m", "NameOfYourMacro"
End Sub
An example using Sendkeys
The idea is to use Sendkeys to send the sequence of keystrokes that would give us the result we want. Here, we want to change the size and the font name of the XlCategory axis. By using the correct Alt key shortcut sequence we can achieve this. I'm not sure if the sequence is the same for all versions of Excel, but with Office 365, if we wanted to change the font name, it would be:
Type Alt - to initiate the Alt Key shortcut sequence.
Type "H" - to get the Home tab
Type "FF" - to select the Font Name text box
Type "Arial" and then press Enter - to change the font to Arial.
For this to apply to the XlCategory axis, we need to make sure that it is already selected before we run the macro. If it is selected, the following code should do the trick:
Sub ChangeCategoryAxisFont()
'Font Name
Application.SendKeys Keys:="%", Wait:=True
Application.SendKeys Keys:="H", Wait:=True
Application.SendKeys Keys:="FF", Wait:=True
Application.SendKeys Keys:="Arial", Wait:=True
Application.SendKeys Keys:="~", Wait:=True 'Press Enter
'Size
Application.SendKeys Keys:="%", Wait:=True
Application.SendKeys Keys:="H", Wait:=True
Application.SendKeys Keys:="FS", Wait:=True
Application.SendKeys Keys:="12", Wait:=True
Application.SendKeys Keys:="~", Wait:=True 'Press Enter
'Restore Numlock (which gets disabled when your macro runs at least one SendKeys command)
Application.SendKeys Keys:="{NUMLOCK}", Wait:=True
End Sub
If it is not already selected (even if the chart is selected), you might have another problem: if you include ActiveChart.Axes(xlCategory).Select in your macro, the options available in the ribbon won't be updated correctly and the macro above won't work. To let the ribbon update, we would need to end the execution of any macros for a brief second and proceed with our macro after.
For instance, you could use the Application.OnTime method to schedule the macro to run one second later, like this:
Sub PreSelectAxisAndRunMainMacro()
ActiveChart.Axes(xlCategory).Select
Application.OnTime Now + TimeSerial(0, 0, 1), "ChangeCategoryAxisFont"
End Sub
I know what you might think: "All this just to make some font changes?!". Yeah, I know, but at least if you become familiar with how to use the SendKeys method, you'll be able to use this in other contexts that require it...

How can I scrape worded information from a website?

I am new to VBA and html coding in general. I apologise if I don't understand basic terms or use them incorrectly. I was looking to create and run a macro in excel for work that would make my job a lot easier. Essentially, I need to grab a bunch of information off of a real estate website. This includes address, list price, listing agency, auction date (if any) etc. I have spent the last 4 hours reading all about web scraping and I understand the processes, I just don't know how to code it. From what I have read, I need to write a code to automatically open the website, force-ably wait until it's loaded, then retrieve information by either tag, name or id. Is this correct? How can I go about this. What resources should I look to use.
TL;DR How to web scrape text from a webpage of search results (noob instructions).
I will not tell you all the details, you have to find them on your own. Some web pages are complicated, some are easy. Other are impossible, especially if the text is displayed not in HTML but in some other form - picture, Flash etc.
It is however quite simple to extract data from HTML web pages in Excel. First of all, you want to automate it. So click 'Record macro' on the 'Developer' ribbon. This way, you will have all the reproducible step recorded and then you can have a look at the macro a adjust some steps to suit your needs. I however can't teach you here how to program VBA.
When your macro is being recorded, click on 'From web' on the 'Data' ribbon. This will show up a new web query. Then you enter the address of the web page you want to read and try to select (with the little arrow or check-off mark) as narrow area you are interested in as possible. You can also explore some of the fine-tuning options in this wizard dialog.
When you are done, click 'Import' and you will have in some form the contents of the web page. If you are lucky, the data you are interested in will be always in the same cells. Then you can read the cells and store the values somewhere (possible using another macro). If the data are not in the same cells every time you refresh the query, then you have bad luck and have to use some complicated formulas or macros to find them.
Next stop the macro which you are recording and review the code which was recorded. Try to experiment and play around with it until you discover what you actually need. Then it is up to you, how you want to automate it. The options are many...
Otherwise Excel is maybe not the best tool. If I wanted to load HTML page and extract data from it, I would use some scripting e.g. Python which has much better tools than Excel and VBA. There are also tools for converting HTML to XHTML and then extracting data from it like from well-formed XML.
Below is a very basic example illustrating some of the concepts of web scraping. Other reading you should do, would be how to use the other element selectors such as getElementByID getElementByClassName getElementByName.
Here's some code to get you started.
Public Sub ExampleWebScraper()
Dim Browser As Object: Set Browser = CreateObject("InternetExplorer.Application")
Dim Elements As Object 'Will hold all the elements in a collection
Dim Element As Object 'Our iterator that will show us the properties
'Open a page and wait for it to load
With Browser
.Visible = True
.Navigate "www.google.com"
'Wait for the page to load
While .busy Or .readystate <> 4
Application.Wait (Now() + TimeValue("00:00:01"))
Wend
'Enumerate all Elements on the page
'It will store these elements into a collection which we can
'iterate over. The * is the key for ALL, here you can specify
'any tagName and it will limit your search to just those.
'E.g. the most common is Likely Input
Set Elements = .document.getElementsByTagname("*") ' All elements
'Iterate through all elements, and print out some properties
For Each Element In Elements
On Error Resume Next ' This is needed as not all elements have the properties below
' if you try and return a property that doesn't exist for that element
' you will receive an error
'The following information will be output to the 'Immediate Window'
'If you don't see this window, Press Ctrl+G, and it will pop up. That's where this info will display
Debug.Print "The Inner Text is: " & Element.InnerText
Debug.Print "The Value is: " & Element.Value
Debug.Print "The Name is: " & Element.Name
Debug.Print "The ID is: " & Element.ID
Debug.Print "The ClassName is: " & Element.Class
Next Element
End With
'Clean up, free memory
Set Browser = Nothing
Set Elements = Nothing
Set Element = Nothing
End Sub

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

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.

Resources