Problems reading a whole line from textfile - excel

I have a program that reads lines of text (some 3000-4000 lines) from a textfile (saved with UTF from Notes). Each line consists of about 300-900 characters. I used this function:
Function loadVerbs2(fullPathName As String) As String()
Dim strings(0 To 5000) As String
Dim my_file As Integer
Dim text_line As String
Dim stringNr As Integer
my_file = FreeFile()
Open fullPathName For Input As my_file
stringNr = 0
While Not EOF(my_file)
Line Input #my_file, text_line
'Cut preceding "
While ((Asc(Left$(text_line, 1)) < Asc("a")) Or (Asc(Left$(text_line, 1)) > Asc("z")))
text_line = Mid$(text_line, 2)
Wend
' Cut ending " and ,
While ((Right$(text_line, 1) = Chr$(34)) Or (Right$(text_line, 1) = ","))
text_line = Left$(text_line, Len(text_line) - 1)
Wend
strings(stringNr) = latinCharacter(text_line)
stringNr = stringNr + 1
Wend
Close #my_file
loadVerbs2 = strings
End Function
For some reason the function doesn't read the whole line, but cut them.
So I changed it to this:
Function loadVerbs(fullPathName As String) As String()
Dim strings(0 To 5000) As String
Dim text_line As String
Dim stringNr As Integer
Dim fso As New FileSystemObject
Dim ts As TextStream
Set ts = fso.OpenTextFile(fullPathName)
Do While Not ts.AtEndOfStream
text_line = ts.ReadLine
'Cut preceding "
While ((Asc(Left$(text_line, 1)) < Asc("a")) Or (Asc(Left$(text_line, 1)) > Asc("z")))
text_line = Mid$(text_line, 2)
Wend
' Cut ending " and ,
While ((Right$(text_line, 1) = Chr$(34)) Or (Right$(text_line, 1) = ","))
text_line = Left$(text_line, Len(text_line) - 1)
Wend
strings(stringNr) = latinCharacter(text_line)
stringNr = stringNr + 1
Loop
ts.Close
loadVerbs = strings
End Function
But with the same result. There are some characters like this in the text: á í é ó à ò ì è â û î ñ ç which makes it neceserry for this "latinCharacter" function to convert them so I can put them on a spreadsheet. But these characters does not stop the ReadLine or Line Input from reading the entire line.
Any suggestions??

I think it's better to use an ADO Stream. One advantage is the possibility to set the right charset.
For infos to ADO Stream look here
Here is a demo for you with the relevant parameters for text imports and what they stand for:
Sub AdoStreamDemo()
Dim importPath As String
Dim importFileName As String
Dim objStream As Object
Dim lineOfTextFile As String
importPath = "D:\Your Folder\" 'Don't forget the bakslash (\) at the end
importFileName = "Your File.xxx" 'Filename with extension
'Initialise ADO Stream
Set objStream = CreateObject("ADODB.Stream")
objStream.Charset = "utf-8" 'default is Unicode
objStream.Type = 2 '2 = Text, 1 = Binary
objStream.LineSeparator = -1 '-1 = adCrLf (default), 13 = adCr, 10 = adLf
objStream.Open 'Opens the stream
objStream.LoadFromFile importPath & importFileName 'Path with backslash (\) at the end and filename
Do Until objStream.EOS 'EOS = End Of Stream
lineOfTextFile = objStream.ReadText(-2) '-2 = one row, -1 = all
'Do here what you want to do with every line of text from the file
Debug.Print lineOfTextFile
'Next line
Loop
objStream.Close 'Closes the stream
End Sub

Ok, problem solved! The easy answer is that there wasn't any problem. When you run the Microsoft Visual Basic for Application debugger and show the local variables window the debugger doesn't show the whole length of the strings. So the program works but it looks like it doesn't in the debugger.

Related

VBA Object with variable or block variable not set error even when is already set

