Excel VBA automated Data from web .aspx - vba

I am trying to automate the process of data collection from the following website.
I failed already at the first task, which is clicking the buttons and submitting a postal code.
The first part of the code should click the left button Pflegeeinrichtungen und Betreuungsangebote, which expands the selection by 4 buttons.
Afterwards the second button stationäre Pflegeeinrichtung should be clicked to expand the selection even further.
The last selection should be Vollstationäre Pflege.
To change the state of the searchButton to clickable a postal code must be entered in the searchBar, which presents proposals based on the entered postal code. One of those proposals must be selected to change the state of the searchButton, just entering the postal code is not enough.
So far I managed to click the second (2.) and third (3.) button and enter a postal code in the searchBar. Excel opens the IE window and clicks the buttons, but since the first (1.) button was not clicked beforehand it does not even show the 2. and 3. button. If i click the first button manually after executing the VBA code I can see that the 2. and 3. button are selected.
My Questions are:
How do I click the first button via VBA?
How do I submit the search for the entered postal code?
How do I choose one of the proposals ? (It does not even matter which one.)
I managed to click the buttons via:
.getElementById("ctl00_ContentPlaceHolder1_suche_btn_versorgung2").Click
and
"ctl00_ContentPlaceHolder1_suche_btn_pflegeart1" for "vollstationäre Pflege"
Thank you very much in advance

