Parse a text string into fields based on text and position VB - vb.net

I have a .text file of strings delimited by spaces. That would be the obvious parsing solution when I bring it into Excel or Access, but since the strings are not the same size, the fields will be incorrect. I'm hoping to find some help here as I'm not really experienced with this.
This is an example section of the string:
259998887575 15 00:14:38 C33 0:14:42 T33 00:14:52 00:14:58
202224446898 33 00:16:24 B23 00:17:00 C31 00:17:15 T31 00:19:30 C04 00:17:15 T28 00:19:30 00:19:32
The numbers with colons are time stamps and the letter codes (T/C/B) all represent a different field type. My problem is that there can be any number of C and T time stamps listed in the string and there may or may not be a B time stamp.
I'd like the result to show 4 fields... the first, the first c time stamp, the last t time stamp and the last time stamp (the bolded time stamps). All other information can be disregarded. I'd like to use VB to cycle through due to the number of records.
Any help is appreciated!

Edit: It seems like you want to split the dates into types, determined by the bit before each letter.
You can use the Strings.Split method to divide the lines at the spaces. Then use the Date.TryParse method to check which parts are Dates (or times, it's the same). Then you select the first letter of the previous part and sort the dates into their respective lists.
Dim s As String = "202224446898 33 00:16:24 B23 00:17:00 C31 00:17:15 T31 00:19:30 C04 00:17:15 T28 00:19:30 00:19:32"
Dim parts() As String = Strings.Split(s, " ") 'Split the string at all spaces
'Create lists of Date, one list for all dates, one list for each Letter
Dim Tdates As New List(Of Date) 'This stores converted dates
Dim Cdates As New List(Of Date) 'This stores converted dates
Dim Bdates As New List(Of Date) 'This stores converted dates
Dim Alldates As New List(Of Date) 'This stores converted dates
For i = 0 To parts.Count - 1 'Iterate through all parts
Dim ThisDate As Date
If Date.TryParse(parts(i), ThisDate) = True Then 'This tries to parse the current part as a date, returns True if the part is a date
Alldates.Add(ThisDate) 'You want to store all dates in this list
If i > 0 AndAlso parts(i - 1).Length > 0 Then
Dim PrevPartsFirstLetter As String = parts(i - 1)(0) 'Crop the first letter of the previous part
Select Case PrevPartsFirstLetter
Case "T" : Tdates.Add(ThisDate)
Case "C" : Cdates.Add(ThisDate)
Case "B" : Bdates.Add(ThisDate)
End Select
End If
End If
Next
'You can now select the parts you want from the lists
The Tdates-List contains all dates which have a T thing before them and so on. The AllDates-List contains all dates in the line.

Related

Get integer data from word tables

I have several word tables that I want to edit based on the value in the last row of the column. I want to delete column contents (except last row of specified column) if the value in the last row exceeds 20.
I have used . Range. Textbut I am having challenges with its implementation. I have this
For i = 3 To . Columns. Count
If ActiveDocument.Tables(i).Cell(ActiveDocument. Tables(i).Rows.Count, i).Range.Text >20 Then ...
How can I get VBA to return the contents of a cell not as a string but as an integer for calculation.
VBA's VAL() function will convert a string containing a numeric value into a number. The function starts from the left and recognises numbers until a non-numeric character is encountered and ignores everything that follows. In the case of text taken from a table cell that is very useful because the End-Of-Cell marker included in the text will be ignored.
Dim C As Long
For C = 1 To 3
With ActiveDocument.Tables(1)
If Val(.Rows.Last.Cells(C).Range.Text) > 20 Then
Debug.Print "Delete rows above"
End If
End With
Next C

How do I check if ticket number is formatted using a function?

I would like my function to follow some convention to check if my ticket number needs formatting or not.
If the convention is not met, then I would like to make some changes to the ticket number.
Ticket number 19K3072216 needs to be formatted to this 19-K3-07-002216 because it does not meet the following conditions.
My function should do the following.
Check if the 1st 2 digits has a value 0 - 9 (numeric)
Check if the 3rd digit has a value of A to Z
Check if the 4th digit has a value 0 - 9 (numeric)
Check if the 5th and 6th digits has a date value (e.g.2 digit year - 17, 90, 15 etc)
Check if the next 6 digits i.e. 7th - 12th digits are numeric.
Because ticket number 19K3072216 does not meet the above conditions, I would like my function to format it to look like this 19-K3-07-002216
The string strTicketNumber should return formatted ticket number 19-K3-07-002216
My vb.net function
Public Class Ticket_Code
Public Shared Sub main()
Dim strTicketNumber As String = FixTicketNumber("19K3072216")
End Sub
Public Shared Function FixCaseNumber(ByVal astrCaseNumber As String) As String
Dim strCaseNumber As String = Replace(astrCaseNumber, "-", "")
'Determine if ticket number is formatted
How do I do this?
'If ticket number is formatted add 2 zeros
'How do I do this?
'Else return unchanged
'If ticket number is already formatted, just returned the number (original number)
Return strCaseNumber
End Function
End Class
It will really depend on your input and how different from the example it can be.
For instance will invalid input always be in the same format 19K3072216or is there the chance it will be all digits, all letters, less/more than 10 characters long etc. All of these rules need to be considered and handled as necessary.
If the input will be from a user, never trust it and always assume it is the furthest from valid as possible. If the app can handle that case it can handle everything else
Something like this should get you started:
Public Sub Main()
Dim strTicketNumber As String = FixTicketNumber("19-K3-07-002216") ' or 19K3072216
Console.WriteLine(strTicketNumber)
Console.ReadKey()
End Sub
Private Function FixTicketNumber(p1 As String) As String
Dim fixed As String = ''
Dim valid As Boolean = checkTicketNumber(p1)
If valid Then
Return p1 ' Ticket number is valid, no transformation needed
Else
'Assume invalid input will always be 10 characters (e.g. 19K3072216)
'Split the input and Step through each rule one at a time
'returning the necessary result/format string as you go
'#1 Check if the 1st 2 digits has a value 0 - 9 (numeric)
Dim ruleOne As String = p1.Substring(0, 2)
'perform isNumeric, concatenate to fixed if everything is ok
'fixed += ruleOne+"-"
'#2 Check if the 3rd digit has a value of A to Z
Dim ruleTwo As String = p1.Substring(3, 1)
'check if its a letter, concatenate to fixed if everything is ok
'... same for all the rules
End If
End Function
Private Function checkTicketNumber(p1 As String) As Boolean
'See if the input matches the rules
'Check if the 1st 2 digits has a value 0 - 9 (numeric)
'Check if the 3rd digit has a value of A to Z
'Check if the 4th digit has a value 0 - 9 (numeric)
'Check if the 5th and 6th digits has a date value (e.g.2 digit year - 17, 90, 15 etc)
'Check if the next 6 digits i.e. 7th - 12th digits are numeric.
Dim pattern As String = "\d{2}-[A-Z]\d-\d{2}-\d{6}"
Dim match As Match = Regex.Match(p1, pattern)
Return match.Success
End Function
It is hard to produce a fully working solution as there are too many unknowns about the input as an outsider.

VBA Split string and convert to Int

I have an Excel sheet where I have data in a column J4:J163, Each cell contains a string e.g. J4 = "1 6, 8 18, 20 24"
Using VBA I want to use the Split function to separate on the delimiter ','
then convert string values e.g. "1 6, 8 18, 20 24" into integers. Which should result into something like this '1 6' '8 18' '20 24'
I want to iterate through each two integer values subtracting like so
1-6 = 5
8-18 = 10
20-24 = 4
Each time adding these results to a variable i.e. 'total'
Depending on how many subtractions have been performed increment a variable, cnt++, in this case 3 times, (total + cnt).
total = 22
This result calculated from cell J4 i.e. 22 should be inputted into L4.
The result from J5 should be inputted into L5 etc.
Hope this makes sense.
Below is a very bare pseudo code, (newbie to VBA) your guidance would be well received.
Sub CalcHrs()
'Variables
Dim wrdArray() As String
Dim textString As String
Dim total As Integer 'substration results accumulation
Dim cnt As Integer 'for loop iteration count
' Grab String
textString = Range("J4")
' Place string into Array and Split
wrdArray() = Split(textString)
'Loop to convert string array to int array
'Some loop (i < array.length, bla bla)
'array index 0 - array index 1 place result into 'total'
'iterate through until length of array is reached, while cnt++
'place result of total + cnt into cell "L4"
'Move onto cell "J5" until "J163"
End Sub
Like somebody writted up. It's not a free "write-my-code" service, You should try yourself and If your code doesn't work then You can post it here to get help.
I will give you some tips:
Split the cell value like this: Split (Cell, ",")
Iterate the array result of this Split with for-each and split each value like this: Split(value, " ")
Add 1 to the normal count and add ABS(cint(value1) - cint(value2)) to the total count. Value1 and Value2 are the values retorned by the second split.

Searching Textfiles for dates

I have created a text file with dates and products bought on that date. I want to read the file when a button is clicked and the return the products bought on the current date only (todays date) into a listbox in VB.net . Any help appreciated.
This is an example of my textfile.
06:35 Sunday, 15 March 2015
Corona Bottle
Miller Bottle
Bulmers Bottle
Beamish Pint
Bacon Fries
Orange Juice
06:41 Sunday, 15 March 2015
Murphy's Pint
Bulmers Pint
Tayto
Purple Snack
This is the code that i have so far:
Private Sub btnTodaysTrans_Click(sender As Object, e As EventArgs) Handles btnTodaysTrans.Click
Dim sr As IO.StreamReader = IO.File.OpenText("ProductsSold.txt")
lstTodaysTrans.Items.Clear()
Do While sr.Peek <> -1
lstTodaysTrans.Items.Add(sr.ReadLine)
Loop
sr.Close()
End Sub
try using the textparser for your operation.it will be like
dim field as string
dim date as datetime
If File.Exists(yourfilename) Then
Using parser As New TextFieldParser(yourfilename)
parser.SetDelimiters(vbTab)
While Not parser.EndOfData
fields = parser.ReadFields()
if IsDate(fields) Then
date= DateTime.ParseExact(fields, "yyyy-MM-dd HH:mm tt", System.Globalization.CultureInfo.InvariantCulture)
if date.value<> your condition Then
'' what you want
else
''what you want
end if
end if
end while
end if
NOTE
Or else You can use the error encountered while converting the text files to datetime as condition for checking if it is a valid date.
First, that is a bad way to store your data. The best way is a database. But even if you use a text-file you could use a better approach. Because the file contains empty line and also different lines belong logically together. So you need to find the date of every product in the previous lines. You could add it to every line, then it's easier.
However, you can use following code which uses LINQ and a loop:
Dim format = "dd MMMM yyyy"
Dim dateProducts As New List(Of Tuple(Of Date, String))
Dim lines = From line In File.ReadLines("ProductsSold.txt")
Where Not String.IsNullOrWhiteSpace(line)
Select line.Trim()
For Each line As String In lines
Dim currentDate As Date
Dim isDateline As Boolean = False
If line.Length >= format.Length AndAlso line.Contains(","c) Then
' try to extract the date...
Dim tokens = line.Split({","c}, StringSplitOptions.RemoveEmptyEntries)
isDateline = Date.TryParseExact(tokens.Last().Trim(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, currentDate)
End If
If isDateline Then
dateProducts.Add(New Tuple(Of Date, String)(currentDate, Nothing))
ElseIf dateProducts.Count > 0 Then
' select date from last item and add this product
dateProducts.Add(New Tuple(Of Date, String)(dateProducts.Last().Item1, line))
Else
' otherwise invalid data, product without date, skip
End If
Next
Now you could use ToLookup to create something similar to a dictionary, the key is the date(without time) and the value is the list of products for that date. One difference to a dictionary is that you get an empty sequence if there is no product for a given date.
Dim dateLookup = dateProducts.
Where(Function(ds) ds.Item2 IsNot Nothing).
ToLookup(Function(ds) ds.Item1.Date)
Dim allProductsOfToday = dateLookup(Date.Today)
For Each dateProductInfo In allProductsOfToday
lstTodaysTrans.Items.Add(dateProductInfo.Item2) ' Item2 is the product
Next
I have tested it with your sample file which doesn't contain products for today, so it's not the best example. If you change one of both date from 15 March 2015 to 16 March 2015 you see the appropriate products in the ListBox.

how to convert the string to date in vb.net

I AM FACING ONE PROBLEM.
I AM USING BELOW METHOD FOR MAKING STRING VALUE TO DATE.
string values is like this ="01/12/2002" like "dd/MM/YYYY"
My problem is that.
two string values
->1)01/01/2025
->2)1/1/2025
i am getting the Value like above 1 or 2
Dim d As Date = DateTime.ParseExact(dumm, "dd/MM/yyyy", Nothing)
if 1 comes nothing will happen but
if i get 2 i am facing error like String was not recognized as a valid DateTime.
As per my Analysts what i understood is date should be 2 digits Remaining all are two digits other wise giving the error.
but some times i am getting single digits from the excel to vb.net
how can i solve this issue...
Dim dumm As String = DtSet3.Tables(0).Rows(k + 0).Item(3).ToString
Dim d As Date = DateTime.ParseExact(dumm, "d/M/yyyy", Nothing)
i put the break point on dumm ok dumm vlaues= "1/2/2026 12:00:00 Am"
Error...............
now
Dim dumm As String = DtSet3.Tables(0).Rows(k + 0).Item(3).ToString
Dim d As Date = DateTime.ParseExact("01/02/2026", "dd/MM/yyyy", Nothing)
Working Fine.......
Use the date format string "d/M/yyyy h:m:s tt". This will handle both cases i.e. with and without leading zero for the day and month. Additionally, since your actual variable has a time component in addition to the date, you need to add the format string for parsing time as well.
However, I would advise you to use TryParseExact, which will return boolean values based on success or failure of the parse rather than throwing exceptions.
Demo for using TryParseExact along with appropriate format string.