I am currently trying to set conditions such that when a CSV file is not found in the folder, it will continue to find other CSV files. However I'm facing the "object with variable or block variable not set" error at the 2nd private sub readdatavcap2 even when I've already set Set o_file = fs2.OpenTextFile for both 1st and 2nd sub. I'm confused because for the 1st sub, the error does not occurs at o_file.Close after the else statement while for 2nd sub it occurs. Does anybody knows why?
Private Sub readdatavcap1(filename As String, i As Integer)
Application.ScreenUpdating = False
Dim sl As String
Dim first As Integer
Dim second As Integer
Dim j As Long
Dim fs2 As New Scripting.FileSystemObject
Dim o_file As Scripting.TextStream
j = 2 'variable not defined at fs2
If Dir(filename) <> "" Then
Set fs2 = CreateObject("Scripting.FileSystemObject") 'FileSystemObject also called as FSO, provides an easy object based model to access computer's file system.
'o_file contains filename(csv file link)
Set o_file = fs2.OpenTextFile(filename, 1, TristateFalse) '1=Open a file for reading only. You can't write to this file. TristateFalse means u get ascii file by default
'2=ForWriting, 8= Forappending
'o_file contains filename(text file data)
sl = o_file.readline 'Reads an entire line (up to, but not including, the newline character) from a TextStream file and returns the resulting string.
Do While Left(sl, 1) = "#" 'Left Function is used to extract N number of characters from a string from the left side.
sl = o_file.readline
Loop
Do While o_file.atendofstream <> True 'atendofstream = Read-only property that returns True if the file pointer is at the end of a TextStream file; False if it is not.
sl = o_file.readline
first = InStr(32, sl, ",", 1) - 15 'INSTR function returns the position of the first occurrence of a substring in a string.
second = InStr(first + 2, sl, ",", 1) 'syntax of InStr( [start], string, substring, [compare] )
'start sets string position for each search, string = string being search, substring= string expression searched ,
'eg:InStr(1, "Tech on the Net", "t") Result: 9 'Shows that search is case-sensitive
'compare= optional 1= textcompare
'searching for commas in the file in this case
If second = 0 Then
second = Len(sl) + 1 'len=length of file string
End If
If tddb_vramp = True Then
' write the Voltage Ramp to stress part
If i = 2 Then
ActiveWorkbook.Sheets("Ramp_current").Cells(j, 1) = Mid(sl, 2, first - 2)
End If
ActiveWorkbook.Sheets("Ramp_current").Cells(j, i) = Abs(Mid(sl, first + 2, second - 2 - first)) + 0.000000000000001
Else
'Write the normal current trace
ActiveWorkbook.Sheets("currentPTN_STI").Cells(j, 2 * i - 3) = Mid(sl, 15, first - 14)
' The MID function returns the specified number of characters in a text string, starting from a specified position (
'ie. starting from a specified character number).
'Use this function to extract a sub-string from any part of a text string. Syntax: MID(text_string, start_number, char_numbers).
ActiveWorkbook.Sheets("currentPTN_STI").Cells(j, 2 * i - 2) = Abs(Mid(sl, first + 2, second - 2 - first)) + 0.000000000000001
End If
j = j + 1
Loop
If tddb_vramp = False Then
myarray(i) = j - 1
End If
o_file.Close
Else
o_file.Close
End If
End Sub
Private Sub readdatavcap2(filename As String, i As Integer)
(rest of the code same as readdatavcap1)
.
.
.
o_file.Close
Else
o_file.Close <---error occurs here
End If
End Sub
I worked my way through your code but can't do more than confirm what GSerg already said in his first comment, i.e. you can't close a file that isn't open.
Option Explicit
Sub Main()
Dim SourceFolder As String
Dim Fn As String ' Filoe name
Dim i As Integer
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = -1 Then ' if OK is pressed
SourceFolder = .SelectedItems(1)
End If
End With
If SourceFolder <> "" Then ' a folder was chosen
i = 2
Fn = Dir(SourceFolder & "\*.csv")
Do While Len(Fn) > 0
readdatavcap1 Fn, i
Fn = Dir
Loop
End If
End Sub
Private Sub readdatavcap1(filename As String, i As Integer)
' "filename" is a variable used by VBA
' your use of it may cause unexpected problems.
' to check, select the name and press F1.
Dim sl As String
Dim first As Integer
Dim second As Integer
Dim j As Long
Dim fs2 As New Scripting.FileSystemObject
Dim o_file As Scripting.TextStream
Dim tddb_vramp As Boolean
If Dir(filename) <> "" Then
Application.ScreenUpdating = False
j = 2 'variable not defined at fs2
' FileSystemObject also called as FSO, provides an easy object based model
' to access computer's file system.
Set fs2 = CreateObject("Scripting.FileSystemObject")
' o_file contains filename (csv file link)
' 1=Open a file for reading only. You can't write to this file.
' 2=ForWriting, 8= For appending
' TristateFalse means u get ascii file by default.
Set o_file = fs2.OpenTextFile(filename, 1, TristateFalse)
' o_file contains filename(text file data)
' Reads an entire line (up to, but not including, the newline character)
' from a TextStream file and returns the resulting string.
sl = o_file.readline
Do While Left(sl, 1) = "#"
' Left Function is used to extract N number of characters from a string from the left side.
sl = o_file.readline
Loop
' atendofstream = Read-only property that returns True if the file pointer
' is at the end of a TextStream file; False if it is not.
Do While o_file.atendofstream <> True
sl = o_file.readline
' INSTR function returns the position of the first occurrence of a substring in a string.
' syntax of InStr( [start], string, substring, [compare] )
' start sets string position for each search, string = string being search,
' substring= string expression searched ,
' eg:InStr(1, "Tech on the Net", "t") Result: 9
' Shows that search is case-sensitive
' compare= optional 1= textcompare
' searching for commas in the file in this case
first = InStr(32, sl, ",", 1) - 15 ' what if first is negative?
second = InStr(first + 2, sl, ",", 1)
If second = 0 Then
second = Len(sl) + 1 'len=length of file string
End If
' "ActiveWorkbook" seems not necessary unless you intend to have
' several workbooks, all having a sheet "Ramp_current" open at the
' same time, and none of them being ThisWorkbook.
' But if that's your intention "ActiveWorkbook" will lead to
' disaster sooner rather than later.
If tddb_vramp = True Then
' write the Voltage Ramp to stress part
If i = 2 Then
ActiveWorkbook.Sheets("Ramp_current").Cells(j, 1) = Mid(sl, 2, first - 2)
End If
ActiveWorkbook.Sheets("Ramp_current").Cells(j, i) = Abs(Mid(sl, first + 2, second - 2 - first)) + 0.000000000000001
Else
'Write the normal current trace
ActiveWorkbook.Sheets("currentPTN_STI").Cells(j, 2 * i - 3) = Mid(sl, 15, first - 14)
' The MID function returns the specified number of characters in a text string,
' starting from a specified position (ie. starting from a specified character number).
' Use this function to extract a sub-string from any part of a text string.
' Syntax: MID(text_string, start_number, char_numbers).
ActiveWorkbook.Sheets("currentPTN_STI").Cells(j, 2 * i - 2) = Abs(Mid(sl, first + 2, second - 2 - first)) + 0.000000000000001
End If
j = j + 1
Loop
If tddb_vramp = False Then
myarray(i) = j - 1
End If
o_file.Close
Application.ScreenUpdating = True
Else
' if Dir(filename) = "" The o_file doesn't exist
MsgBox filename & " wasn't found.", _
vbInformation, "Reading failure"
End If
End Sub
You should remove the Else condition from the above code. If you do that the code will do exactly nothing if the file isn't found. This fact would probably induce me to convert this procedure into a function that returns True if the file was found and False if it isn't. Perhaps that's helpful.
The point is that this procedure must be called by a Main proc which loops through all the files in a folder (for example) calling your proc with different file names. So, if your proc returns False the Main might issue a message saying that a file wasn't found. But even if you don't care for that, it's the Main that would select the next file after one has either been found and evaluated or not.

