VB: Pull text from specific HTML tag into Textbox - vb.net

I am trying to write a VB.Net application that needs to pull the text from a specific tag:
<span data-reactid="85">172,890,000</span>
and then enter the text found 172,890,000 into a textbox on the form.
In Textbox1, you enter the Stock Symbol you want to search.
The data for "TTM - Total Revenue" will always be held within the:
<span data-reactid="85">172,890,000</span> tag. Regardless of stock you check.
In RichTextBox1, is the downloaded source code for the url.
TextBox2 is where it pulls "TTM". I will probably change it to a label as it's a constant value. I cant put the number in the variable as it will vary on the company, i.e. the value entered into TextBox1.
TextBox3 is going to show the value I really need. The 172,890,000 held in the
<span data-reactid="85">172,890,000</span> tag.
I was wondering how to search for the string within RichTextBox1, and pull the next 7 characters after the end of the string if that would work?
My code so far is:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Source As String
Dim ttm1 As String
Dim ttmrev As String
Source = New System.Net.WebClient().DownloadString("https://finance.yahoo.com/quote/" + TextBox1.Text + "/financials?p=" + TextBox1.Text)
ttm1 = <span data-reactid="65">ttm</span>
ttmrev = <span data-reactid="85"></span>
RichTextBox1.Text = Source
If RichTextBox1.Find(ttm1) Then
TextBox2.Text = "ttm".ToUpper
End If
End Sub
End Class

As usual in coding, there are always many ways to accomplish the same end result. One way is to use a Regex.
For example:
Imports System.Text.RegularExpressions
Sub Main
' In place of a static string here, place the exact line you want to search instead.
Dim str As String = "<span data-reactid=""85"">172,890,000</span>"
' Search for the match
showMatch(str, "(\d+),?(\d+),?(\d+)")
End Sub
Sub showMatch(ByVal text As String, ByVal expr As String)
' Make sure you're expression looks the way you want it
Debug.WriteLine("The Expression: " + expr)
' Declare the variable and do the regex match
Dim mc As MatchCollection = Regex.Matches(text, expr)
Dim m As Match
' Handle the result however you wish; for example instead of a loop, since
' there should only be 1 result you could just do
' something like: TextBox3.Text = m.ToString()
For Each m In mc
Debug.WriteLine(m)
Next m
End Sub
The above regex will find any number that matches for example:
172,890,000
890,000
000
2,80,000
etc.
Another choice might be to use a WebBrowser control, fetch the source into it, and play around with the innerHtml as needed.

Related

I need help outputting squares of numbers separated by commas

Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
TextBox2.Text = TextBox1.Text ^ 2
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
TextBox1.Text = Nothing
TextBox2.Text = Nothing
End Sub
End Class
The code above outputs squares of any single values input in textbox1 but i need some help in inputting a couple of values separated by commas and then output the squares of those individual values eg 3,4 the output 9,16
I'm not going to do it all for you, because this looks like homework, but here are some pointers:
TextBox2.Text = TextBox1.Text ^ 2
1) Turn on Option Strict, by placing Option Strict On at the top of your code file or by putting it in the project properties Compile tab. This will help you be more rigorous with your coding. Here you're taking a string (TextBox1.Text) and having VB auto convert it to a number (which might fail), squaring it, and then auto converting it back to a string to store in TextBox2.Text. This is bad news all round; always be crystal clear in your own mind and explicit in your coding about the difference between various data types.A string containing numbers is not the same thing as a number!
2) Rename your textboxes after you drop them on a form. Nothing is more frustrating than to read a block of code where the variable names are irrelevant garbage. You will find this when you come back to some complex code in 6 months and think "what the..."; renaming a textbox so it is called resultTextBox or inputTextBox takes seconds and makes your code instantly more comprehensible to both you and anyone you call in to help out with it
separated by commas
The following line of code will split a string into an array of strings, on comma:
Dim csv = "3,6"
Dim arr = csv.Split(","c)
Console.WriteLine(arr(0)) 'prints 3
Console.WriteLine(arr(1)) 'prints 6
The following line of code will convert a string to an integer:
Dim s = "3"
Dim i = Convert.ToInt32(s)
Maths operations can now be performed on it
i = i * i 'square it
The following line of code will turn an integer into a string:
Dim i as Integer = 3
Dim s as String = i.ToString() 's is now "3"
The following line of code will loop through an array, appending the values in the array to a string variable, and adding commas. Finally it trims off the excess trailing comma
Dim s as New String
For Each x as String in arr
s = s & x & ","
Next x
s = s.TrimEnd(","c)
Here is another way too, using the String.Join helper method:
Dim s as String = String.Join(","c, arr)

VB.net Using a string to change something.Text

