Currently I'm using InStr to find a string in a string, I'm new to VB.NET and wondering if I can use InStr to search every element of an array in a string, or a similar function like this:
InStr(string, array)
Thanks.
You need to loop:
Dim bFound As Boolean = False
For Each elem As String In array
If myString.Contains(elem) Then
bFound = True
Exit For
End If
Next
You can transform it into a function to call it more than once easily:
Public Function MyInStr(myString As String, array() As String) As Boolean
For Each elem As String In array
If myString.Contains(elem) Then return True
Next
return false
End Function
Then:
MyInStr("my string text", New String() {"my", "blah", "bleh"})
Here goes the LINQ solution:
Dim a() = {"123", "321", "132"}
Dim v = a.Select(Function(x) InStr(x, "3")).ToArray
MessageBox.Show(String.Join(",", v)) '3,1,2
Converting SysDragon's answer to classic asp:
You need to loop:
Dim bFound
bFound = False
For Each elem In myArray
If InStr(myString, elem)>=0 Then
bFound = True
Exit For
End If
Next
You can transform it into a function to call it more than once easily:
Function MyInStr(myString, myArray)
Dim bFound
bFound = false
For Each elem In myArray
If InStr(myString, elem)>=0 Then
bFound = True
Exit For
End If
Next
MyInStr = bFound
End Function
Then:
MyInStr("my string text", Array("my", "blah", "bleh"))
If you are looking at searching for a string in any of the items in a string array, then you can use array.find(<T>) method. See more here: http://msdn.microsoft.com/en-IN/library/d9hy2xwa%28v=vs.90%29.aspx
Instr returns an integer specifying the start position of the first occurrence of one string within another.
Refer this
To find string in a string you can use someother method
Here is an example of highlighting all the text you search for at the same time but if that is not what you want, you have to solve it on your own.
Sub findTextAndHighlight(ByVal searchtext As String, ByVal rtb As RichTextBox)
Dim textEnd As Integer = rtb.TextLength
Dim index As Integer = 0
Dim fnt As Font = New Font(rtb.Font, FontStyle.Bold)
Dim lastIndex As Integer = rtb.Text.LastIndexOf(searchtext)
While (index < lastIndex)
rtb.Find(searchtext, index, textEnd, RichTextBoxFinds.WholeWord)
rtb.SelectionFont = fnt
rtb.SelectionLength = searchtext.Length
rtb.SelectionColor = Color.Red
rtb.SelectionBackColor = Color.Cyan
index = rtb.Text.IndexOf(searchtext, index) + 1
End While
End Sub
This method with search for text "boy" in RichTextBox2, change the textcolor to red and back color to cyan
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
findTextAndHighlight("boy", RichTextBox2)
End Sub
Related
I am trying to create an excel function which will fill column with data gathered from OGame's reports. I have encountered strage behavior (at least from my point of view).
I have a form where the user can copy their reports to a form's textbox. After clicking the button, the following functions should start:
Option Explicit
Private Sub CommandButton1_Click()
Dim arr() As String
Dim test As Boolean
Dim str As String
str = testFunction()
arr = readData(Raporty.Value)
' Dim element As Variant
' For Each element In arr
' Debug.Print element
' Debug.Print "-------------------------------"
' Next element
test = writeData(arr)
Debug.Print (test)
Debug.Print ("str: " + str)
Unload ufWczytajRaporty
End Sub
Private Function testFunction() As String
Debug.Print ("testFunction")
testFunction = "testFunctionText"
End Function
Private Function writeData(arr1() As String) As Boolean
Debug.Print ("writeData")
For Each element In arr1
writeDataRow (element)
Next element
writeData = True
End Function
Private Function readData(text As String) As String()
Debug.Print ("readData")
Dim list As Object
Dim substr As Integer
Dim temp As String
Dim arr(0 To 10) As String
Dim result() As String
Dim counter As Integer
Set list = CreateObject("System.Collections.ArrayList")
counter = 0
If text = "" Then
MsgBox "Dane nie mogą być puste! Proszę uzupełnić poprawnymi raportami!", vbCritical
Else
If InStr(1, text, "Przybył statek handlowy") = 1 Then
While (InStr(1, text, "Towar został już odebrany."))
substr = InStr(1, text, "Towar został już odebrany.") + 26
arr(counter) = Left(text, substr)
temp = Mid(text, substr, Len(text))
text = temp
counter = counter + 1
Wend
Unload ufWczytajRaporty
Else
MsgBox "Niepoprawne raporty! Proszę wkleć dobre raporty!", vbCritical
End If
End If
ReDim result(0 To counter)
Dim i As Integer
For i = 0 To counter
result(i) = arr(i)
Next i
readData = arr
End Function
This functions provide the following result in Immediate:
testFunction
readData
False
str: testFunctionText
As you can see the above false is a call of writeData fuction, however it never entered the function. writeData function contains Debug.Print ("writeData") but it was never displayed.
Furthermore if I change places the following function:
str = testFunction()
arr = readData(Raporty.Value)
to
arr = readData(Raporty.Value)
str = testFunction()
testFunction is not called aswell.
Can someone explain me what is happening? Why those functions are not called?
I would need a little help. If in the Textbox - TxtStringNum1.Text - we have the Digit 3. and TxtIntDraws.Lines (1) - contains the following set: 13,20,21,23,47,49,50,51,63,64,66,70
It shows me that there is Exists a Digit of 3, but it is actually the Digits of 13. It fails to look for it as a whole.
Private Sub ScanareLinia1()
Dim textsrtring As String = TxtStringNum1.Text
Dim words As String() = textsrtring.Split(New Char() {" "c})
' Split string based on space
Dim found As Boolean = False
' Use For Each loop over words
Dim word As Integer
For Each word In words
For i As Integer = 0 To TxtIntDraws.Lines.Count - 1
If TxtIntDraws.Lines(1).Contains(word) Then
TxtResultStr1.Text = word
End If
Next
Next
ScanareLinia2()
End Sub
I have a good comparison code, but I do not know how to use it for the code above.
Private Sub CompareNumbers()
'Pentru funcția de Check-In (For Match Exactly Value Number in List)
'First Textbox that is to be used for compare
Dim textBox1Numbers As List(Of Integer) = GetNumbersFromTextLine(TxtStringNum1.Text)
'Second Textbox that is to be used for compare
Dim textBox2Numbers As List(Of Integer) = GetNumbersFromTextLine(TxtbValBeforeCompar.Text)
'Union List of Common Numbers (this uses a lambda expression, it can be done using two For Each loops instead.)
Dim commonNumbers As List(Of Integer) = textBox1Numbers.Where(Function(num) textBox2Numbers.Contains(num)).ToList()
'This is purely for testing to see if it worked you can.
Dim sb As StringBuilder = New StringBuilder()
For Each foundNum As Integer In commonNumbers
sb.Append(foundNum.ToString()).Append(TextBox25.Text)
TxtbValAfterCompar.Text = (sb.ToString())
Next
End Sub
Private Function GetNumbersFromTextLine(ByVal sTextLine As String) As List(Of Integer)
'Pentru funcția de Check-In (For Match Exactly Value Number in List)
Dim numberList As List(Of Integer) = New List(Of Integer)()
Dim sSplitNumbers As String() = sTextLine.Split(TextBox8.Text)
For Each sNumber As String In sSplitNumbers
If IsNumeric(sNumber) Then
Dim iNum As Integer = CInt(sNumber)
TxtbValAfterCompar.Text = iNum
If Not numberList.Contains(iNum) Then
TxtbValAfterCompar.Text = ("")
numberList.Add(iNum)
End If
Else
End If
Next
Return numberList
End Function
You can use the following condition using String.Split and Array.IndexOf:
If Array.IndexOf(TxtIntDraws.Lines(1).Split(","c), CStr(word)) > -1 Then
TxtResultStr1.Text = word
End If
So the following Array.IndexOf(CStr("13,14,15,16,17").Split(","c), "13") > -1 is True and Array.IndexOf(CStr("13,14,15,16,17").Split(","c), "3") > -1 is False.
The program I'm working on has two different functions, one that calculates the number of syllables in a text file, and another that calculates the readability of the text file based on the formula
206.835-85.6*(Number of Syllables/Number of Words)-1.015*(Number of Words/Number of Sentences)
Here are the problems I'm having:
I'm supposed to display the contents of the text file in a multi-line text box.
I'm supposed to display the answer I get from the function indexCalculation in a label below the text box.
I'm having trouble calling the function to actually have the program calculate the answer to be displayed in the label.
Here is the code I have so far.
Option Strict On
Imports System.IO
Public Class Form1
Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
Me.Close()
End Sub
Private Sub OpenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click
Dim open As New OpenFileDialog
open.Filter = "text files |project7.txt|All file |*.*"
open.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
If open.ShowDialog() = Windows.Forms.DialogResult.OK Then
Dim selectedFileName As String = System.IO.Path.GetFileName(open.FileName)
If selectedFileName.ToLower = "project7.txt" Then
Dim text As String = File.ReadAllText("Project7.txt")
Dim words = text.Split(" "c)
Dim wordCount As Integer = words.Length
Dim separators As Char() = {"."c, "!"c, "?"c, ":"c}
Dim sentences = text.Split(separators, StringSplitOptions.RemoveEmptyEntries)
Dim sentenceCount As Integer = sentences.Length
Dim vowelCount As Integer = 0
For Each word As String In words
vowelCount += CountSyllables(word)
Next
vowelCount = CountSyllables(text)
Label1.Show(indexCalculation(wordCount, sentenceCount, vowelCount))
Else
MessageBox.Show("You cannot use that file!")
End If
End If
End Sub
Function CountSyllables(word As String) As Integer
word = word.ToLower()
Dim dipthongs = {"oo", "ou", "ie", "oi", "ea", "ee", _
"eu", "ai", "ua", "ue", "au", "io"}
For Each dipthong In dipthongs
word = word.Replace(dipthong, dipthong(0))
Next
Dim vowels = "aeiou"
Dim vowelCount = 0
For Each c In word
If vowels.IndexOf(c) >= 0 Then vowelCount += 1
Next
If vowelCount = 0 Then
vowelCount = 1
End If
Return vowelCount
End Function
Function indexCalculation(ByRef wordCount As Integer, ByRef sentenceCount As Integer, ByRef vowelCount As Integer) As Integer
Dim answer As Integer = CInt(206.835 - 85.6 * (vowelCount / wordCount) - 1.015 * (wordCount / sentenceCount))
Return answer
End Function
End Class
Any suggestions would be greatly appreciated.
Here are my suggestions:
update your indexCalculation function to take in Integers, not strings. that way you don't have to convert them to numbers.
remove all of your extra variables you are not using. this will clean things up a bit.
remove your streamreader. it appears you are reading the text via File.ReadAllText
Label1.Show(answer) should be changed to Label1.Show(indexCalculation(wordCount,sentenceCount,vowelCount)) -- unless Label1 is something other than a regular label, use Label1.Text = indexCalculation(wordCount,sentenceCount,vowelCount))
Then for the vowelCount, you need to do the following:
Dim vowelCount as Integer = 0
For Each word as String in words
vowelCount += CountSyllables(word)
Next
Also, add the logic to the CountSyllables function to make it 1 if 0. If you don't want to include the last character in your vowel counting, then use a for loop instead of a for each loop and stop 1 character short.
How to make a style as a bookmark in word 2010?
You won't be able to use most of the text in the document as the bookmark name. It is just illegal to use certain characters in a bookmark name in Word/VBA. It may be possible to add such characters in bookmark names in an XML format of the document, so if it is required, you can ask a separate question.
This feels like way too much code to post on SO. You really need to explain what framework you have in place and tell us where your hurdles are. We can't do this again. "Works for me". If you have any questions though don't hesitate to ask.
Run the "RunMe" macro at the bottom.
Private Function IsParagraphStyledWithHeading(para As Paragraph) As Boolean
Dim flag As Boolean: flag = False
If InStr(1, para.Style, "heading", vbTextCompare) > 0 Then
flag = True
End If
IsParagraphStyledWithHeading = flag
End Function
Private Function GetTextRangeOfStyledParagraph(para As Paragraph) As String
Dim textOfRange As String: textOfRange = para.Range.Text
GetTextRangeOfStyledParagraph = textOfRange
End Function
Private Function BookmarkNameAlreadyExist(bookmarkName As String) As Boolean
Dim bookmark As bookmark
Dim flag As Boolean: flag = False
For Each bookmark In ActiveDocument.Bookmarks
If bookmarkName = bookmark.name Then
flag = True
End If
Next
BookmarkNameAlreadyExist = flag
End Function
Private Function CreateUniqueBookmarkName(bookmarkName As String)
Dim uniqueBookmarkName As String
Dim guid As String: guid = Mid$(CreateObject("Scriptlet.TypeLib").guid, 2, 36)
guid = Replace(guid, "-", "", , , vbTextCompare)
uniqueBookmarkName = bookmarkName & guid
CreateUniqueBookmarkName = uniqueBookmarkName
End Function
Private Function BookmarkIt(rng As Range, bookmarkName As String)
Dim cleanName As String: cleanName = MakeValidBMName(bookmarkName)
If BookmarkNameAlreadyExist(cleanName) Then
cleanName = CreateUniqueBookmarkName(cleanName)
End If
ActiveDocument.Bookmarks.Add name:=cleanName, Range:=rng
End Function
''shamelessly stolen from gmaxey at http://www.vbaexpress.com/forum/showthread.php?t=37674
Private Function MakeValidBMName(strIn As String)
Dim pFirstChr As String
Dim i As Long
Dim tempStr As String
strIn = Trim(strIn)
pFirstChr = Left(strIn, 1)
If Not pFirstChr Like "[A-Za-z]" Then
strIn = "A_" & strIn
End If
For i = 1 To Len(strIn)
Select Case Asc(Mid$(strIn, i, 1))
Case 49 To 58, 65 To 90, 97 To 122
tempStr = tempStr & Mid$(strIn, i, 1)
Case Else
tempStr = tempStr & "_"
End Select
Next i
tempStr = Replace(tempStr, " ", " ")
MakeValidBMName = tempStr
End Function
Sub RunMe()
Dim para As Paragraph
Dim textOfPara As String
For Each para In ActiveDocument.Paragraphs
If IsParagraphStyledWithHeading(para) Then
textOfPara = GetTextRangeOfStyledParagraph(para)
If para.Range.Bookmarks.Count < 1 Then
BookmarkIt para.Range, textOfPara
End If
End If
Next
End Sub
There are some good examples on how to calculate word frequencies in C#, but none of them are comprehensive and I really need one in VB.NET.
My current approach is limited to one word per frequency count. What is the best way to change this so that I can get a completely accurate word frequency listing?
wordFreq = New Hashtable()
Dim words As String() = Regex.Split(inputText, "(\W)")
For i As Integer = 0 To words.Length - 1
If words(i) <> "" Then
Dim realWord As Boolean = True
For j As Integer = 0 To words(i).Length - 1
If Char.IsLetter(words(i).Chars(j)) = False Then
realWord = False
End If
Next j
If realWord = True Then
If wordFreq.Contains(words(i).ToLower()) Then
wordFreq(words(i).ToLower()) += 1
Else
wordFreq.Add(words(i).ToLower, 1)
End If
End If
End If
Next
Me.wordCount = New SortedList
For Each de As DictionaryEntry In wordFreq
If wordCount.ContainsKey(de.Value) = False Then
wordCount.Add(de.Value, de.Key)
End If
Next
I'd prefer an actual code snippet, but generic 'oh yeah...use this and run that' would work as well.
This might be what your looking for:
Dim Words = "Hello World ))))) This is a test Hello World"
Dim CountTheWords = From str In Words.Split(" ") _
Where Char.IsLetter(str) _
Group By str Into Count()
I have just tested it and it does work
EDIT! I have added code to make sure that it counts only letters and not symbols.
FYI: I found an article on how to use LINQ and target 2.0, its a feels bit dirty but it might help someone http://weblogs.asp.net/fmarguerie/archive/2007/09/05/linq-support-on-net-2-0.aspx
Public Class CountWords
Public Function WordCount(ByVal str As String) As Dictionary(Of String, Integer)
Dim ret As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer)
Dim word As String = ""
Dim add As Boolean = True
Dim ch As Char
str = str.ToLower
For index As Integer = 1 To str.Length - 1 Step index + 1
ch = str(index)
If Char.IsLetter(ch) Then
add = True
word += ch
ElseIf add And word.Length Then
If Not ret.ContainsKey(word) Then
ret(word) = 1
Else
ret(word) += 1
End If
word = ""
End If
Next
Return ret
End Function
End Class
Then for a quick demo application, create a winforms app with one multiline textbox called InputBox, one listview called OutputList and one button called CountBtn. In the list view create two columns - "Word" and "Freq." Select the "details" list type. Add an event handler for CountBtn. Then use this code:
Imports System.Windows.Forms.ListViewItem
Public Class MainForm
Private WordCounts As CountWords = New CountWords
Private Sub CountBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CountBtn.Click
OutputList.Items.Clear()
Dim ret As Dictionary(Of String, Integer) = Me.WordCounts.WordCount(InputBox.Text)
For Each item As String In ret.Keys
Dim litem As ListViewItem = New ListViewItem
litem.Text = item
Dim csitem As ListViewSubItem = New ListViewSubItem(litem, ret.Item(item).ToString())
litem.SubItems.Add(csitem)
OutputList.Items.Add(litem)
Word.Width = -1
Freq.Width = -1
Next
End Sub
End Class
You did a terrible terrible thing to make me write this in VB and I will never forgive you.
:p
Good luck!
EDIT
Fixed blank string bug and case bug
This might be helpful:
Word frequency algorithm for natural language processing
Pretty close, but \w+ is a good regex to match with (matches word characters only).
Public Function CountWords(ByVal inputText as String) As Dictionary(Of String, Integer)
Dim frequency As New Dictionary(Of String, Integer)
For Each wordMatch as Match in Regex.Match(inputText, "\w+")
If frequency.ContainsKey(wordMatch.Value.ToLower()) Then
frequency(wordMatch.Value.ToLower()) += 1
Else
frequency.Add(wordMatch.Value.ToLower(), 1)
End If
Next
Return frequency
End Function