Why is the result 1, when I count the lines of the text?

Originally I have a list of name of text files in the column A (in excel), and I want to go through all files to open and count its rows. When I run the script below the counter result is '1'
When I open the text files with Notepad++ or Sublime Text I see the lines of the file in different rows. But when I open the files with Notepad I see whole text in one row. What is the problem in this case and how can I fix it. (The line divider is 'LF'.)
Sub counting()
Dim FilePath As String
Dim counter As Integer
Dim curLine As String
FilePath = "C:\Users\kornel.fekete\Desktop\test\Test.txt"
Open FilePath For Input As #1
Do While Not EOF(1)
counter = counter + 1
Line Input #1, curLine
Loop
Cells(1, 1).Value = counter
Close #1
End Sub
I have to do this counting with more than 100 text files.
You could use a textstream:
Sub counting()
Dim fso As New FileSystemObject
Dim ts As TextStream
Dim longtext As String
Dim lines As Variant
Set ts = fso.OpenTextFile("C:\Users\kornel.fekete\Desktop\test\Test.txt", ForReading, False)
longtext = ts.ReadAll
ts.Close
lines = Split(longtext, vbLf)
Cells(1, 1) = UBound(lines) - LBound(lines) + 1
End Sub
You need to set a reference to Microsoft Scripting Runtime.