I need to work in VB.net for school and have encountered a problem.
The program works like this:
I've got a store page with buttons to buy them, they each have a name with the item and "_buy" after it. So if I wanted to buy a laptop, I'd press a button named laptop_buy.
What I want then is to make the event call the fuction Buy(laptop), so I can use the laptop ID later on.
I also have things named like laptop_level and laptop_price. I want to change them when I click the button. So I created this function:
Private Sub laptop_buy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles laptop_buy.Click
Buy("laptop")
End Sub
And
Function Buy(ByVal item)
Dim itemlevel As String = item + "_level.Text"
itemlevel += 1
End Function
So this should change the laptop_level.Text when I click laptop_buy.
But it isn't working.
Help is greatly appriciated!
You can use ControlCollenction.Find method to get your label.
Then you need to cast it's text value to Integer (I recommend using Int32.TryParse method for that) and then add 1 and return the result to the label text. Something like this should do the trick.
Sub Buy(ByVal item As String)
Dim level As Inetger
Dim ItemLabel as Label;
Dim ChildControls As Control() = Me.Controls.Find(item & "_level", True)
If ChildControls.Length > 0 Then
ItemLabel = ChildControls(0)
End If
If not isNothing(ItemLabel) AndAlso Int32.TryParse(ItemLabel.Text, level) Then
ItemLabel.Text = (Level + 1).ToString
End If
End Sub
Note: Code was written directly here, and it's been a long time since my vb.net days, so there might be some mistakes in the code.
Your trying to add 1 to a string.
A 'String' is a series of text characters, so the '1' in your text box is the character '1' not the number. You need to first conver the text into an 'integer'
Try:
dim itemlevel as integer = TryCast(item, integer)
If IsNothing(itemlevel) = false then
itemlevel = itemlevel + 1
Return itemlevel
end if
MSDN TryCast

loop - reading text after a certain string up until a certain string

start=AKS-RHzlSXSftLGYdBNk.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1&
For every instance of the word 'start' I need to be able to get the text after the first full stop, right up until the & symbol. E.g. 'eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1'.
There will be more than one instance of this. They will need to be appended to a listbox.
What is the simplest/quickest way to do this? (Using possibly streamreader - text file)
The simplest and quickest way will be to read each line, and check if it .StartsWith("start="). If so, then get the .IndexOf(".") and the .IndexOf("&", <whereever the first indexOf was>). Get the .SubString which encompasses those two values. I'm sure you can write the code yourself from that ;)
I tested this function with a button click, output text each line on a textbox. I am sure you can adapt this to your code.
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
txtResults.Text = ""
Dim ParseString As String
ParseString = "start=123341.23124&kjdshfkjsdaksdstart=1231.2321312&kadhskjashdkjastart=1231.23126789898&skjdfhkjsd"
Dim Delimiters() As String = New String() {"start="}
Dim Words() As String
Words = ParseString.Split(Delimiters, CompareMethod.Text)
For Each Part In Words
Dim Middle As String
Middle = Part.Split(".").Skip(1).Take(1).FirstOrDefault()
Dim Good As String
Good = Middle.Split("&").FirstOrDefault()
txtResults.Text += Good + vbNewLine
Next
End Sub
Output was
23124
2321312
23126789898
Added 31104 lines to a string and ran, took about 11 seconds to run on my laptop. Might be too slow for your app?

How can I get specific items from text file? Visual Basic 2010

I am trying to figure out how to get a message box to show only specific words from a text file, which contains all of the words within the dictionary. I have tried various different ways, but cannot get it to work, but I do think I am on the right track so just need some pointers.
Basically, there is a scrambled up string, which is different every time, and is contained within a label. I want the program to only show words which contains the letters inside the scrambled string, but not sure how to achieve this?
Here is the code that I have so far:
Private Sub btnAnswers_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswers.Click
Dim hash As List(Of String) = New List(Of String)(System.IO.File.ReadAllLines("C:\Users\Katie\Documents\Project\dictionary.txt"))
Dim Letters As String
Dim OneCharacter As String
Dim Found As Boolean
Dim item As String
Dim AllCharacters As String
Found = False
Letters = lblLetters.Text
For i = 0 To Letters.Length - 1
OneCharacter = Letters.Substring(i, 1)
For Each item In hash
If item.Contains(OneCharacter) Then
Found = True
AllCharacters = OneCharacter
Else
Found = False
End If
MsgBox(item)
Next
Next i
End Sub
The message box does show up words, from the dictionary, but words can contain letters that are not present in the label string, so my code is wrong. Can anyone help? Apologies, but I am new to programming.
With a simple modification to the previous answer you can restrict the output to only words that contain only the scrambled letters:
Private Sub btnAnswers_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim hash As List(Of String) = New List(Of String)(System.IO.File.ReadAllLines("C:\Users\Katie\Documents\Project\dictionary.txt"))
Dim Letters As String = lblLetters.Text
For Each item As String In hash
Dim word As String = item.ToLower()
For i = 0 To Letters.Length - 1
Dim OneCharacter As Char = Char.ToLower(Letters(i))
While word.Contains(OneCharacter)
word = word.Remove(word.IndexOf(OneCharacter), 1)
End While
Next
If (word.Length = 0) Then
'The given dictionary entry includes all the letters in the label. No more iterations will be performed
MsgBox(item)
Exit For
End If
Next
End Sub
With this code if the scrambled letters contain 'bok' then "book" will get selected. However removing the while loop and leaving only the remove statement, will ensure that only the exact number of each different letter will match. so that 'obok' will be needed to match "book".
As suggested by Steven Doggart, you have to invert the loop nesting. What you want is going through all the dictionary entries and, for each of them, checking if it contains all the letters in the string. Your loop structure is not allowing to do that.
I have performed the required updates in your code. Bear in mind that this code ignores caps ("A" is the same than "a").
Private Sub btnAnswers_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim hash As List(Of String) = New List(Of String)(System.IO.File.ReadAllLines("C:\Users\Katie\Documents\Project\dictionary.txt"))
Dim Letters As String = lblLetters.Text
For Each item As String In hash
Dim Found As Boolean = True
For i = 0 To Letters.Length - 1
Dim OneCharacter As String = Letters.Substring(i, 1)
Dim itemToLower As String = item.ToLower()
If Not itemToLower.Contains(OneCharacter.ToLower()) Then
Found = False
Exit For
End If
Next i
If (Found) Then
'The given dictionary entry includes all the letters in the label. No more iterations will be performed
MsgBox(item)
Exit For
End If
Next
End Sub
This code looks for keys containing all the characters in the given label (not at the contrary), that is: with a label "dict", "dictentry" would be right.
In any case, the whole point of my answer is not delivering a code which you just have to execute; the point of this code is helping you to understand what you did wrong and how to start doing things right. If you are not interested in this exact functionality, you woud have to edit my code such that what you want can be accomplished; or, ideally, you would be writing your own code completely from scratch.
You're calling MsgBox(item) outside of the if statement that determines whether the current word contains the current character. Which means it's going to pop up for every letter, every word. Move MsgBox(item) inside the first half of the if statement if you only want it to show when the letter is actually found in the word.
I'd also suggest following Steven Doggart's advice and reversing the way the loops are nested. If the characters are the outer loop, you could get the message box multiple times per word (e.g., if your letters are "sdf" and one of the words is "foods," it will pop up 3 times).
For Each item In hash
For i = 0 To Letters.Length - 1
OneCharacter = Letters.Substring(i, 1)
If item.Contains(OneCharacter) Then
Found = True
AllCharacters = OneCharacter
MsgBox(item)
Else
Found = False
End If
Next
Next

