Dim files = From file In Directory.EnumerateFiles(txtFolder.Text, txtType.Text, SearchOption.AllDirectories)
From line In System.IO.File.ReadLines(file) Where line.Contains(txtFindWhat.Text) Select New With {file, line}
For Each f In files
Dim item As New ListViewItem($"{f.file}") 'First Column File Localtion
item.SubItems.Add($"{f}") 'Second Column Add The line number where found the text
item.SubItems.Add($"{f.line}") 'Third Column Text Search
ListView1.Items.Add(item) 'Add Records
Next
Question::
How to display the line number where it was found in the file in the second column?
Example: Test.txt contains:
asdasd
Testa
Geter
Better
So I search for text "Better" and display in Column 2 that it was found at line 4 in file.
I think you tried to do too much in a single line. I broke it down into two steps. Remember Linq is doing the loops behind the scenes so it really shouldn't slow down your code.
What will slow down your code is updating the user interface in a loop. I accumulated the ListViewItems in a list and then added them all at once after the loop.
The line number was determined by adding a line counter. It is incremented inside the inner loop and reset to 1 for each file in the outer loop. Since humans start counting at 1 that is what I used rather than the computer's counting system that starts with 0.
Private Sub OPCode()
Dim files = Directory.EnumerateFiles(txtFolder.Text, txtType.Text, SearchOption.AllDirectories)
Dim lst As New List(Of ListViewItem)
For Each f In files
Dim lineNumber As Integer = 1
Dim lines = File.ReadAllLines(f)
For Each line In lines
If line.Contains(txtFindWhat.Text) Then
Dim li As New ListViewItem(f)
li.SubItems.Add(lineNumber.ToString)
li.SubItems.Add(line)
lst.Add(li)
End If
lineNumber += 1
Next
Next
ListView1.Items.AddRange(lst.ToArray)
End Sub
Related
I have to dim n variables in my software, where n is a number that user types in the interface. I'd start with a for loop, in order to declare these variables, with something like:
for i = 0 to n
dim r.i as IRow = worksheet.CreateRow(i)
next
This is what I think but obviously I know that's wrong. Does anyone knows if this is possible? I can't create neither List(Of) nor arrays because these are rows of an excel file I'm trying to export, otherwise NPOI returns me error.
What does Excel have anything to do with not using a List? You can absolutely use worksheet.CreateRow() with a list:
Dim rows As New List(Of IRow)
For i As Integer = 0 to n - 1
rows.Add(worksheet.CreateRow(i))
Next
Now the name of each row is row(0), row(1), row(2) ... row(n - 1)
If you've tried this and NPOI is giving you an error, you should show that code around where the error is thrown and tell us what the error is.
Based on comments:
'Assuming everything has the same number of entries as ListBox1, per the comments
Dim rows As New List(Of IRow)
Dim row As IRow = worksheet.CreateRow(0)
row.CreateCell(0).SetCellValue("Time")
row.CreateCell(1).SetCellValue("hrr")
For i As Integer = 0 To ListBox1.Items.Count - 1
row = worksheet.CreateRow(i+1)
row.CreateCell(0).SetCellValue(ListBox1.Items(i))
row.CreateCell(1).SetCellValue(ListBox2.Items(i))
rows.Add(row)
Next i
is there a way to count the amount of lines before a specific line / string in a text file.
For Example:
1
2
3
4
5
6
7
8
9
Say i want to count the amount of line before '8'...
How would i do that?
thanks!
Hope that this actually you are looking for,
it will read all lines from a file specified. then find the IndexOf particular line(searchText) then add 1 to it will gives you the required count since index is0based.
Dim lines = File.ReadAllLines("f:\sample.txt")
Dim searchText As String = "8"
msgbox(Array.IndexOf(lines, searchText) + 1)
Here's another example using List.FindIndex(), which allows you to pass in a Predicate(T) to define how to make a match:
Dim fileName As String = "C:\Users\mikes\Documents\SomeFile.txt"
Dim lines As New List(Of String)(File.ReadAllLines(fileName))
Dim index As Integer = lines.FindIndex(Function(x) x.Equals("8"))
MessageBox.Show(index)
In the example above, we're looking for an exact match with "8", but you can make the predicate match whatever you like for more complex scenarios. Just make the function (the predicate) return True for what you want to be a match.
For example, a line containing "magic":
Function(x) x.ToLower().Contains("magic")
or a line that begins with a "FirstStep":
Function(x) x.StartsWith("FirstStep")
The predicate doesn't have to be a simple string function, it can be as complex as you like. Here's one that will find a string that ends with "UnicornFarts", but only on Wednesday and if Notepad is currently open:
Function(x) DateTime.Today.DayOfWeek = DayOfWeek.Wednesday AndAlso Process.GetProcessesByName("notepad").Length > 0 AndAlso x.EndsWith("UnicornFarts")
You get the idea...
Using a List, instead of an Array, is good for situations when you need to delete and/or insert lines into the contents before writing them back out to the file.
My text data file is like this:
{1000}xxx{1200}xxx{3000}xxxxxx{5000}
{1000}xx{1500}xxxxxx{4000}xx{6000}
{1000}xxxx{1600}xxx{3000}xxx{6000}
...
I need to convert this data file to csv file or excel file to analyze. I tried Excel or other convert software. But it is not working.
Can I use VB to do that? I did not use VB for a long time (over 10 years).
I am sorry. I did not make it clear.
The number in curly brackets is the field name. Each record doesn't have same field. The result after converted should be like this:
(header line) 1000 1200 1500 1600 3000 4000 5000 6000
(record line) xxx xxx xxx xxx
. xxx xxx xxx xxx
. xxx xxx xxx xxx
We have the text data file everyday (10 - 20 records). Although data is not big, we don't need to re-type to excel file if we can convert to csv file. This can help us lot of time.
You almost definitely could use a programming language (like VB) to make this change. I'm not sure you need to do that though.
If you are trying to write a program to convert the same type of file over and over, it might make sense to build a program in VB.net.
FYI, its hard to help advise you further without understanding more about what you need to do? For example, the size of the file, how often you will need to do it, what the target format will be, etc...
... but the answer I provided did answer the question you asked! ... and I am seeking rep points ;)
In light of your explanation of how the data is structured:
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions
Module Module1
Class Cell
Property ColumnName As String
Property Value As String
' To help with debugging/general usage
Public Overrides Function ToString() As String
Return String.Format("Col: {0} Val: {1}", ColumnName, Value)
End Function
End Class
Dim table As New List(Of List(Of Cell))
Sub Main()
Dim src As String = "C:\temp\sampledata.txt"
Dim dest = "C:\temp\sampledata.csv"
Dim colNames As New List(Of String)
' This regex will look for zero or more characters ".*" surrounded by braces "\{ \}" and
' collect the zero or more characters in a group "( )". The "?" makes it non-greedy.
' The second capture group "( )" gets all the characters up to but not including
' the next "\{" (if it is present).
Dim cellSelector = New Regex("\{(.*?)\}([^\{]*)")
' Read in the cells and record the column names.
Using inFile = New StreamReader(src)
While Not inFile.EndOfStream
Dim line = inFile.ReadLine
Dim rowContent As New List(Of Cell)
For Each m As Match In cellSelector.Matches(line)
rowContent.Add(New Cell With {.ColumnName = m.Groups(1).Value, .Value = m.Groups(2).Value})
If Not colNames.Contains(m.Groups(1).Value) Then
colNames.Add(m.Groups(1).Value)
End If
Next
table.Add(rowContent.OrderBy(Function(c) c.ColumnName).ToList)
End While
End Using
colNames.Sort()
' add the header row of the column names
Dim sb As New StringBuilder(String.Join(",", colNames) & vbCrLf)
' output the data in csv format
For Each r In table
Dim col = 0
Dim cellNo = 0
While cellNo < r.Count AndAlso col < colNames.Count
' If this row has a cell with the appropriate column name then
' add the value to the output.
If r(cellNo).ColumnName = colNames(col) Then
sb.Append(r(cellNo).Value)
cellNo += 1
End If
' add a separator if is not the last item in the row
If col < colNames.Count - 1 Then
sb.Append(","c)
End If
col += 1
End While
sb.AppendLine()
Next
File.WriteAllText(dest, sb.ToString)
End Sub
End Module
From your sample data, the output is
1000,1200,1500,1600,3000,4000,5000,6000
xxx,xxx,,,xxxxxx,,,
xx,,xxxxxx,,,xx,,,
xxxx,,,xxx,xxx,,,,
I notice that none of the final columns have data in them. Is that just a copy-and-paste error or intentional?
EDIT: I use Option Infer On, which is why some of the type declarations are missing.
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
Ive searched over and over the internet for my issue but I havent been able to find / word my searches correctly...
My issue here is that I have a Comma Separated value file in .txt format... simply put, its a bunch of data delimited by commas and text qualifier is separated with ""
For example:
"So and so","1234","Blah Blah", "Foo","Bar","","","",""
"foofoo","barbar","etc.."
Where ever there is a carriage return it signifies a new row and every comma separates a new column from another.
My next step is to go into VB.net and create an array using these values and having the commas serve as the delimeter and somehow making the array into a table where the text files' format matches the array (i hope im explaining myself correctly :/ )
After that array has been created, I need to select only certain parts of that array and store the value into a variable for later use....
Andthats where my trouble comes in... I cant seem to get the correct logic as to how to make the array and selecting the certain info out of it..
If any
You might perhaps give a more detailed problem description, but I gather you're looking for something like this:
Sub Main()
Dim fileOne As String = "a1,b1,c1,d1,e1,f1,g1" + Environment.NewLine + _
"a2,b2,c2,d2,e2,f2,g2"
Dim table As New List(Of List(Of String))
' Process the file
For Each line As String In fileOne.Split(Environment.NewLine)
Dim row As New List(Of String)
For Each value In line.Split(",")
row.Add(value)
Next
table.Add(row)
Next
' Search the "table" using LINQ (for example)
Dim v = From c In table _
Where c(2) = "c1"
Console.WriteLine("Rows containing 'c1' in the 3rd column:")
For Each x As List(Of String) In v
Console.WriteLine(x(0)) ' printing the 1st column only
Next
' *** EDIT: added this after clarification
' Fetch value in row 2, column 3 (remember that lists are zero-indexed)
Console.WriteLine("Value of (2, 3): " + table(1)(2))
End Sub