I have two lines of text which have long space (more like 14-15 spaces) before the actual text. I have tried simple replace to split and merge but nothing is working. I have also tried trim and the worst thing is that ASCII gives code of 32. But nothing works. Here is the text :
your heartburn symptoms
Certain foods, such as fat, chocolate, caffeine and alcohol can aggravate heartburn symptoms 1
Certain foods
(BTW it's not like it looks it is. In my actual richtextbox, when I select the space it gets selected as one big piece of space like a tab and i have also tried replacing vbtab but no use)
What I want is :
your heartburn symptoms
Certain foods, such as fat, chocolate, caffeine and alcohol can aggravate heartburn symptoms 1
Certain foods
Believe me I have tried almost 7-8 diffferent function but now I am going mad. Some of my logic :
Dim lineArray As String() = rtfArticle.Lines
For z As Integer = 0 To lineArray.Length - 1
Dim w As String() = lineArray(z).Split(" ")
MsgBox(lineArray(z))
Dim tmp As String = ""
For Each s34 As String In w
If (s34 <> " ") Then
temp = temp & " " & s34
End If
Next
lineArray(z) = temp
Next
It completely messes up the code. Any idea about this?
You could try:
Dim lineArray As String() = rtfArticle.Lines
For z As Integer = 0 To lineArray.Length - 1
lineArray(z) = lineArray(z).Trim()
Next
MSDN for Trim() says:
Removes all leading and trailing white-space characters from the
current String object.
Related
I have a bunch of different sets of engineering measurements in the format:
77.170 (+/- 0.025)
And I need to split it into the first number, which is the nominal value, and the number in the parenthesis, the tolerance. Not sure exactly how to do this in excel VBA. I was thinking I would use the Split function with a space delimiter, giving me the first number, then the unnecessary characters, then the tolerance, but the tolerance will include a parenthesis. How could I get rid of just that parenthesis, and will what I just suggested even work? Thanks!
Consider:
Sub dural()
s = "77.170 (+/- 0.025)"
s2 = Replace(Replace(Replace(s, " ", ""), "+/-", ""), ")", "")
ary = Split(s2, "(")
MsgBox ary(0) & vbCrLf & ary(1)
End Sub
Use Text to Columns and a formula.
Go to Data--->Text to Columns. Choose delimited and choose Space as your delimiter. This should split the text string into something like:
ColA |ColB|ColC
77.170|(+/-|0.025)
Column C is a bit funky, so let's just grab everything but the last character.
In column D put this:
=LEFT(C1,LEN(C1)-1)
Finally, you should get:
ColA |ColB |ColC |ColD |
77.170|(+/- |0.025)|0.025|
I would use a combination of instr() and mid to get what you need. For example
measurments="77.170 (+/- 0.025)"
mid(measurements,1,instr(measurements," "))
trim(mid(measurements,instr(measurements,"-")+1,instr(measurements,")")-instr(measurements,"-")-1))
or, to combine,
measurments="77.170 (+/- 0.025)"
mid(measurements,1,instr(measurements," ")) & " " & trim(mid(measurements,instr(measurements,"-")+1,instr(measurements,")")-instr(measurements,"-")-1))
Try using a combination of InStr(), Left(), Right().
Get the index/position of the '(' using InStr and then extract the characters using Left and Right. If you want to get the final data as a double or a Long use CDbl() or CLng() respectively.
For getting text out of other text consider using Regular Expresions.
To use them in VBA you will need in Reference 'VBScript_RegExp_55' library.
The reason why you might want to do that is because following code returns whatever first two numbers show up in your text( it can be modified to be much smarter than that), regardless of other text around it.
Dim Regex As RegExp
Dim Matches As MatchCollection
Set Regex = New RegExp
Regex.Pattern = "\d*\.\d*"
Regex.Global = True
Set Matches = Regex.Execute("77.170 (+/- 0.025)")
MsgBox (Matches(0).Value & " " & Matches(1).Value)
Assuming s is your measurement string, here is the most direct way:
v = Split(Left(s, Len(s) - 1), " (+/- ")
That's it. Now v(0) holds the nominal value and v(1) holds the tolerance.
I have this data in Excel:
But one of my clients needs it summarize per item in detail.
So above data needs to be converted to:
This way, client can analyze it per tracking and per item.
The text format is not really uniform since it is entered manually.
Some users use Alt+Enter to separate items. Some uses space and some doesn't bother separating at all. What's consistent though is that they put hyphen(-) after the item then the count (although not always followed by the number, there can be spaces in between). Also if the count of that item is one(1), they don't bother putting it at all (as seen on the tracking IDU3004 for Apple Juice).
The only function I tried is the Split function which brings me closer to what I want.
But I am still having a hard time separating the individual array elements into what I expect.
So for example, IDU3001 in above after using Split (with "-" as delimiter) will be:
arr(0) = "Apple"
arr(1) = "20 Grape"
arr(2) = "5" & Chr(10) & "Pear" ~~> Just to show Alt+Enter
arr(3) = "3Banana"
arr(4) = "2"
Of course I can come up with a function to deal with each of the elements to extract numbers and items.
Actually I was thinking of using just that function and skip the Split altogether.
I was just curious that maybe there is another way out there since I am not well versed in Text manipulation. I would appreciate any idea that would point me to a possible better solution.
I suggest using a Regular Expression approach
Here's a demo based on your sample data.
Sub Demo()
Dim re As RegExp
Dim rMC As MatchCollection
Dim rM As Match
Dim rng As Range
Dim rw As Range
Dim Detail As String
' replace with the usual logic to get the range of interest
Set rng = [A2:C2]
Set re = New RegExp
re.Global = True
re.IgnoreCase = True
re.Pattern = "([a-z ]+[a-z])\s*\-\s*(\d+)\s*"
For Each rw In rng.Rows
' remove line breaks and leading/trailing spaces
Detail = Trim$(Replace(rw.Cells(1, 3).Value, Chr(10), vbNullString))
If Not Detail Like "*#" Then
' Last item has no - #, so add -1
Detail = Detail & "-1"
End If
' Break up string
If re.Test(Detail) Then
Set rMC = re.Execute(Detail)
For Each rM In rMC
' output Items and Qty's to Immediate window
Debug.Print rM.SubMatches(0), rM.SubMatches(1)
Next
End If
Next
End Sub
Based on your comment I haved assumed that only the last item in a cell may be missing a -#
Sample input
Apple Juice- 20 Grape -5
pear- 3Banana-2Orange
Produces this output
Apple Juice 20
Grape 5
pear 3
Banana 2
Orange 1
I have a text file that reads:
Left Behind,Lahaye,F,7,11.25
A Tale of Two Cities,Dickens,F,100,8.24
Hang a Thousand Trees with Ribbons,Rinaldi,F,30,16.79
Saffy's Angel,McKay,F,20,8.22
Each Little Bird that Sings,Wiles,F,10,7.70
Abiding in Christ,Murray,N,3,12.20
Bible Prophecy,Lahaye and Hindson,N,5,14.95
Captivating,Eldredge,N,12,16
Growing Deep in the Christian Life,Swindoll,N,11,19.95
Prayers that Heal the Heart,Virkler,N,4,12.00
Grow in Grace,Ferguson,N,3,11.95
The Good and Beautiful God,Smith,N,7,11.75
Victory Over the Darkness,Anderson,N,12,16
The last element of each line is a price. I would like to add up all the prices. I've been searching for so many hours now and cannot find a thing to answer my question. This seems soooo easy but I cannot figure it out!!! Please help out. BTW, this list is bound to change (adding of lines, deletion of lines, altering of lines) so if you can, please nothing concrete but instead leave the code open to changes. Thanks!!!
Just so you can see my pooooorrrr work, here is what I have (I think I deleted my code and rewrote a different way for several hours now.):
Dim Inv() As String = IO.File.ReadAllLines("Books.txt")
Dim t As Integer = Inv.Count - 1
Dim a As Integer = 0 to t
Dim sumtotal As String = sumtotal + Inv(4)
also,
for each line has either an "F" or an "N". how do I add up all the F's and all the N's. Do I do it via if statements?
First, you'll be better off using Double as your type instead of String. Second, observe how I use the Split function on each line, cast its last element as a double, and add it to the total. Yes, using an If Statement is how you can determine whether or not to add to the count of F or the count of N.
Dim lstAllLines As List(Of String) = IO.File.ReadAllLines("Books.txt").ToList()
Dim dblTotal As Double = 0.0
Dim intCountOfF As Integer = 0
Dim intCountOfN As Integer = 0
For Each strLine As String In lstAllLines
Dim lstCells As List(Of String) = strLine.Split(",").ToList()
dblTotal += CDbl(lstCells(3))
If lstCells(2) = "F" Then
intCountOfF += 1
Else
intCountOfN += 1
End If
Next
I am new to VB.Net 2008. I have a tricky task to resolve, it is regarding extracting characters (values) from a long string, the extracted values from the text shall be summed up and sorted by keywords, reformatted and saved into a CSV file.
It looks something like this but much longer :
UNH+RAM6957'COMPANY1BY500C10'ZEW+REQEST6957'COMPANY2SL200C20'COMPANY1SL300C10'ZEW
The values are seperated by ' .
As first step I splitted the string to make it readable, I used the function like:
Dim LineOfText As String
Dim i As Integer
Dim aryTextFile() As String
LineOfText = p_EDI
aryTextFile = LineOfText.Split("'")
For i = 0 To UBound(aryTextFile)
Console.WriteLine((aryTextFile(i)))
Next i
Now the result looks like:
UNB+UNOA:1+CCP:ZEW+STE:ZEW+100901:1200+2010917283
UNH+M000001+ORDRSP:D:96A:UN:EGT102
BGM+02G::ZEW+NOMRES24364+34
DTM+Z05:0:805
DTM+137:201009011000:203
DTM+Z01:201009090400201009100400:719
RFF+AHI:GSCOMPANY1
NAD+ZSO+CCP::ZEW
NAD+ZSH+GSSTATKRAFT::ZEW
TDT+41G++70
LOC+Z11+:::TTF
LIN+1+23
LOC+Z11+:::TTF
QTY+Z05:0:KW1
DTM+2:201009090400201009100400:719
NAD+ZUS+GSBNP::ZEW
LIN+2+23
LOC+Z11+:::TTF
QTY+Z05:0:KW1
DTM+2:201009090400201009100400:719
NAD+ZUS+GSBPA::ZEW
So far so good:
Now I have to extract the date and time from the header:
The line looks like:
**DTM+137**:201009011000:203 should look like
DTM+137:2010.09.01-10:00:203 and store it into a 'incomming_DTM' variable for example
Now the message period would be interresting to know:
The line looke like:
**DTM+Z01**:201009090400201009100400:719 the output should look like:
DTM+Z01 2010.09.09-04:00, 2010.09.10-04:00 and store it into 'period_DTM' variable
As next step I need to parse the next lines until it reaches the KEYWORD LIN
Like:
LIN+1+23
LOC+Z11+:::TTF
QTY+Z05:0:KW1
DTM+2:201009090400201009100400:719
NAD+ZUS+GSBNP::ZEW
NAD+ZSH+COMPANY1RPH N001::ZEW (P Character in word -> SELL QTY:0 KW/h)
LIN+2+23
LOC+Z11+:::TTF
QTY+Z05:0:KW1
DTM+2:201009090400201009100400:719
NAD+ZUS+GSBPA::ZEW
NAD+ZSH+COMPANY1RRH N001::ZEW (R Character in word -> BUY QTY:0 KW/h)
and store the KEYWORDS "QTY" "DTM" "NAD+ZSH" and its following Characters
into variables.
THEN I need to parse until it reaches the next LIN Keyword and store the
keywords there into vaiables again. The goal of this complicated exercise is,
to sum up values of QTY and NAD+ZSH+COMPANY1RVH and NAD+ZSH+COMPANY1RPH
If we have a closer look at the last zwo charaters in COMPANY1RRH and COMPANY1RPH
we see RH and PH, RH means buy and PH means sell.
Maybe it is possible to store BUY or SELL into a Contract vaiable for each LIN?
I need to sum up all sells and buys which where found in the string.
Every LIN marks a time period of one hour, so we have probably 24 series per
string which contains 24 LIN every LIN have a Time period, BUY or SELL keywords
and a Quantity.
Can someone please help me with this task?
As first step, storing the keywords and its follwoing characters into variables would
be a very good start. It might be very good to do that probably until the parser reaches the LIN, then store the found values into a CSV file or Array?, then parse until the next LIN and so on...
I would like to create a CSV file out of the results like: So the CSV should contain
24 records one per every hour per every LIN..
Dim csvData = Now & "," & "TRADED_QTY" & "," & DTM+Z01 & "," & "N" & "," & QTY & "," & "KWH/h" & "," & Contract
Console.WriteLine(csvData)
Creating the CSV File with True Flag -> Append data to CSV.
Dim csvFile As String = "C:\Test.csv"
Dim outFile As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(csvFile, True)
Any ideas are highly welcome, I consider this as very complex task
espacial as I am really new to VB.NET.
Thank you in advance!
I see "EDI" in your code. If this is an EDI format, then you should have, or be able to get, some kind of EDI specification. Likely, it will be a fixed-length specification, meaning that "Value X is characters 1 to 9", "Value Y is characters 10 to 11", "Value Z is character 12", etc.
Here is one possible approach to parse out the KEYWORDS as first step:
Dim EDI As Object
EDI = dataReader(0)
'Convert EDI Object into a string and write it to the console.
Dim p_EDI As String = Convert.ToString(EDI)
'Create LineBreaks after every " ' "
Dim LineOfText As String
Dim i As Integer
Dim aryTextFile() As String
LineOfText = p_EDI
aryTextFile = LineOfText.Split("'")
'Starting with IF clause to find keywords
For Each line As String In aryTextFile
Console.WriteLine(line)
If line.StartsWith("UNB") Then
Dim foundUNB_Data = p_EDI.IndexOf("UNB")
'Start at that position and extract UNB + 27 characters
Dim UNBData = EDI.Substring(foundUNB_Data, 30)
Console.WriteLine(UNBData)
ElseIf line.StartsWith("LIN") Then
.
.
ElseIf line.StartsWith("QTY") Then
.
.
End If
Next
Any further ideas are highly welcome..
Thank you.
I have the following code to generate combinations of string for a small list and would like to adapt this for a large list of over 300 string words.Can anyone suggest how to alter this code or to use a different method.
Public Class combinations
Public Shared Sub main()
Dim myAnimals As String = "cat dog horse ape hen mouse"
Dim myAnimalCombinations As String() = BuildCombinations(myAnimals)
For Each combination As String In myAnimalCombinations
''//Look on the Output Tab for the results!
Console.WriteLine("(" & combination & ")")
Next combination
Console.ReadLine()
End Sub
Public Shared Function BuildCombinations(ByVal inputString As String) As String()
''//Separate the sentence into useable words.
Dim wordsArray As String() = inputString.Split(" ".ToCharArray)
''//A plase to store the results as we build them
Dim returnArray() As String = New String() {""}
''//The 'combination level' that we're up to
Dim wordDistance As Integer = 1
''//Go through all the combination levels...
For wordDistance = 1 To wordsArray.GetUpperBound(0)
''//Go through all the words at this combination level...
For wordIndex As Integer = 0 To wordsArray.GetUpperBound(0) - wordDistance
''//Get the first word of this combination level
Dim combination As New System.Text.StringBuilder(wordsArray(wordIndex))
''//And all all the remaining words a this combination level
For combinationIndex As Integer = 1 To wordDistance
combination.Append(" " & wordsArray(wordIndex + combinationIndex))
Next combinationIndex
''//Add this combination to the results
returnArray(returnArray.GetUpperBound(0)) = combination.ToString
''//Add a new row to the results, ready for the next combination
ReDim Preserve returnArray(returnArray.GetUpperBound(0) + 1)
Next wordIndex
Next wordDistance
''//Get rid of the last, blank row.
ReDim Preserve returnArray(returnArray.GetUpperBound(0) - 1)
''//Return combinations to the calling method.
Return returnArray
End Function
End Class
'
CHANGES//
For wordDistance = 1 To inputList.Count.ToString / 2
Dim count = inputList.Count.ToString
'Go through all the words at this combination level...
For wordIndex As Integer = 0 To inputList.Count.ToString - wordDistance
'Get the first word of this combination level
combination.Add(inputList.Item(wordIndex))
'And all all the remaining words a this combination level
For combinationIndex As Integer = 1 To wordDistance
combination.Add(" " & inputList.Item(wordIndex + combinationIndex))
Next combinationIndex
'Add this combination to the results
If Not wordsList.Contains(combination) Then
wordsList.Add(combination.ToString)
End If
'Add a new row to the results, ready for the next combination
'ReDim Preserve returnArray(returnArray.GetUpperBound(0) + 1)
Next wordIndex
Next wordDistance
One obvious thing in your code is the usage of ReDim Preserve. That can be quite a slow operation since I think it copies the whole array into a new array every time the size is changed, and since you're doing that inside loops I assume that could be a significant issue.
The simplest way of fixing that is to stop using those kinds of arrays and instead use List with it's Add method.
I want to make sure I understand what you are trying to do first. Your problem seems to be:
Given a list of strings,
Return every possible combination of n items from the list,
where n = 2 to length of list
For example, in a list of 5 strings, you would want all combinations of 2 strings, of 3 strings, of 4 strings, and of 5 strings.
If that is an accurate statement of your problem, there is one glaring issue to point out. The number of items you will be generating is on the order of 2 ^ (length of list). This means that trying to generate all combinations of 300 items will never be fast no matter what. Also, for any but the tiniest of lists, you will need to generate items lazily or you will run out of memory.
If you do not want all combinations of all lengths, you may want to clarify your question to better state your desired goal.