Results 1 to 22 of 22

Thread: Finding text files on a directory.

  1. #1

    Thread Starter
    Fanatic Member The_Grudge's Avatar
    Join Date
    Jan 2005
    Location
    Canada
    Posts
    836

    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.

  2. #2
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    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)

  3. #3
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,715

    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
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    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.

  5. #5
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    341

    Re: Finding text files on a directory.

    Quote Originally Posted by dilettante View Post
    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!!

  6. #6
    Fanatic Member
    Join Date
    Jan 2006
    Posts
    557

    Re: Finding text files on a directory.

    Quote Originally Posted by bPrice View Post
    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

  7. #7
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    341

    Re: Finding text files on a directory.

    Quote Originally Posted by Navion View Post
    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

  8. #8
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: Finding text files on a directory.

    Quote Originally Posted by dilettante View Post
    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.

    Quote Originally Posted by bPrice View Post
    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)

  9. #9

    Thread Starter
    Fanatic Member The_Grudge's Avatar
    Join Date
    Jan 2005
    Location
    Canada
    Posts
    836

    Re: Finding text files on a directory.

    Quote Originally Posted by dilettante View Post
    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.

  10. #10
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    14,205

    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.

  11. #11
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    341

    Re: Finding text files on a directory.

    Quote Originally Posted by Bonnie West View Post
    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.

  12. #12
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    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!

  13. #13
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,654

    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


  14. #14
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: Finding text files on a directory.

    Quote Originally Posted by dilettante View Post
    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

  15. #15
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Finding text files on a directory.

    Gaining 25% by just typing an extra character? Seems like a bargain to me!

  16. #16
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: Finding text files on a directory.

    Quote Originally Posted by dilettante View Post
    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

  17. #17
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    14,205

    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.

  18. #18
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    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?

    Quote Originally Posted by dilettante View Post
    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)

  19. #19
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    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.

  20. #20
    Frenzied Member
    Join Date
    Mar 2008
    Posts
    1,210

    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.

  21. #21
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: Finding text files on a directory.

    Quote Originally Posted by Magic Ink View Post
    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.

    Quote Originally Posted by Magic Ink View Post
    ... (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)

  22. #22
    Frenzied Member
    Join Date
    Mar 2008
    Posts
    1,210

    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
  •  



Click Here to Expand Forum to Full Width