How can click on a javascript show link programatically with vb.net? - vb.net

I'm trying to develop a new feature for our vb.net order entry system. At the moment I provide an assisted paypal login which loops through transactions and copies the transactions. My program then looks at this data and copies it into text boxes. The operator then approves and saves the record.
EDIT: I need to see the transaction in PayPal.
So my code uses IHTMLFormElement and loops round form elements and adds values. However I only really use this to log in to paypal. See my code...
Dim theObject As Object = Nothing
theObject = "https://www.paypal.com/cgi-bin/webscr?cmd=_login-run"
WebBrowPayPal.AxWebBrowser1.Navigate2(theObject)
While WebBrowPayPal.AxWebBrowser1.ReadyState <>
tagREADYSTATE.READYSTATE_COMPLETE
Application.DoEvents()
End While
Dim HtmlDoc As IHTMLDocument2 = CType(WebBrowPayPal.AxWebBrowser1.Document,
IHTMLDocument2)
Dim FormCol As IHTMLElementCollection = HtmlDoc.forms
Dim iForms As Integer = FormCol.length
Dim i As Integer
Dim x As Integer
For i = 0 To iForms - 1
Dim oForm As IHTMLFormElement = CType(FormCol.item(CType(i, Object),
CType(i, Object)), IHTMLFormElement)
For x = 0 To oForm.length - 1
If oForm.elements(x).tagname = "INPUT" Then
If oForm.elements(x).name = "login_email" Then
oForm.elements(x).value = "PayPal#mydomain.com"
End If
If oForm.elements(x).name = "login_password" Then
oForm.elements(x).value = "mypassword"
End If
If oForm.elements(x).type = "submit" Or _
oForm.elements(x).type = "SUBMIT" Then
oForm.elements(x).click()
End If
End If
Next
Next i
I'm now trying this page
https://www.paypal.com/uk/cgi-bin/webscr?cmd=_history&nav=0.3.0
Which is the history page, which allows you to search on the paypal transaction id.
Unfortunately you need to click on 'find a transaction' which then uses some javascript to shows the post fields. So the problem is that the fields I need to use are hidden.
How can I click on this javascript link in code ?

I'm not sure if this will help but you might want to try executing the script (which fires when you're clicking "Find a transaction") directly using IHTMLDocument2.write method:
Dim HtmlDoc As IHTMLDocument2 = CType(WebBrowPayPal.AxWebBrowser1.Document,
IHTMLDocument2)
HtmlDoc.write("<script>[Search button event handler]</script>")
UPDATE
I managed to get it working. Here is a form Load event handler (WinForms) that causes the Web Browser control to load http://www.google.com and then clicks "I'm feeling lucky" button:
Imports mshtml
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim clicked As Boolean = False
Dim doc As IHTMLDocument2 = Nothing
Dim form As IHTMLFormElement = Nothing
Dim input As HTMLInputElement = Nothing
Dim forms As IHTMLElementCollection = Nothing
AxWebBrowser1.Navigate2("http://www.google.com")
While AxWebBrowser1.ReadyState <> SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE
Application.DoEvents()
End While
doc = CType(AxWebBrowser1.Document, IHTMLDocument2)
For i As Integer = 0 To doc.forms.length - 1
form = CType(doc.forms.item(i, i), IHTMLFormElement)
For j As Integer = 0 To form.length - 1
If TypeOf (form.elements(j)) Is HTMLInputElement Then
input = CType(form.elements(j), HTMLInputElement)
If String.Compare(input.name, "btnI", StringComparison.InvariantCultureIgnoreCase) = 0 Then
input.click()
clicked = True
Exit For
End If
End If
Next
If clicked Then
Exit For
End If
Next
End Sub
End Class
If you need to click on a link then just change HTMLInputElement to HTMLLinkElement (in declaration and cast operation).
I suppose you're not using WinForms but if you do so, I'd suggest you to switch to the .NET version of the WebBrowser control.
Hope this will help you.
-- Pavel

Related

Fetch all the href links of a webpage using vba selenium