VB 2010 array/write array to file

I'm close to getting this to work, but currently can't get any output to display in the listbox. I had it working, but needed to move some things around to get the join function to work.
In my program, a user enters input into a textbox and an array is displayed in a listbox based on what they type in. For example, if they type in "a", all foods (in the textfile that is connected to the program) that start with "a" will be displayed.
When there is output, I need to find a way to name this array (which is created based on what the user inputs) and join all of the items in the listbox (example: foods stacked on top of each other in the listbox will be shown at the bottom as a string).
I am posting the code that I have thus far; all of the errors that I'm getting (and potentially my logic errors) are just in the first public class until the end of the first if-next statement:
Public Class frmFoods
Dim foods() As String = IO.File.ReadAllLines("foods.txt")
Private Sub btnDisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisplay.Click
Dim Letter As String = txtLetter.Text.ToUpper
Dim smallerarray() As Array
Dim userarray As String
lstOutput.Items.Clear()
If IsNumeric(txtLetter.Text) = False Then
For Each food As String In foods
smallerarray = listfoods(Letter)
lstOutput.Items.Add(Letter)
userarray = Join(smallerarray, ", ")
lstOutput.Items.Add(userarray)
Next
ElseIf IsNumeric(txtLetter.Text) = True Then
MessageBox.Show("Please enter a letter.")
Else
MessageBox.Show("The text box is empty")
End If
End Sub
Function listfoods(ByVal letter As String) As String()
Dim foodarray(foods.Count - 1) As String
Dim counter As Integer = 0
For Each food As String In foods
If food.StartsWith(letter) Then
foodarray(counter) = food
counter += 1
End If
Next
ReDim Preserve foodarray(counter - 1)
Return foodarray
End Function
you need to save the results of the listfoods function in a dictionary or similar and associate it with a key if you want to 'Name' it, although its not clear why you need to do this
As for listing the foods starting with the particular letter, you just need to iterate your result of the function listfoods and separate each one by a comma don't you?
What you have now will create many lists of each food as you are getting the list of food beginning with a particular letter for each food.. As I understand the question you only need to do that once.
Example:
Private Sub btnDisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisplay.Click
Dim Letter As String = txtLetter.Text.ToUpper
Dim smallerarray() As Array
Dim userarray As String
lstOutput.Items.Clear()
If IsNumeric(txtLetter.Text) = False Then
'get all items from the file which begin with the letter the user chose
smallerarray = listfoods(Letter)
'add that letter to the output listbox
lstOutput.Items.Add(Letter)
'join all of the elements which begin with that letter
'into a single comma separated string
userarray = Join(smallerarray, ", ")
'add that string to the output
lstOutput.Items.Add(userarray)
ElseIf IsNumeric(txtLetter.Text) = True Then
MessageBox.Show("Please enter a letter.")
Else
MessageBox.Show("The text box is empty")
End If
End Sub
it would probably be useful for you to step through the code and see the values of the variable at each place and compare this with what you expect to see if you can see where the actual value differs from what your logically expect so you can start to identify where the issue is