-
Jan 22nd, 2015, 04:25 PM
#1
Thread Starter
Fanatic Member
Finding text files on a directory.
I have a loading program which I wrote a few years ago, and I'd like to make some changes to it.
It's only function is to load text files from a network drive into our Oracle database. It works fine, but here's how it currently works.
Open the app-->click "Select file"-->select the text file from the dialogue box-->select "Run"--> file loads and is moved to another directory.
The text files in the directory are generated one per day. Sometimes when I go to load the data there are a few days worth of files in there, and sometimes it's just one file I need to load.
What I'd like to do is modify the program so that upon opening it just searches the directory for text files and loads them automatically.
Since the program is already written as stated above, I just need to know how to scan a directory for text files. I can make it work from there.
I've read about the DIR function as well as some other methods, but I'm not sure I get them. Any tips or nudges in the right direction would be appreciated.
-
Jan 22nd, 2015, 05:21 PM
#2
Re: Finding text files on a directory.
Here's a Unicode-aware example:
Code:
Private Type WIN32_FIND_DATA
dwFileAttributes As VbFileAttribute
ftCreationTime As Currency
ftLastAccessTime As Currency
ftLastWriteTime As Currency
nFileSize As Currency
dwReserved As Currency
cFileName As String * 260
cAlternateFileName As String * 14
End Type
Private Declare Function FindClose Lib "kernel32.dll" (ByVal hFindFile As Long) As Long
Private Declare Function FindFirstFileW Lib "kernel32.dll" (ByVal lpFileName As Long, ByVal lpFindFileData As Long) As Long
Private Declare Function FindNextFileW Lib "kernel32.dll" (ByVal hFindFile As Long, ByVal lpFindFileData As Long) As Long
Private Declare Function lstrlenW Lib "kernel32.dll" (ByVal lpString As Long) As Long
Public Function GetFiles(ByRef Path As String, Optional ByRef FileSpec As String = "*.txt") As Collection
Const INVALID_HANDLE_VALUE = -1&
Dim hFindFile As Long, WFD As WIN32_FIND_DATA
Set GetFiles = New Collection
hFindFile = FindFirstFileW(StrPtr(Path & "\" & FileSpec), VarPtr(WFD))
If hFindFile <> INVALID_HANDLE_VALUE Then
Do: GetFiles.Add Path & "\" & Left$(WFD.cFileName, lstrlenW(StrPtr(WFD.cFileName)))
Loop While FindNextFileW(hFindFile, VarPtr(WFD))
hFindFile = FindClose(hFindFile): Debug.Assert hFindFile
End If
End Function
Usage example:
Code:
Option Explicit 'In a standard module
Private Sub Main()
Dim vFile As Variant
For Each vFile In GetFiles("\\Server\Share\Path\To\Your\Text Files")
Debug.Print """"; vFile; """"
Next
End Sub
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Jan 22nd, 2015, 05:32 PM
#3
Re: Finding text files on a directory.
To get all files in a directory use the IO.Directory's GetFiles method and pass the file type as the parameter. Here is an example:
Code:
Private Function GetTextFiles(ByVal directory As IO.DirectoryInfo) As IO.FileInfo()
Return directory.GetFiles("*.txt")
End Function
Edit: I'm sorry, I thought this was a Vb.Net question. Ignore this
-
Jan 23rd, 2015, 12:21 AM
#4
Re: Finding text files on a directory.
The VB6 Dir$() function is actually pretty simple to use and meets peoples' needs in 999 out of 1000 cases.
People do seem to like to go nuts though, assuming misery loves company so they drag everyone down into their private Hell of Unicode requirements. Almost nobody ever needs to worry about Unicode file names, but for those that do there are other solutions.
Your requirements are even simpler than that though, since you do not need to recurse through subdirectories. At that point the code required is pretty minimal. Here the retrieved file names are just dumped into a wide ListBox control for viewing:
Code:
Option Explicit
Private Sub Form_Load()
Dim Path As String
Dim Item As String
Path = App.Path & "\"
Item = Dir$(Path & "*.*", vbNormal)
Do Until Len(Item) = 0
List1.AddItem Path & Item
Item = Dir$()
Loop
End Sub
It really is that simple - just as described in the documentation, which even includes sample code itself.
-
Jan 23rd, 2015, 01:29 AM
#5
Hyperactive Member
Re: Finding text files on a directory.
Originally Posted by dilettante
The VB6 Dir$() function is actually pretty simple to use...
Hi Dilettante. Good day.
I saw you guys always use functions with a "$" attached to the end. For another example, I also saw right$, left$ and mid$. I know of their existence of course but never get to know the serious difference!!
-
Jan 23rd, 2015, 04:12 AM
#6
Re: Finding text files on a directory.
Originally Posted by bPrice
I also saw right$, left$ and mid$. I know of their existence of course but never get to know the serious difference!!
The $ denotes the string version of a function whose equivalent without the $ returns a variant of type string (not the same thing)
Although the result is functionally the same, the string versions are noticeably faster.
Code:
avariant = "ABCDEFGHIJKLMNNOPQRSTUVWXYZ"
astring$ = "ABCDEFGHIJKLMNNOPQRSTUVWXYZ"
t1 = Timer
num% = 10000
For i% = 1 To num%
For j% = 1 To num%
' variant to variant
avariant2 = Mid(avariant, 15, 8)
Next
Next
t2 = Timer
For i% = 1 To num%
For j% = 1 To num%
' variant to string, (actually slower than the loop above because of extra casting)
astring2$ = Mid(astring$, 15, 8)
Next
Next
t3 = Timer
For i% = 1 To num%
For j% = 1 To num%
'string to string (fastest)
astring3$ = Mid$(astring$, 15, 8)
Next
Next
t4 = Timer
MsgBox t2 - t1 & vbCrLf & t3 - t2 & vbCrLf & t4 - t3
-
Jan 23rd, 2015, 07:40 AM
#7
Hyperactive Member
Re: Finding text files on a directory.
Originally Posted by Navion
The $ denotes the string version of a function whose equivalent without the $ returns a variant of type string (not the same thing)...
Got it now. Thanks Navion
-
Jan 23rd, 2015, 09:03 AM
#8
Re: Finding text files on a directory.
Originally Posted by dilettante
People do seem to like to go nuts though, assuming misery loves company so they drag everyone down into their private Hell of Unicode requirements. Almost nobody ever needs to worry about Unicode file names, ...
The reason why I usually prefer calling the Unicode API equivalent of intrinsic VB6 functions/statements is not because I need to deal with Unicode characters, but because it is faster to call them on modern OSs.
Having said that, I do agree that the OP probably doesn't require Unicode-awareness nor utmost efficiency. In that case, the built-in Dir function should indeed be adequate.
Originally Posted by bPrice
I saw you guys always use functions with a "$" attached to the end. For another example, I also saw right$, left$ and mid$. I know of their existence of course but never get to know the serious difference!!
Note that in VB6, the Dir function already returns a String (there's no Variant version) so there's really no need to affix the $ type-declaration character.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Jan 23rd, 2015, 10:12 AM
#9
Thread Starter
Fanatic Member
Re: Finding text files on a directory.
Originally Posted by dilettante
The VB6 Dir$() function is actually pretty simple to use and meets peoples' needs in 999 out of 1000 cases.
People do seem to like to go nuts though, assuming misery loves company so they drag everyone down into their private Hell of Unicode requirements. Almost nobody ever needs to worry about Unicode file names, but for those that do there are other solutions.
Your requirements are even simpler than that though, since you do not need to recurse through subdirectories. At that point the code required is pretty minimal. Here the retrieved file names are just dumped into a wide ListBox control for viewing:
Code:
Option Explicit
Private Sub Form_Load()
Dim Path As String
Dim Item As String
Path = App.Path & "\"
Item = Dir$(Path & "*.*", vbNormal)
Do Until Len(Item) = 0
List1.AddItem Path & Item
Item = Dir$()
Loop
End Sub
It really is that simple - just as described in the documentation, which even includes sample code itself.
That's why I ended up posting on here. Too much overkill on the web. Why use four pages of code when you can use six lines? Not just limited to this particular issue either. I'll give the Dir$() thing a shot, thanks.
-
Jan 23rd, 2015, 04:28 PM
#10
Re: Finding text files on a directory.
Another option is the file list box, just set the path and the pattern, DIR$() is faster File List is more simple.
-
Jan 24th, 2015, 01:53 AM
#11
Hyperactive Member
Re: Finding text files on a directory.
Originally Posted by Bonnie West
Note that in VB6, the Dir function already returns a String (there's no Variant version) so there's really no need to affix the $ type-declaration character.
I am glad that I have come back to see this thread again. Thank you Bonnie. Thanks for the tip.
-
Jan 24th, 2015, 03:49 AM
#12
Re: Finding text files on a directory.
Not much of a tip though really. Once you start dropping use of the $-suffix where it "doesn't matter," pretty soon you start dropping them where it does. Next thing you know your programs are so slow you may as well be using VB.Net!
-
Jan 24th, 2015, 08:14 AM
#13
Re: Finding text files on a directory.
As resident king of overkill, one of my main projects is a basic file search program that currently has 37,211 lines of code, 8,134 more lines of comments, 2,487 procedures, 393 controls, 11 forms, 21 modules, 33 class modules, 6 user controls, and a resource file for good measure. It's Unicode aware, implements all the modern shell interfaces I'm always posting about, draws several controls from scratch with CreateWindowEx (massive performance increase once you hit 600+ listview items) and subclasses most the rest, a UI using all the modern bells and whistles, and even it's own support DLL written in C++ just to do a single little thing that was super hard in VB but very simple in C++.
THAT, my friends, is overkill. Although to be completely fair the core search class is only 1,099 lines- just my own unicode upgrade to leandro ascieto's cSearch.cls
-
Jan 24th, 2015, 01:18 PM
#14
Re: Finding text files on a directory.
Originally Posted by dilettante
Not much of a tip though really. Once you start dropping use of the $-suffix where it "doesn't matter," pretty soon you start dropping them where it does. Next thing you know your programs are so slow you may as well be using VB.Net!
That reads, as if VB5/6-programs would slow down to a crawl, by not applying the $-suffix.
Let's be frank (and technical) here:
The performance gain one can achieve with that "suffixing" is in the range of only about 25%!
Thats the *maximum* one can expect from such "consequent suffixing" - and these max. 25%
will be seen only in longer loops, which will perform (in Sum) *millions* of these calls (with
nothing IO- or Math-related in-between).
Here's my test-code (slightly adapted from what Navion already posted above):
Code:
Option Explicit
Private Sub Form_Click()
Cls
AutoRedraw = True
DoEvents
Dim sSrc As String, vDst As Variant, sDst As String, i&, T1!, T2!, T3!
sSrc = "ABCDEFGHIJKLMNNOPQRSTUVWXYZ"
Const Count& = 10000000 'we loop 10Mio times
T1 = Timer
For i = 1 To Count 'Variant to Variant
vDst = Mid(sSrc, 15, 8)
Next
T1 = Int((Timer - T1) * 1000)
T2 = Timer
For i = 1 To Count 'Variant to String, (actually slower than the loop above because of extra casting)
sDst = Mid(sSrc, 15, 8)
Next
T2 = Int((Timer - T2) * 1000)
T3 = Timer
For i = 1 To Count 'String to String (fastest)
sDst = Mid$(sSrc, 15, 8)
Next
T3 = Int((Timer - T3) * 1000)
Print vbCrLf & T1 & vbCrLf & T2 & vbCrLf & T3
Print "Performance-Advantage of Mid$ vs. Mid: " & Format((T2 - T3) / T2, "Percent")
'now the same for ChrW vs. ChrW$ (resolving to "A" and "B" alternatingly)
T1 = Timer
For i = 1 To Count 'Variant to Variant
vDst = ChrW(65 + (i Mod 2))
Next
T1 = Int((Timer - T1) * 1000)
T2 = Timer
For i = 1 To Count 'Variant to String, (actually slower than the loop above because of extra casting)
sDst = ChrW(65 + (i Mod 2))
Next
T2 = Int((Timer - T2) * 1000)
T3 = Timer
For i = 1 To Count 'String to String (fastest)
sDst = ChrW$(65 + (i Mod 2))
Next
T3 = Int((Timer - T3) * 1000)
Print vbCrLf & T1 & vbCrLf & T2 & vbCrLf & T3
Print "Performance-Advantage of ChrW$ vs. ChrW: " & Format((T2 - T3) / T2, "Percent")
End Sub
Producing (native compiled, but not much different in the IDE) these results:
So, advertising consequently applied $-suffixing as a way to somehow "magically boost up"
the performance of your VB-Apps, is a myth.
Bonnies suggestions, to avoid automatic ANSI-conversions (by using W-Functions),
is much more significant in its effect on performance.
Olaf
-
Jan 24th, 2015, 01:26 PM
#15
Re: Finding text files on a directory.
Gaining 25% by just typing an extra character? Seems like a bargain to me!
-
Jan 24th, 2015, 01:36 PM
#16
Re: Finding text files on a directory.
Originally Posted by dilettante
Gaining 25% by just typing an extra character? Seems like a bargain to me!
<sigh>
You don't seem to understand - these 25% will only apply in very, very rare cases -
these loops I posted above represent an artificial test-scenario... in "real-world-Apps"
you will see perhaps:
- 5-10% gain in e.g. a CSV- or JSON-parser which is "naively written with VBs String-Functions"
- and zero gain in your typical "Button-Click" which is parsing out e.g. a File-Ending
Olaf
-
Jan 24th, 2015, 02:01 PM
#17
Re: Finding text files on a directory.
Well just to be clear you will get the performance gain in all cases where it applies it is just that in most programs that gain will not be noticeable since the function is not being called 1000s or millions of times at once. In many cases it will be a single call. It will still be faster with the $ but the user would never notice it.
-
Jan 24th, 2015, 03:32 PM
#18
Re: Finding text files on a directory.
Regarding the $ suffix of the Dir function, I've always wondered - did the Dir function come in 2 flavors (Variant & String) in previous versions of VB? If so, that would help explain what seems to be an old habit of veteran programmers of appending $ to the Dir function. If it's indeed true, then why was the Variant version of Dir taken out of VB6? Oh, and there is another VB6 String function that I notice some programmers routinely tack the $ sign onto - the Replace function. I thought it was introduced only in VB6? The IDE's Object Browser clearly shows that it has no $ counterpart (since it already returns a String), yet why do some still believe it needs a $ suffix? Is this practice an example of cargo cult programming?
Originally Posted by dilettante
Once you start dropping use of the $-suffix where it "doesn't matter," pretty soon you start dropping them where it does.
Are you suggesting that we should append the $ type-declaration character to all intrinsic VB6 functions that returns a String (and not just those that comes in multiple versions)? Apparently, the explicitly/implicitly declared return value of a function is not enough indication of whether the $ suffix should be used or not, so what is really the rule for String functions?
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Jan 24th, 2015, 04:30 PM
#19
Re: Finding text files on a directory.
The only place I have ever heard of any performance penalty incurred by using the $ is in the case of Join() vs. Join$(), and I'm not even sure about that case.
The real issue with dropping the $ in cases where it doesn't matter is that it leads to the habit of failing to use it where it does matter. I just don't see any practical argument in favor of not using it every time, and a very strong one in favor of cultivating the habit of always using it.
But the habit is the important thing. Do it "wrong" casually and you'll be doing it wrong when you need it too. Small effort, non-trivial gains that can add up quickly when you are really hammering on text.
-
Jan 25th, 2015, 05:26 AM
#20
Re: Finding text files on a directory.
I really like to easily identify all strings in my code and so all my strings (variables, UD and native functions) routinely get the $ suffix unless something special is going on; it's a no brainer really and if it can be faster too why not.
-
Jan 25th, 2015, 09:16 AM
#21
Re: Finding text files on a directory.
Originally Posted by Magic Ink
I really like to easily identify all strings in my code and so all my strings ... routinely get the $ suffix unless something special is going on; ...
Some people (like myself) prefer to convey the same information using the Hungarian notation instead of Sigils.
Originally Posted by Magic Ink
... (variables, UD and native functions) ...
Assuming you meant to say UDT, note that sigils are invalid inside Type blocks.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Jan 25th, 2015, 09:38 AM
#22
Re: Finding text files on a directory.
>Assuming you meant to say UDT
No I meant User Defined Functions.
I'm aware of the Hungarian approach but given that VB uses Sigils to identify its String functions I prefer to follow that convention.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|