Option Explicit
Private chr As Selenium.ChromeDriver
Sub Test()
Set chr = New Selenium.ChromeDriver
chr.Start
chr.Get "https://www.grainger.com/category/pumps/rotary-pumps/rotary-gear-pump-heads?
categoryIndex=1"
chr.Wait 1000
Dim mylinks As Selenium.WebElements
Dim mylink As Selenium.WebElement
Dim i As Long
Set mylinks = chr.FindElementsByTag("a")
For i = 0 To mylinks.Count
For Each mylink In mylinks
If LCase(mylink.Attribute("data-testid")) = "product-detail-title" Then
Debug.Print mylink.Attribute("href")
Exit For
End If
Next mylink
i = i + 1
Next
End Sub
I was trying to extract all the href links present in that webpage link mentioned with the above code. But, the issue that i am facing is, whatever the first link it is fetching in the result, the same link is repeating in the next loop also in the result till mylinks.count. I think, i'm missing something here, kindly suggest what needs to be corrected here to get all the links as i needed. Please advise.

Catia Listbox items

I have this task where i need to find some type of hybridshapes and collect them in a listbox
i have done that part, but i need to create it in such a way that when user selects a item from the list box respective hybridshape or object should get selected in catia
here is the image
here is the code
Option Explicit
Dim ODoc As Document
Dim opartdoc As PartDocument
Dim oPart As Part
Dim ohybs As HybridBodies
Dim ohyb As HybridBody
Dim ohybshps As HybridShapes
Dim ohybshp As HybridShape
Dim i As Integer
Dim j As Integer
Private Sub UserForm_Initialize()
Set ODoc = CATIA.ActiveDocument
Set opartdoc = CATIA.ActiveDocument
Set oPart = opartdoc.Part
End Sub
Private Sub ListBtn_Click()
Set ohybs = oPart.HybridBodies
Set ohyb = ohybs.Item("Shapes")
Set ohybshps = ohyb.HybridShapes
For i = 1 To ohybshps.Count
Set ohybshp = ohybshps.Item(i)
ShapeBox.AddItem ohybshp.Name
ShapeBox.Font.Bold = True
ShapeBox.Font.Size = 25
Next
End Sub
Private Sub SelectBtn_Click()
End Sub
i dont know much about listbox handling
how do i create link between items in listbox and objects in catia
thanks
Hi you could add this to your code and try it. Beware your solution is pretty fragile one. You should consider more robust checks for objects validation
The trick lies in ShapeBox.Value in Shapebox click event. The rest is just catia stuff. But this solution is not foolproof because if you have more shapes with same names it might not select the right one. I would prefer creating a collection where you store real object from sets and the passing these objects to selection
Private Sub ShapeBox_Click()
Call opartdoc.Selection.Clear
Call opartdoc.Selection.Add(opartdoc.Part.FindObjectByName(ShapeBox.Value))
End Sub

Trying to delete a line in a text file -VB