Search number of times a string occurs in text file

I am trying to go read a text file and count the number of times a phrase/string (not word) occurs in the text file, but so far what I have is this:
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("D:\VBscript project\testing.txt", ForReading)
strContents = objFile.ReadAll
objFile.Close
i = 0
arrLines = Split(strContents, "")
For Each strLine in arrLines
If InStr(strLine, "hi there") Then
i = i + 1
End If
Next
WScript.Echo "Number of times word occurs: " & i
This will only allow me to count the number of times a word occurs, which does not work when I try to tweak it to count phrases.
Consider the below example:
strPath = "D:\VBscript project\testing.txt"
strPhrase = "hi there"
strContent = ReadTextFile(strPath, 0)
arrContent = Split(strContent, strPhrase)
MsgBox "Number of times phrase occurs: " & UBound(arrContent)
Function ReadTextFile(strPath, lngFormat)
' lngFormat -2 - System default, -1 - Unicode, 0 - ASCII
With CreateObject("Scripting.FileSystemObject").OpenTextFile(strPath, 1, False, lngFormat)
ReadTextFile = ""
If Not .AtEndOfStream Then ReadTextFile = .ReadAll
.Close
End With
End Function
Note that Split-based method is case-sensitive.
strPath = "D:\VBscript project\testing.txt"
strPhrase = "hi there"
strContent = ReadTextFile(strPath, 0)
arrContent = Split(strContent, strPhrase)
MsgBox "Number of times phrase occurs: " & UBound(arrContent)
Function ReadTextFile(strPath, lngFormat)
' lngFormat -2 - System default, -1 - Unicode, 0 - ASCII
With CreateObject("Scripting.FileSystemObject").OpenTextFile(strPath, 1, False, lngFormat)
ReadTextFile = ""
If Not .AtEndOfStream Then ReadTextFile = .ReadAll
.Close
End With
End Function
If I understood you correctly and what you are asking for is really as simple as it looks, you could just change the "hi there" string to a parameter. This way you can dynamically tell your function what to look for.
EDIT: Thanks to #omegastripes I noticed a flaw in my previous code, so this is one that would work.
The code would be like this:
Sub yourSubName (pstrTextToCount)
Const ForReading = 1
Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objFile : Set objFile = objFSO.OpenTextFile("D:\VBscript project\testing.txt", ForReading)
Dim strContents : strContents = objFile.ReadAll
objFile.Close
' You don't need these objects anymore, so release them
Set objFile = Nothing
Set objFSO = Nothing
Dim intTextPosition : intTextPosition = 0
Dim i : i = -1
Do
i = i + 1
intTextPosition = InStr(intTextPosition + 1, strContents, pstrTextToCount)
Loop While (intTextPosition > 0)
Wscript.Echo "Number of times '" & pstrTextToCount & "' occurs: " & i
End Sub
I am assuming your Sub will only do that and this is why I enclosed it into the Sub, End Sub statements. You can add any other coding that you need, but only remember to add your required parameter on the signature of the Sub for it to work.
PS: As a good practice, always Dim your variables and release memory of objects that are no longer needed with Set objName = Nothing
Here a version using Regular Expressions so you can specify if the search needs to be case sensitive.
For testpurpose I use the contents of the script itself as input.
Dim path, phrase, content
path = Wscript.ScriptFullName
phrase = "hi there\^$*+?{}.()|[]"
content = CreateObject("Scripting.FileSystemObject").OpenTextFile(path).ReadAll
Function NumberOfPhrasesInString(phrase, text, IgnoreCase)
Dim regexpr, matches
Set regexpr = New RegExp
phrase = RegExEscape(phrase)
With regexpr
.Pattern = phrase
.Global = True
.IgnoreCase = IgnoreCase
Set matches = .Execute(text)
End With
NumberOfPhrasesInString = matches.count
End Function
Function RegExEscape(str)
Dim special
RegExEscape = str
special = "\^$*+?{.()|[]"
For i=1 To Len(special)
RegExEscape = replace(RegExEscape, Mid(special, i, 1), "\" & Mid(special, i, 1))
Next
End Function
Wscript.Echo "Number of times phrase occurs: " & NumberOfPhrasesInString(phrase, content, false)
As a bonus, since I'm switched to Ruby here also that version
path = __FILE__ # the path to this script for test purposes
phrase = 'HI THERE \ ^ $ * + ? { . ( | ['
puts phrase
content = File.read path
def number_of_phrases_in_string(phrase, text, ignoreCase=false )
escaped = Regexp.escape(phrase)
text.scan(Regexp.new(escaped, ignoreCase)).count.to_s
end
puts "Number of times phrase occurs: " + number_of_phrases_in_string(phrase, content, true)
Or in a single line
puts File.read(__FILE__).scan(Regexp.new(Regexp.escape(phrase), true)).count
The true in the last line defines casesensitivity

Read a Text file which has huge line (more than 1024 characters) using VBA macro

I need to pick a particular data from a text file. But this text file has data which is more than 1024 characters on a single line.
For eg: I need data between string text1 and text 2. My code takes only the first data between text1 & text2 in the huge line, and moves to next line. But previous huge line has multiple instances of text1 & text2. I am not able to get those data. Please help. Find below my code:
Sub Macro1()
Dim dat As String
Dim fn As String
fn = "C:\Users\SAMUEL\Desktop\123\Source1.TXT" '<---- change here
With CreateObject("Scripting.FileSystemObject").OpenTextFile(fn)
Do While Not .AtEndOfStream
dat = .Readline
If InStr(1, dat, "text1", vbTextCompare) > 0 Then
x = InStr(dat, "text1") + 8
y = InStr(dat, "text2")
Z = y - x
MsgBox Mid(dat, x, Z)
End If
Loop
.Close
End With
End Sub
I want to pick the data between Text1 and Text2 to a specific cell.
The data looks like "This is an Text1 awesome Text2 website. I like this Text1 website Text2."
This is a huge data which I copied from a website. When I save in a Text file, one line of this web data is more than 4000 characters. So the line in text file ends at 1024 characters and data moves to next line that becomes 3 lines. But My macro takes first 1024 in string "dat" and moves to second line of web data, that means it skips all data after 1024 characters to 4000 characters. The data I want which exists between Text1 and Text2 could be anywhere in whole 4000 characters, But It will be in same pattern. It will never be like Text1...Text1...Text2..
Using a regexp is a useful way to quickly replace all matches in a single shot, or work through each match (including multiple matches per line) as this sample does below.
Sub DisappearingSwannie()
Dim objFSO As Object
Dim objFil As Object
Dim objRegex As Object
Dim objRegMC As Object
Dim objRegM As Object
Dim strIn As String
Dim X
Dim lngCnt As Long
Dim fn As String
fn = "C:\temp\test.TXT" '<---- change here
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objRegex = CreateObject("vbscript.regexp")
Set objFil = objFSO.OpenTextFile(fn)
X = Split(objFil.readall, vbNewLine)
With objRegex
.Global = True
.Pattern = "text1(.+?)text2"
End With
For lngCnt = 1 To UBound(X)
If objRegex.test(X(lngCnt)) Then
Set objRegMC = objRegex.Execute(X(lngCnt))
For Each objRegM In objRegMC
Debug.Print "line " & lngCnt & " position:" & objRegM.firstindex
Next
End If
Next
End Sub
Here is a macro that looks in A1 and B1 for Text1 and Text2. It then allows you to pick a file to process and parses out the substrings from text1 to text2 inclusive. Finally, it splits them into chunks of no more than 1024 characters (ensuring that each chunk ends with a space, so as not to split words), and writes them into a series of rows in column A starting in A2.
Both the parsing of the substrings, and the breaking them up into 1024 character chunks, are accomplished using regular expressions. The "work" is done in VBA arrays as this is faster than going back and forth to the worksheet.
Since the length of a string variable can be approximately 2^31 characters, I doubt you will have any problem reading the entire document into a single variable and then processing it, instead of going line by line.
Since the macro has arguments, you will need to call it from another macro; or it should be trivial for you to change the code to allow different methods of input for text1 and text2.
There is no error checking.
If you do not want to include Text1 and Text2 in the results, a minor change in the regular expression pattern is all that would be required.
I used early binding so as to take advantage of the "hints" while writing the macro. This requires setting references as noted in the macro. However, it should be simple for you to change this to late binding if you wish.
You might also consider a modification so that the multi-row chunks are somehow differentiated from the single row chunks.
Enjoy
Option Explicit
'Set Reference to Microsoft Scripting Runtime
'Set Reference ot Microsoft VBScript Regular Expressions 5.5
Sub ExtractPhrases(Text1 As String, Text2 As String)
Dim FSO As FileSystemObject
Dim TS As TextStream
Dim FN As File, sFN As String
Dim RE As RegExp, MC As MatchCollection, M As Match
Dim RE2 As RegExp, MC2 As MatchCollection, M2 As Match
Dim sPat As String
Dim S As String, sTemp As String
Dim V() As Variant, vRes() As Variant
Dim I As Long, J As Long, K As Long
Dim C As Range
Dim rRes As Range
'Get File path
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.ButtonName = "Process File"
.Filters.Add "Text", "*.txt", 1
.FilterIndex = 1
.InitialView = msoFileDialogViewDetails
If .Show = -1 Then sFN = .SelectedItems(1)
End With
'Read File into String variable
Set FSO = New FileSystemObject
Set TS = FSO.OpenTextFile(FileName:=sFN, IOMode:=ForReading, Create:=False)
S = TS.ReadAll
'Get results
Set RE = New RegExp
Set RE2 = New RegExp
With RE2
.Global = True
.MultiLine = False
.Pattern = "(\S[\s\S]{1,1023})(?:\s+|$)"
End With
With RE
.Global = True
.IgnoreCase = True
.Pattern = "\b" & Text1 & "\b([\s\S]+?)\b" & Text2 & "\b"
If .Test(S) = True Then
ReDim vRes(0)
Set MC = RE.Execute(S)
For I = 1 To MC.Count
Set MC2 = RE2.Execute(MC(I - 1))
ReDim V(1 To MC2.Count)
For J = 1 To MC2.Count
V(J) = MC2(J - 1).SubMatches(0)
Next J
ReDim Preserve vRes(UBound(vRes) + J - 1)
For J = 1 To MC2.Count
K = K + 1
vRes(K) = V(J)
Next J
Next I
End If
End With
vRes(0) = "Phrases"
'transpose vRes
ReDim V(1 To UBound(vRes) + 1, 1 To 1)
For I = 0 To UBound(vRes)
V(I + 1, 1) = vRes(I)
Next I
Set rRes = Range("a2").Resize(rowsize:=UBound(V))
Range(rRes(1), Cells(Rows.Count, rRes.Column)).Clear
rRes = V
End Sub

Search a string from text file & Return the Line Number using VBA

I have one text file that contains around 100K lines. Now I would like to search a string from the text file. If that string is present then I want to get the line number at which it's present. At the end I need all the occurrence of that string with line numbers from the text file.
* Ordinary Method Tried *
We can read the whole text file line by line. Keep a counter variable that increases after every read. If I found my string then I will return the Counter Variable. The limitation of this method is, I have to traverse through all the 100K lines one by one to search the string. This will decrease the performance.
* Quick Method (HELP REQUIRED)*
Is there any way that will directly take me to the line where my searchstring is present and if found I can return the line number where it's present.
* Example *
Consider below data is present in text file. (say only 5 lines are present)
Now I would like to search a string say "Pune". Now after search, it should return me Line number where string "pune" is present. Here in this case it's present in line 2. I should get "2" as an output. I would like to search all the occurrence of "pune" with their line numbers
I used a spin off of Me How's code example to go through a list of ~10,000 files searching for a string. Plus, since my html files have the potential to contain the string on several lines, and I wanted a staggered output, I changed it up a bit and added the cell insertion piece. I'm just learning, but this did exactly what I needed and I hope it can help others.
Public Sub ReadTxtFile()
Dim start As Date
start = Now
Dim oFSO As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim oFS As Object
Dim filePath As String
Dim a, b, c, d, e As Integer
a = 2
b = 2
c = 3
d = 2
e = 1
Dim arr() As String
Do While Cells(d, e) <> vbNullString
filePath = Cells(d, e)
ReDim arr(5000) As String
Dim i As Long
i = 0
If oFSO.FileExists(filePath) Then
On Error GoTo Err
Set oFS = oFSO.OpenTextFile(filePath)
Do While Not oFS.AtEndOfStream
arr(i) = oFS.ReadLine
i = i + 1
Loop
oFS.Close
Else
MsgBox "The file path is invalid.", vbCritical, vbNullString
Exit Sub
End If
For i = LBound(arr) To UBound(arr)
If InStr(1, arr(i), "Clipboard", vbTextCompare) Then
Debug.Print i + 1, arr(i)
Cells(a + 1, b - 1).Select
Selection.Insert Shift:=xlDown
Cells(a, b).Value = i + 1
Cells(a, c).Value = arr(i)
a = a + 1
d = d + 1
End If
Next
a = a + 1
d = d + 1
Loop
Debug.Print DateDiff("s", start, Now)
Exit Sub
Err:
MsgBox "Error while reading the file.", vbCritical, vbNullString
oFS.Close
Exit Sub
End Sub
the following fragment could be repalaced like:
Dim arr() As String
Dim i As Long
i = 0
If oFSO.FileExists(filePath) Then
On Error GoTo Err
Set oFS = oFSO.OpenTextFile(filePath)
Do While Not oFS.AtEndOfStream
ReDim Preserve arr(0 To i)
arr(i) = oFS.ReadLine 'to save line's content to array
'If Len(oFSfile.ReadLine) = 0 Then Exit Do 'to get number of lines only
i = i + 1
Loop
oFS.Close
Else
MsgBox "The file path is invalid.", vbCritical, vbNullString
Exit Sub
End If
Here's another method that should work fairly quickly. It uses the shell to execute the FINDSTR command. If you find the cmd box flickers, do an internet search for how to disable it. There are two options provided: one will return the line number followed by a colon and the text of the line containing the keyword. The other will just return the line number.
Not sure what you want to do with the results, so I just have them in a message box.
Option Explicit
'Set reference to Windows Script Host Object Model
Sub FindStrings()
Const FindStr As String = "Pune"
Const FN As String = "C:\users\ron\desktop\LineNumTest.txt"
Dim WSH As WshShell
Dim StdOut As Object
Dim S As String
Set WSH = New WshShell
Set StdOut = WSH.Exec("cmd /c findstr /N " & FindStr & Space(1) & FN).StdOut
Do Until StdOut.AtEndOfStream
S = S & vbCrLf & StdOut.ReadLine
'If you want ONLY the line number, then
'S = S & vbCrLf & Split(StdOut.ReadLine, ":")(0)
Loop
S = Mid(S, 2)
MsgBox (S)
End Sub

Resources