In the end I gave in and used selenium basic VBA wrapper and here is how you do what you are after with VBA. You can use other supported browsers apart from Chrome.
Code:
Option Explicit
Public Sub test()
Dim d As WebDriver
Set d = New ChromeDriver
Const DATA_OPTION As Long = 1 '<== 1 bist Pflege­einrichtungen und Betreuungs­angebote , oder für Pflegeberatung verwenden 2: .....("button[data-tab=""2""]")
Const LOCATION As String = "10777 Berlin/Schöneberg" '<== Wo möchten Sie suchen?
Const CARE_SETTING As Long = 1 '<== 1 für Ambulanter Pflegedienst. Oder: 2.Stationäre Pflegeeinrichtung ; 3.Angebote zur Unterstützung im Alltag ; 4. Häuslicher Betreuungsdienst
With d
.Start "Chrome"
.Get "https://www.pflegelotse.de/(S(x2hdp4ld1i0ok4y0q2upqasz))/presentation/pl_startseite.aspx"
.FindElementByCss("button[data-tab=""" & DATA_OPTION & """]").Click
Application.Wait Now + TimeSerial(0, 0, 1)
.FindElementByCss("button[data-value=""" & CARE_SETTING & """]").Click
.FindElementById("ctl00_ContentPlaceHolder1_suche_bezirk").SendKeys LOCATION
Application.Wait Now + TimeSerial(0, 0, 1)
Dim keys As New keys
.SendKeys keys.Enter
Application.Wait Now + TimeSerial(0, 0, 1)
.FindElementById("ctl00_ContentPlaceHolder1_suche_btn_suche").Click
Stop
.Quit
End With
End Sub
In action:

Related

Sub to add controls works when called from one sub but the other

I am getting an error that I just can't figure out. I wrote a sub that opens a form in Design view, deletes all of the dynamic controls, then adds the requested number.
The sub gets called in two different ways. The user opening the form (via a Main Menu form) to fill out a new form (so the dynamic controls are deleted then recreated) OR after the form is created, the user can click a button on the form to add more rows of controls. Both the Main Menu and button form call the same sub, BUT when the button is clicked the code gets stuck and error 29054 'Microsoft Access can't add, rename, or delete the control(s) you requested.' is thrown. The button to debug is deactivated so I can't see what line is actually getting stuck, but when I step through the code this is the last line before the error pops up (the last indent block in the context below):
With Application.CreateControl("BOM5", acComboBox, acDetail, frm.Controls("Tabs").Pages(PageNum).Name, , ChangeTypeLeft, LastControlTop, ChangeTypeWidth, ControlHeight)
The rest of the code is as follows.
DoCmd.OpenForm "BOM5", acDesign
Set frm = Application.Forms("BOM5")
' Cycle through controls and set LastControlTop based on the last dynamic control, if any
For i = 0 To frm.Controls.Count - 1
Set ctl = frm.Controls(i)
Debug.Print ctl.Name
If ctl.Tag Like DYNAMIC_TAG & "*" Then
If ctl.ControlType = acComboBox Or ctl.ControlType = acTextBox Then
LastControlTop = ctl.Top + ControlHeight + ControlPadding
FormRowCount = FormRowCount + 1
End If
Else
FormRowCount = (FormRowCount / 6) + 1 ' Convert number of fields to number of rows then add one to start new batch of controls
Exit For
End If
Next
PageNum = frm.Controls("Tabs").Pages.Count - 1 ' .Pages has an index of 0. Getting PageNum to follow suit with the -1
' Add controls for inputting parts
For FormRowCount = FormRowCount To NewControlCount
With Application.CreateControl("BOM5", acComboBox, acDetail, frm.Controls("Tabs").Pages(PageNum).Name, , ChangeTypeLeft, LastControlTop, ChangeTypeWidth, ControlHeight)
.Name = "ChangeType" & FormRowCount
.Tag = DYNAMIC_TAG
.RowSourceType = "Table/Query"
.RowSource = "ChangeType"
End With
The last for loop has 5 other With Application.CreatControl statements, but I just showed the first one. The other 5 are similar except text boxes instead of combo.
I've had this error before, but I think I resolved it by moving the DoCmd.OpenForm statement to a different part of the code (like out of an if statement or for loop or somewhere that wasn't letting it get called) but I don't think that will resolve it. Besides, the first for loop iterates correctly since I see it grabbing the control height of the last dynamic control.
You can't do this. A form or report can only hold a certain amount of controls, deleted or not, so - eventually - it will not accept more controls. At that point, you must recreate the form from scratch.
So, don't delete the controls. Create those you may need and, at any time, hide those not needed and rename the rest if necessary.

Input data from excel to Web page(URL), and take a screen shot of the web page and copy results from web page to excel

Hi Team, i want to input data from excel to Web page(URL), and take a screen shot of the web page and copy results from web page to excel.
the url links - https://www.random.org/integers/
i want to generate 15 requests of random numbers from the above link. Every time i need to input value between in the for fields. When i press Get numbers i will get the random numbers. I want to copy random result numbers to my excel and also i need screen shots of both the web page as proof.
can some pls help my request.
This will do it using selenium basic wrapper for vba. Props to #FlorentB for this wrapper.
Code:
Option Explicit
Public Sub GatherScreenShots()
Dim variablesArray(), numRequests As Long, d As New ChromeDriver, i As Long, inputFields As WebElements
Const OUTPUTPATH As String = "C:\Users\User\Desktop\screenshot"
variablesArray = ThisWorkbook.Worksheets("Sheet1").Range("A1").CurrentRegion.Value
numRequests = UBound(variablesArray, 1)
With d
.Start "Chrome"
.Get "https://www.random.org/integers/"
For i = 2 To numRequests '<== Note UBound was 16 but looping from 2 so 15 requests in example given
Set inputFields = d.FindElementsByCss("input[type=""text""]")
inputFields(2).Clear
inputFields(2).SendKeys variablesArray(i, 2) 'NUM_INTEGERS
inputFields(3).Clear
inputFields(3).SendKeys variablesArray(i, 3) 'MIN_VALUE '<==Remember to check this is lower than MAX_VALUE
inputFields(4).Clear
inputFields(4).SendKeys variablesArray(i, 4) 'MAX_VALUE
inputFields(5).Clear
inputFields(5).SendKeys variablesArray(i, 5) 'NUM_COLUMNS
d.FindElementByCss("input[value=""Get Numbers""]").Click
' Application.Wait Now + TimeSerial(0, 0, 1) '<== Not needed in testing but just in case you want to add a wait
.TakeScreenshot.SaveAs OUTPUTPATH & i - 1 & ".jpg"
d.FindElementByCss("input[value=""Go Back""]").Click
' Application.Wait Now + TimeSerial(0, 0, 1)
Next i
End With
d.Quit
End Sub
Example input data in Sheet1:
Note:
There is a method driver.TakeScreenshot().ToExcel I believe though I prefered to output to desktop.

VBA - another userfom open itself while I don't code this order

First of all, I'm sorry for my english speaking.
I test a code in order to implement a list of item for a business. My userform is use to search an item regarding other item which is linked. The valid bouton is used to search that and write the links on other listbox. When I click on the valid bouton, another userform open it. I don't understand why.
This is my code regarding this userform, can you explain me why vba do this ?
Private Sub valider_Click()
Dim i As Integer
subcat2.Enabled = True
cat2.Enabled = True
fami2.Enabled = True
depar2.Enabled = True
i = 1
While nom2 <> Feuil1.Cells(i, 1)
i = i + 1
Wend
subcat2 = Feuil1.Cells(i, 2)
cat2 = Feuil1.Cells(i, 3)
fami2 = Feuil1.Cells(i, 4)
depar2 = Feuil1.Cells(i, 5)
End Sub
Tkank you,
Best regards
Try putting a breakpoint in the valider_Click() method and running in debug mode and clicking the button.
If your program hits the breakpoint, then the button is wired to the event handler method correctly.
Otherwise, look at the button properties to see whether it's wired to the right event. Maybe it's accidentally wired to something that opens the other form?

Behind-the-scenes VBA activity interfering with listboxes

Background:
I have a VBA project in an Excel spreadsheet. In it, I have a form that contains a frame that contains multiple labels/listboxes.
When the application is loaded, these listboxes are populated with data. (Nearly) everything works as expected, and this is what the form looks like:
My Problem:
My problem is that when a user clicks on an item in a listbox, that listbox is automatically "jumped into view" or something. For example; if I click on list item 5 like so, the frame scrolls down so that the listbox is at the top:
Before Click:
After Click:
You can see that the list item under my click has been selected, but the list was scrolled up beforehand so it's not actually the intended selection. This is not being done by any of my code.
If I put a "Stop" as the "Enter" and "Click" event handlers, the correct list item is selected and the list has not jumped at "Enter", but has by "Click".
More information:
If I continue to click on other elements from the same listbox, the listbox does not "jump". I can scroll up and down, and the listbox will not jump. As soon as I click in a DIFFERENT listbox (so "listbox1_Exit" and "listbox2_Enter" have been raised), the new listbox is "jumped" into view.
My Question:
My Question is: what "behind-the-scenes" code is VBA executing between these two events, and how can I prevent this from occuring? Or is there a way to "monitor" events?
(VBA appears to just resume execution if you "step" past the end of an event handler, rather than move to the next executing line of code - which would REALLY be helpful here...)
Edit:
Minimal example - plonk a frame on an empty form, add 2 listboxes to the frame and execute this code in the form:
Private Sub UserForm_Initialize()
Dim lb1 As Control
Dim lb2 As Control
Dim Frame1 As Control
Set Frame1 = Me.Controls("Frame1")
Set lb1 = Me.Controls("ListBox1")
Set lb2 = Me.Controls("ListBox2")
lb1.Height = 500
lb2.Height = 500
For i = 1 To 25
lb1.AddItem ("Potato " & i)
lb2.AddItem ("Frog " & i)
Next i
lb1.Top = 0
lb2.Top = lb1.Height + 10
Frame1.ScrollHeight = lb1.Height + lb2.Height + 10
End Sub
then scroll to the point where you can see the end of Listbox1 and the start of Listbox2, and try clicking elements in Listbox2.

Opening new form after right click on selected record in continuous form

In my access database before I was using a list box in the form for having list of items and I had below code for opening new form after right click on each selected item in list box.
Private Sub ItemList_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Const RIGHTBUTTON = 2
If Button = RIGHTBUTTON Then
DoCmd.OpenForm "frmShortcut_GenerateTask"
DoCmd.MoveSize udtPos.X * mp.TwipsPerPixelX, udtPos.Y * mp.TwipsPerPixelY
End If
End Sub
Now I am using a continuous form instead of list box and I have defined a [isselected) field for selecting each record in continuous form after clicking on that. Now my problem is how I have to write code for right clicking and opening new form.
I used the same code I had used for list box, but it does not work and nothing happened.
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Const RIGHTBUTTON = 2
If Button = RIGHTBUTTON Then
DoCmd.OpenForm "frmShortcut_GenerateTask"
DoCmd.MoveSize udtPos.X * mp.TwipsPerPixelX, udtPos.Y * mp.TwipsPerPixelY
End If
End Sub
Private Sub P_Click()
On Error Resume Next
Me.IsSelected = Not Me.IsSelected
' Save the status
Me.Dirty = False
' Force conditional highlighting
P_ForceHighLight
' Update display in SF_Selected
Me.Parent("SF_Selected").Requery
ActiveControl.SelLength = 0
On Error GoTo 0
End Sub
I recommend either using a DoubleClick event in all of your textboxes and combos, or else putting a small button at one edge of your continuous form that allows the user to open records. Right-click is going to give you problems (so will labels and image controls) because this event doesn't cause (or ensure) that the Form's internal Recordset Bookmark property is actually moved to the record they right-clicked on. In my experience, only buttons, textboxes, and comboboxes will move the Bookmark to the record the user is trying to select.
To Test this, try putting code at the top of your different routines that shows you what record is selected:
MsgBox "RecordID = " & Me!RecordIDField
If you are consistently getting the correct ID, then your problem has to do with how your opening your new form, passing parameters or arguments, etc.