I'm very new to coding so any help is appreciated.
I've created a simple listbox that displays an array from a text file.
I wanted to add a textbox and a delete button so the user can type a word and then delete that line from the text file.
I've read many forums with various solutions for this but all have returned errors - currently I am getting this error: "System.IO.IOException: 'The process cannot access the file 'C:\Users\hches\source\repos\Inventory\Inventory\bin\Debug\Stock.txt' because it is being used by another process.'"
in sub DeleteLine()
Here is the relevant code to the Delete button and the respective DeleteLine() sub:
Private Sub BTDel_Click(sender As Object, e As EventArgs) Handles BTDel.Click
Dim sr As New StreamReader("Stock.txt")
Dim i As Integer = 0
Dim deleted As Boolean = False
If TBSearch.Text = "" Then
MsgBox("Please enter an Item to Delete.")
Else
Do Until sr.Peek() = -1 Or deleted = True 'prevents it from looping through the whole stock if the item is deleted
Dim Itm As String = sr.ReadLine()
If Itm.Contains(TBSearch.Text) Or Itm.ToLower.Contains(TBSearch.Text.ToLower) Then 'if the line read from the text contains the search word, continue
MsgBox(TBSearch.Text & " has been deleted.") 'simple messagebox says it has been deleted
DeleteLine()
deleted = True
TBSearch.Clear()
ElseIf sr.Peek() = -1 Then 'if it reaches the end of the document and it hasn't been found
MsgBox("Item has not been deleted.") 'message box appears saying it is not deleted
deleted = False
TBSearch.Clear()
End If
i = i + 1
Loop
End If
End Sub
Public Sub DeleteLine()
Dim line As Integer = 0
Dim Filename = "Stock.txt"
Dim TheFileLines As New List(Of String)
For line = 0 To TheFileLines.Count
TheFileLines.AddRange(System.IO.File.ReadAllLines(Filename))
' if line is beyond end of list then exit sub
If line >= TheFileLines.Count Then Exit Sub
TheFileLines.RemoveAt(line)
System.IO.File.WriteAllLines(Filename, TheFileLines.ToArray)
Next
End Sub
Many thanks for any guidance,
Henry
SOLVED -- For anyone interested I will post my solution, thanks for the help.
Public Sub DeleteLine()
ArrayLoad() 'populates my array from text file
File.Delete("Stock.txt") 'deletes original text file
Dim stockList As List(Of String) = ItemNames.ToList 'creates a list using my array
stockList.Remove(TBSearch.Text) 'removes the searched item from the list
File.Create("Stock.txt").Dispose() 'creates a new text file (same name as the original so the program will work fine)
Using sw As New StreamWriter("Stock.txt") 'sets up a streamwriter to write the new list to the text file
For Each item As String In stockList
sw.WriteLine(item)
Next
sw.Flush()
sw.Close()
End Using
End Sub
End Class

How do I speed up searching through files on a network drive and prevent "not responding" in VB.Net

