Pchełki VBA, odcinek 19: czytamy z pliku

Nie jestem osobnikiem zbyt wścibskim i nigdy tak naprawdę nie byłem w stanie zrozumieć szaleństwa programów typu „Big Brother”, w których podglądactwo z wstydliwej czynności zostało wzniesione na piedestał i okazało się Sztuką (przez wielkie „gie” co prawda, ale jednak sztuka to sztuka).

Niemniej jednak czasami zaglądam w statystyki tego bloga, a już najbardziej interesuje mnie jak ludzie do mnie trafiają (oprócz oczywistej nachalnej reklamy, którą czasem uskuteczniam wśród znajomych, a która całkiem nie działa). Ostatnio uczyniłem na ten temat nawet osobny wpis (tak, ten o karaluchach, sklepowej defekacji i usuwaniu ludzi), dziś natomiast wychodzę naprzeciw tym rzeszom przypadkowych szukaczy Wiedzy, którzy trafili do mnie za okruchami informacji o czytaniu z pliku w VBA.

Najpierw opis problemu, który próbujemy rozwiązać: chcemy napisać funkcję VBA, która, użyta w arkuszu, dla zadanego pliku tekstowego wyświetli podstawowe informacje statystyczne dotyczące tego pliku. W naszym przypadku, żeby zmieścić się w kategorii „pchełki”, ograniczymy się do policzenia linii i znaków w pliku. Jak ktoś chce, niech sobie rozbuduje ten kod o liczenie słów, akapitów, imiesłowów bądź paraleli – sky is the limit, jak mówią lokalni.

Podam dwa rozwiązania, obydwa identyczne funkcjonalnie, pierwsze „nieeleganckie”, używające wyłącznie standardowych, wbudowanych w VBA funkcji operacji na plikach, oraz drugie, „porządne”, oparte o bibliotekę Microsoft Scripting Runtime (a więc bardziej „nowoczesne”, chociaż tak naprawdę wcale nie lepsze).

Rozwiązanie 1:

Public Function GetFileStats(strFileName As String) As String
  Dim f As Integer, strline As String, lines As Integer, chars As Integer

  If Len(Dir$(strFileName)) = 0 Then
    GetFileStats = "File '" & strFileName & "' could not be open."
    Exit Function
  End If

  f = FreeFile
  Open strFileName For Input As f
  Do While Not EOF(f)
    Line Input #f, strline
    lines = lines + 1
    chars = chars + Len(strline)
  Loop
  Close #f
GetFileStats = "File '" & strFileName & "': " & lines & " line(s), " & chars & " character(s)."
End Function

Rozwiązanie 2:

Public Function GetFileStats2(strFileName As String) As String
  Dim fso As New FileSystemObject
  Dim lines As Integer, chars As Long, strline As String
  On Error GoTo no_file
  Set ts = fso.OpenTextFile(strFileName)
  On Error GoTo 0
  Do While Not ts.AtEndOfStream
    strline = ts.ReadLine
    lines = lines + 1
    chars = chars + Len(strline)
  Loop
  ts.Close
  GetFileStats2 = "File '" & strFileName & "': " & lines & " line(s), " & chars & " character(s)."
endf:
  Exit Function
no_file:
  GetFileStats2 = "File '" & strFileName & "' could not be open."
  Resume endf
End Function

Ponieważ dziś jestem solidnie zmęczony, wyjątkowo nie będę tłumaczył szczegółów obydwu rozwiązań – proszę sobie we własnym zakresie przeanalizować kod, jeżeli ktoś ma jakieś pytania, proszę o komentarz.

Aha, żeby włączyć bibliotekę Microsoft Scripting Runtime należy w edytorze VBA zajrzeć do menu Tools => References, znaleźć na liście pozycję „Microsoft Scripting Runtime” i, za przeproszeniem, postawić przy niej ptaszka. Dzięki temu będzie można tworzyć obiekty typów FileSystemObject czy TextStream, a także na nich operować.

Dobranoc.

Dodaj komentarz

4 komentarzy do "Pchełki VBA, odcinek 19: czytamy z pliku"

Powiadom o
avatar
Sortuj wg:   najnowszy | najstarszy | oceniany
Butter
Gość

a nie powinno być:

Loop

Close #f

–> f = FreeFile

?

xpil
Gość

FreeFile zwraca pierwszy dostępny identyfikator pliku (liczba, na ogół jedynka, chyba że otwieramy więcej plików na raz). Woła się to na ogół tu przed otwarciem pliku. Wołanie tego po zamknięciu pliku ma sens wyłącznie metafizyczny (o ile za chwilę nie otwieramy kolejnego pliku).

Butter
Gość

Żadne garbage collectory? destruktory? Nic?

xpil
Gość

FreeFile zwraca liczbę całkowitą. Open / Close otwiera i zamyka plik (otwarcie pliku "rezerwuje" tą liczbę, zamknięcie ją "zwalnia"). Co byś chciał jeszcze z tą liczbą zrobić, spalić ją komisyjnie w piecu hutniczym?

wpDiscuz