Trying to get this to change the case of the first letter of the parsed strings segments. So if a user enters "JOHN WAYNE DOE" in txtName then it would display "John Wayne Doe"
I entered it the way it shows it in the book but the message box displays the parsed string however it was entered so in the above example the return is "JOHN WAYNE DOE"
I figure its a logic error since I am known to do that a lot just have no idea where i made the error.
Dim name As String = txtName.Text
name = name.Trim
Dim names() As String = name.Split(CChar(" "))
Dim firstName As String = names(0)
Dim middleName As String = names(1)
Dim lastName As String = names(2)
Dim firstLetters1 As String = firstName.Substring(0, 1).ToUpper
Dim otherletters1 As String = firstName.Substring(1).ToLower
Dim firstLetters2 As String = middleName.Substring(0, 1).ToUpper
Dim otherletters2 As String = middleName.Substring(1).ToLower
Dim firstletters3 As String = lastName.Substring(0, 1).ToUpper
Dim otherletters3 As String = lastName.Substring(1).ToLower
MessageBox.Show("First Name: " & firstName & vbCrLf & "Middle Name: " & middleName & vbCrLf & "Last Name: " & lastName)
Just to mention this alternative
Dim currentCulture As CultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture
Dim titleCase = currentCulture.TextInfo.ToTitleCase(txtName.Text)
Console.WriteLine(titleCase)
Dim names() As String = titleCase.Split(" "c)
......
This method ensure the proper casing of the string respecting the current culture.
And doesn't require so many direct splitting and string concatenations with the inherent memory footprint. (Internally, a StringBuilder is used to manipulate the input string, with just one final ToString() to return the result)
Try this:
MessageBox.Show(_
"First Name: " & firstLetters1 & otherletters1 & vbCrLf & _
"Middle Name: " & firstLetters2 & otherletters2 & vbCrLf & _
"Last Name: " & firstLetters3 & otherletters3)
String is immutable class, your ToUpper and ToLower calls create new instances. In the message box you are passing the old unprocessed instances.
Update
Alternatively, you can use our old call:
MessageBox.Show("First Name: " & firstName & vbCrLf & "Middle Name: " & middleName & vbCrLf & "Last Name: " & lastName)
as long as you do this before:
firstName = firstLetters1 & otherletters1
middleName = firstLetters2 & otherletters2
lastName = firstLetters3 & otherletters3
This might get you a better idea on how string's immutability works.
Dim Name As String = "JOHN WAYNE DOE"
Name = Microsoft.VisualBasic.StrConv(Name, VbStrConv.ProperCase)
The will give the output "John Wayne Doe"
Related
Originally the Keywords will we pulled out from a text file located on a web server.
Dim KeyWords As String = Split(Split(TempSMTPFile, "# Keywords #")(1), "# Keywords #")(0)
I want to create a function that will split out all the keywords inside a string
The keywords in this example will be:
' This list might be changed to more or less keywords.
Dim KeyWords As String = "[One=Test1]" & vbNewLine & "[Two=Test2]" & vbNewLine & "[Three=Test3]"
' I Need a function to split out all keywords and do below check between all splits.
If KeyWords.ToLower.Contains("[" & Splited_keyword & "=") Then ' One, Two, Three
MsgBox(Split(Split(KeyWords, "[" & Splited_keyword & "=")(1), "]")(0)) ' Test1, Test2, Test3
End If
' This should print OneTest1, TwoTest2, ThreeTest3
Thanks for your comments, I was able to solve this with this solution.
Dim str As String() = keywords.Split(New [Char]() {CChar(vbCrLf)})
For Each s As String In str
If s.Contains("[") Then
Dim SplittedKeyword = Split(Split(s, "[")(1), "=")(0)
If TextUserShortDescription.Text.ToLower.Contains(SplittedKeyword.ToLower) Then
MsgBox(SplittedKeyword & (Split(Split(s, "[" & SplittedKeyword & "=")(1), "]")(0)))
End If
End If
Next
This could help you (untested):
Dim keyValues as String()
keyValues = KeyWords.Split(Environment.NewLine)
For Each (keyvalue as string in keyValues)
MsgBox(keyvalue.SubString(1, keyvalue.IndexOf("["c) + " " + keyvalue.SubString(keyvalue.IndexOf("="c), keyvalue.LastIndexOf("]"c)
End For
I have a VB.net program that I am trying to add a bitlocker lookup tool that will search active directory for the machine name, and display the "Password ID" as well as the "Recovery Password"
So far my script/code works flawlessly for the lookup and displaying the Recovery Password, but I cannot get it to display the Password ID.
I've tried:
Item.Properties("msFVE-RecoveryGuid")(0)
Which returns the error "System.InvalidCastException: Conversion from type 'Byte()' to type 'String' is not valid."
Item.Properties("msFVE-RecoveryGuid")(0).ToString
Which returns "System.Byte[]"
Item.Properties("msFVE-RecoveryGuid").ToString
Which returns "System.DirectoryServices.ResultPropertyValueCollection"
So far in my searching I've only seen C# examples, and I haven't been able to translate.
The same for Recovery Password works however:
(Item.Properties("msFVE-RecoveryPassword")(0))
Here is the larger snippet of what I have for context:
Dim RootDSE As New DirectoryEntry("LDAP://RootDSE")
Dim DomainDN As String = RootDSE.Properties("DefaultNamingContext").Value
Dim ADsearch As New DirectorySearcher("LDAP://" & DomainDN)
ADsearch.Filter = ("(&(objectClass=computer)(name=" & MachineName & "))")
Dim ADresult As SearchResult = ADsearch.FindOne
Dim ADpath As String = ADresult.Path
Dim BTsearch As New DirectorySearcher()
BTsearch.SearchRoot = New DirectoryEntry(ADpath)
BTsearch.Filter = "(&(objectClass=msFVE-RecoveryInformation))"
Dim BitLockers As SearchResultCollection = BTsearch.FindAll()
Dim Item As SearchResult
Dim longTempstring As String = ""
For Each Item In BitLockers
If Item.Properties.Contains("msFVE-RecoveryGuid") Then
Dim tempstring As String = Item.Properties("msFVE-RecoveryGuid")(0).ToString
longTempstring = longTempstring & tempstring & vbNewLine
'ListBox2.Items.Add(Item.Properties("msFVE-RecoveryGuid")(0))
End If
If Item.Properties.Contains("msFVE-RecoveryPassword") Then
ListBox1.Items.Add(Item.Properties("msFVE-RecoveryPassword")(0))
End If
Next
MsgBox(longTempstring)
So I figured out that I needed to convert the bytes to hex in order to get them to match what is viewed in the Microsoft Management Console. Once I began doing that the only problem I ran into is that I discovered the indexing of the byte arrays are not in the same order as they are in Active Directory. -- so instead of looping I had to list out each index of the Byte array and sort them to their proper positions so that they match how they show up in AD.
My end function is:
Function bitread(ByVal GUID As Byte())
Dim tempVar As String
tempVar = GUID(3).ToString("X02") & GUID(2).ToString("X02") _
& GUID(1).ToString("X02") & GUID(0).ToString("X02") & "-" _
& GUID(5).ToString("X02") & GUID(4).ToString("X02") & "-" _
& GUID(7).ToString("X02") & GUID(6).ToString("X02") & "-" _
& GUID(8).ToString("X02") & GUID(9).ToString("X02") & "-" _
& GUID(10).ToString("X02") & GUID(11).ToString("X02") _
& GUID(12).ToString("X02") & GUID(13).ToString("X02") _
& GUID(14).ToString("X02") & GUID(15).ToString("X02")
Return tempVar
End Function
Called with:
bitread(Item.Properties("msFVE-RecoveryGUID")(0))
I have a class called Person which has the properties FirstName, LastName and MiddleName and I have a form-wide SortedDictionary(Of Integer, Person) called oPeople.
On Form_Load, I call a method that loads a list of 65 people. Right now this is hard-coded but eventually I'll be grabbing it from a database.
Once the form is loaded, I have a TextBox called txtSearchForName for the user to enter a search term and have the system look through oPeople filtering on LastName for a full or partial match (case insensitive).
Eventually I would like to be able to search for comparisons between FirstName, LastName and MiddleName (if there is one).
At this point all I want to do is loop through the results of the LINQ query and output them to the console window.
Here's the Person class:
Public Class Person
Private _fnm As String = String.Empty
Public Property FirstName() As String
Get
Return _fnm
End Get
Set(ByVal value As String)
_fnm = value.Trim
End Set
End Property
Private _lnm As String = String.Empty
Public Property LastName() As String
Get
Return _lnm
End Get
Set(ByVal value As String)
_lnm = value.Trim
End Set
End Property
Private _mnm As String = String.Empty
Public Property MiddleName() As String
Get
Return _mnm
End Get
Set(ByVal value As String)
_mnm = value.Trim
End Set
End Property
Public Sub New()
End Sub
Public Sub New(ByVal firstName As String,
ByVal lastName As String,
Optional ByVal middleName As String = "")
_fnm = firstName
_lnm = lastName
_mnm = middleName
End Sub
End Class
This is the method I'm using to add people. I'm adding 65 people but have cut the code down:
Private Sub FillPeopleDictionary()
Try
If oPeople.Count > 0 Then oPeople.Clear()
Dim oNewPerson As Person = Nothing
oNewPerson = New Person("Scarlett", "Johansson")
oPeople.Add(1, oNewPerson)
oNewPerson = New Person("Amy", "Adams")
oPeople.Add(2, oNewPerson)
oNewPerson = New Person("Jessica", "Biel")
oPeople.Add(3, oNewPerson)
Catch ex As Exception
MessageBox.Show(ex.Message, "Error [FillPeopleDictionary]", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
This is my LINQ statement followed by the output to console which is called when the user clicks a button:
Dim sSearchTerm As String = txtSearchForName.Text.Trim.ToLower
Dim queryResults = From person In oPeople
'Where SqlMethods.Like(person.Value.LastName.ToLower, "%" & sSearchTerm & "%")
'Where person.Value.LastName.ToLower.Contains("%" & sSearchTerm & "%")
Console.WriteLine("search term: " & sSearchTerm &
Environment.NewLine & Environment.NewLine &
"queryResults.Count: " & queryResults.Count.ToString &
Environment.NewLine)
For Each result In queryResults
If Not String.IsNullOrEmpty(result.Value.MiddleName) Then
Console.WriteLine(result.Key.ToString.PadLeft(2, "0") & ": " & result.Value.FirstName & " " & result.Value.MiddleName & " " & result.Value.LastName)
Else
Console.WriteLine(result.Key.ToString.PadLeft(2, "0") & ": " & result.Value.FirstName & " " & result.Value.LastName)
End If
Next
The LINQ statement works as it stands, with no conditions, so it loops through and correctly lists all of the people in the oPeople collection.
There are two Where clauses commented out below the initial queryResults statement. Those are the two ways I was trying to filter. One approach was to use .Contains and the other was to use .Like however neither works.
If the user was to type "mar", I would hope to get back a list of 6 people from the list of 65(case insensitive):
Meghan Markle
Margo Robbie
Kate Mara
Mary Elizabeth Winstead
Marian Rivera
Amy Smart
Now of course that is searching on FirstName and LastName. Right now I am just trying to get LastName to work. With only the LastName the list would only be:
Meghan Markle
Kate Mara
Amy Smart
Can anyone see what I am doing wrong here? Or should I scrap the idea of using LINQ with a SortedDictionary?
Change your Person class to include a PersonId and pass that through like oNewPerson = New Person(1, "Scarlett", "Johansson").
Change the oPeople to be a List(Of Person) so when adding it would look like this oPeople.Add(oNewPerson).
Your LINQ statement would then look like this:
Dim queryResults = From person In oPeople
Where person.FirstName.ToLower Like "*" & sSearchTerm & "*" Or
person.LastName.ToLower Like "*" & sSearchTerm & "*"
You would also want to change the rest as no longer using a dictionary:
For Each result In queryResults
If Not String.IsNullOrEmpty(result.MiddleName) Then
Console.WriteLine(result.PersonId.ToString.PadLeft(2, CChar("0")) & ": " & result.FirstName & " " & result.MiddleName & " " & result.LastName)
Else
Console.WriteLine(result.PersonId.ToString.PadLeft(2, CChar("0")) & ": " & result.FirstName & " " & result.LastName)
End If
Next
Hope this helps.
Your 2nd Where clause attempt is close, except the Contains function there is String.Contains which does not use the % wildcard characters that SQL uses, so you need:
Dim queryResults =
From person In oPeople
Where person.Value.LastName.ToLower.Contains(sSearchTerm)
You can easily add a check for FirstName with OrElse person.Value.FirstName.ToLower.Contains(sSearchTerm).
Change your Linq query to be as follows:
Dim queryResults = From p In oPeople
Where p.Value.FirstName.ToLower.Contains(sSearchTerm) Or p.Value.LastName.ToLower.Contains(sSearchTerm)
I need to find the position of a changing specified word in a string, and I need it to be very specific so it doesn't include words without spaces so say if I was looking for the word 'Hi' It would only return true if it was checking 'Hi' and not 'HiExample'.
Code:
Dim userString As String = userInput.Text
userString = userString.ToLower()
Dim d As New Dictionary(Of String, Integer)
Dim wordString = userString.ToLower().Split(" "c)
Dim iList As New List(Of String)()
For Each word In wordString
If d.ContainsKey(word) Then
d(word) += 1
iList.Add(word)
Else
d.Add(word, 1)
End If
Next
For Each de In d
For i As Integer = 0 To wordString.Count - 1
Dim index As Integer = userString.IndexOf(de.Key)
output.Text &= "Word: " & de.Key & " Occurrence: " & de.Value & " Position: " & GET POSTION OF EACH WORD HERE & Environment.NewLine
Next
Next
Checking for upper case or lower case will not be necessary as I have already converted the string into lower case.
Thanks,
Matt
you can try Regex
For Each de In d
Dim index As Integer = Regex.Matches(userString, "(?<=^|\b|\s)" & Regex.Escape(de.Key) & "(?=\s|\b|$)")(0).Index
Console.WriteLine("Word: " & de.Key & " Occurrence: " & de.Value & " Position: " & index)
Next
this might get you started
I need to send an email with a table that has variable values in each cell. I can do this using any method (html via email, an excel/word table, etc.). The only hitch is due to the restrictions of the Emailer program and System.Net.Mail import, it has to be a string.
Here's what I have so far:
Imports DelayEmailer.DelayTrackerWs
Imports System.Configuration
Public Class DelayEmailer
Public Shared Sub Main()
Dim ws As New DelayTrackerWs.DelayUploader
Dim delays As DelayTrackerWs.Delay()
Dim emailer As New Emailer()
Dim delaystring As String
delays = ws.SearchDelaysDate(DelayTrackerWs.AreaEnum.QT, DelayTrackerWs.UnitEnum.QT, Now.AddDays(-1), Now)
delaystring = "Delays" & vbNewLine
delaystring &= "Facilty Start Time Status Category Reason Comment"
For i = 0 To delays.Length - 1
delaystring &= vbNewLine & delays(i).Facility & " "
delaystring &= FormatDateTime(delays(i).DelayStartDateTime, DateFormat.ShortDate) & " "
delaystring &= FormatDateTime(delays(i).DelayStartDateTime, DateFormat.ShortTime) & " "
'delaystring &= delays(i).DelayDuration & " "
delaystring &= delays(i).Status & " "
delaystring &= delays(i).CategoryCode & " "
delaystring &= delays(i).ReasonCode & " "
delaystring &= delays(i).Comment
Next
emailer.Send(ConfigurationManager.AppSettings("EmailList"), "delays", delaystring)
End Sub
As you can see, I currently have just a bunch of concatenated strings that line up if the values of each delays(i) are the same. The other problem is that this needs to be easily viewable via mobile devices and with the strings, it wraps and gets really unreadable. A table here should fix this.
You can send html email from .NET using MailMessage and SmtpClient classes, create an email template as string and set MailMessage's IsBodyHtml property to true:
Dim strHeader As String = "<table><tbody>"
Dim strFooter As String = "</tbody></table>"
Dim sbContent As New StringBuilder()
For i As Integer = 1 To rows
sbContent.Append("<tr>")
For j As Integer = 1 To cols
sbContent.Append(String.Format("<td>{0}</td>", YOUR_TD_VALUE_STRING))
Next j
sbContent.Append("</tr>");
Next i
Dim emailTemplate As String = strHeader & sbContent.ToString() & strFooter
...