Part of my application searches for a string provided by a textbox within .txt files and .pdf files stored on a network drive. It works great on my PC when looking within a directory of a few files stored on a local disk, when I run it on my work PC which is less beefy and looking at a network drive I get "not responding" and it takes a good few minutes to finally wake up again. This is only searching through around 100 files and that number is only going to get bigger.
I thought about adding a progress bar, but if the application is not responding I assume the progress bar will not update? I would be very grateful to hear the advice of someone much more experienced in this than me.
In short, the code searches as described above, uses the name of the folder (that begins with SCC) to add an item to a listbox. If it cannot search the PDF for any reason then it adds it to another listbox displaying the folder names it was unable to search.
Here is the section of code that does the search:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim path As String = ""
Dim list As System.Collections.ObjectModel.ReadOnlyCollection(Of String)
Dim raf As itextsharp.text.pdf.RandomAccessFileOrArray = Nothing
Dim reader As itextsharp.text.pdf.PdfReader = Nothing
Dim searchPhrase As String = faultSearch.Text
VINListBox.Items.Clear()
Region "search plain text"
'finds text within faultSearch textbox within the files in directory
list = My.Computer.FileSystem.FindInFiles(archive_dir, faultSearch.Text, True, FileIO.SearchOption.SearchAllSubDirectories)
For Each foundFile As String In list
path = foundFile
GetVinName(path)
Next
End Region
Region "search PDF"
'Finds text within faultSearch textbox within PDF files in directory
For Each file As String In My.Computer.FileSystem.GetFiles(archive_dir, FileIO.SearchOption.SearchAllSubDirectories)
If System.IO.Path.GetExtension(file).ToUpper = ".PDF" Then
Try
raf = New itextsharp.text.pdf.RandomAccessFileOrArray(file)
reader = New itextsharp.text.pdf.PdfReader(raf, Nothing)
For i As Integer = 1 To reader.NumberOfPages()
Dim pageText As String = itextsharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, i)
If pageText.ToUpper.Contains(searchPhrase) Then
GetVinName(file)
End If
Next
Catch ex As Exception
GetErrVinName(file)
End Try
End If
Next
End Sub
End Region
Private Sub GetVinName(ByVal strVIN As String)
Dim fldName() As String
fldName = Split(strVIN.ToString, "\",, CompareMethod.Text)
For x = 0 To UBound(fldName) - 1
If InStr(fldName(x), "SCC", CompareMethod.Text) > 0 Then
strVIN = Trim(fldName(x))
If errListBox.Items.Contains(strVIN) = True Then
errListBox.Items.Remove(strVIN)
End If
If VINListBox.Items.Contains(strVIN) = False Then
VINListBox.Items.Add(strVIN)
End If
Exit For
End If
Next
End Sub
Private Sub GetErrVinName(ByVal strVIN As String)
Dim fldName() As String
fldName = Split(strVIN.ToString, "\",, CompareMethod.Text)
For x = 0 To UBound(fldName) - 1
If InStr(fldName(x), "SCC", CompareMethod.Text) > 0 Then
strVIN = Trim(fldName(x))
If VINListBox.Items.Contains(strVIN) = False Then
If errListBox.Items.Contains(strVIN) = False Then
errListBox.Items.Add(strVIN)
Else
Exit Sub
End If
Else
Exit Sub
End If
Exit For
End If
Next
End Sub

Log In to page automatically by filling in HTML elements with VB.NET

I'm attempting to migrate a script written in VBA inside a database into an application that I've written in VB.NET, as an added feature.
I understand that the VBA and VB.NET languages are very different and I've been having a hard time trying to migrate the section of code that I need.
I need to open an Internet Explorer page, fill in two textboxes that would be used for a username and password, and press the submit / login button automatically.
In VBA, I was able to do this using the below code.
Dim HTMLDoc As HTMLDocument
Dim MyBrowser As InternetExplorer
Dim MyHTML_Element As IHTMLElement
Dim MyURL As String
'Ignore errors
On Error GoTo Err_Clear
MyURL = Address
Set MyBrowser = New InternetExplorer 'Open Internet Explorer
MyBrowser.Silent = True 'Silence popups & Errors
MyBrowser.Navigate MyURL 'Browse
MyBrowser.Visible = True 'Obvious
Do
'Wait till finished
Loop Until MyBrowser.ReadyState = READYSTATE_COMPLETE
Set HTMLDoc = MyBrowser.Document
'Enter user / password
For Each MyHTML_Element In HTMLDoc.getElementsByTagName("input")
If MyHTML_Element.Name = ("username") Then
MyHTML_Element.Value = Username 'Variable to be passed to sub
ElseIf MyHTML_Element.Name = ("password") Then
MyHTML_Element.Value = Password 'Variable to be passed to sub
ElseIf MyHTML_Element.Type = "submit" Then
MyHTML_Element.Click: Exit For
End If
Next
Err_Clear:
If Err <> 0 Then
'Debug.Assert Err = 0
Err.Clear
Resume Next
End If
When moving this to VB.NET, even after adding the references I'd used for Microsoft Internet Controls, and Microsoft HTML Object library, I receive several errors such as:
Dim MyHTML_Element As IHTMLElement '"ITHMLElement" is ambiguous in the namespace 'mshtml'
Loop Until MyBrowser.Readystate = READYSTATE_COMPLETE 'Not declared
I've used Visual Basic before, but haven't used it to manipulate values of HTML pages within a web browser, and haven't been able to find much regarding this in VB.NET online.
I'm hoping someone can provide some insight into this for me, or point me in the right direction, thanks in advance!
I found an answer today on another site.
I was able to use the following vb.net code to identify each element, fill in it's value with a username and password, and then click a submit button (assuming the submit button's Element ID is known)
Dim theElementCollection As HtmlElementCollection = Me.WebBrowser1.Document.GetElementsByTagName("input")
For Each curElement As HtmlElement In theElementCollection
Dim controlName As String = curElement.GetAttribute("name").ToString.ToUpper
If controlName.ToUpper = "USERNAME" Then
curElement.SetAttribute("Value", Username)
ElseIf controlName.ToUpper = "PASSWORD" Then
curElement.SetAttribute("Value", Password)
WebBrowser1.Document.GetElementById("submitButton").InvokeMember("click") 'click button