Złączenia na plikach TXT ADO   strona główna:
A po co ten Excel ;-)
 
Tym razem przedstawię procedurę która swego czasu mnie po prostu zachwyciła :-) Sprawa wyszła tak naprawdę przy okazji okazji konieczności wynalezienia  
obejścia na import danych z pliku xls przy pomocy ADO gdy plik źródłowy jest otwarty a tak naprawdę plik źródłowy był zarazem plikiem docelowym a zapytanie  
SQL wydawało mi się najlepszym rozwiązaniem. M$ na takie okazje podpowiada metodę SaveCopyAs obiektu Thisworkbook ale ja chcąc tego uniknąć chciałem   BUG: Memory leak occurs when you query an open Excel worksheet by using ActiveX Data Objects (ADO)
posłużyć się tymczasowymi plikami tekstowymi. Z importem z jednego pliku txt nie ma problemu ale jeżeli potrzebne informację są rozbite na np.: dwa pliki txt  
należałoby utworzyć złączenie i o tym będzie nasz temat.  
 
Więc dane w dwóch plikach wyglądają następująco: plik  dane.txt  
 
Lp ID data wartosc1 wartosc2 wartosc3  
1 1001 2010-07-19 1 101 40,86  
2 1002 2010-07-20 2 102 -12,75  
3 1003 2010-07-21 3 103 80,89  
4 1004 2010-07-22 4 104 -41,88  
5 1001 2010-07-23 5 105 9,38  
6 1002 2010-07-19 6 106 20,27  
7 1003 2010-07-20 7 107 -1,82  
8 1004 2010-07-21 8 108 70,16  
9 1001 2010-07-22 9 109 78,32  
10 1002 2010-07-23 10 110 -41,1  
11 1003 2010-07-19 11 111 77,48  
12 1004 2010-07-20 12 112 78,32  
 
plik info.txt  
ID Nazwa Adres Telefon  
1001 Nazwa1 Adres1 01 234 5678  
1002 Nazwa2 Adres2 02 234 5678  
1003 Nazwa3 Adres3 03 234 5678  
1004 Nazwa4 Adres4 04 234 5678  
 
Kolumny w obu plikach posiadają nagłówki a separatorem kolumn jest Tab.  
 
     Naszym zadaniem będzie np.: wyciągnięcie danych z pliku dane.txt zapisanych w kolumnach wartosc1, wartosc3 wraz z informacjami z pliku info.txt z kolumn  
Nazwa, Adres, Telefon. Pliki te posiadają kolumny z nagłówkiem ID i to pole łączy dane zawarte w obu plikach "relacją". Takie rozdzielenia danych jest podsta-  
wowym etapem procedur normalizacji jakiemu poddawane być powinny dane we wszelkiego rodzaju bazach danych. Chodzi o tzw. "Drugą postać normalną"   Postać normalna (bazy danych)
 
Procedura importująca dane wykorzystując Lewostronne złączenie zwenętrzne wygląda następująco  
 
Option Explicit  
 
Const adOpenStatic = 1  
Const adStateOpen = 1  
Const adEditNone = 0  
 
Sub ZłączenieNaTXT()  
    On Error GoTo ZłączenieNaTXT_Error  
 
    Const strTXTFilesPath As String = "C:\Documents and Settings\jr\Pulpit"  
    Const strTXTFile1Name As String = "dane.txt"  
    Const strTXTFile2Name As String = "info.txt"  
    Dim nr As Integer  
    Dim strSchemainiFilePath As String  
    Dim strConnectionString As String, strSQL As String, objRecordset As Object  
 
    nr = FreeFile  
    strSchemainiFilePath = strTXTFilesPath & "\schema.ini"  
    Open strSchemainiFilePath For Output As #nr   Inicjowanie sterownika źródła danych tekstowych
        Print #nr, "[" & strTXTFile1Name & "]"  
        Print #nr, "Format = TabDelimited"  
        Print #nr, "ColNameHeader = True"  
        Print #nr, "DecimalSymbol=,"  
        Print #nr, "Col4=wartosc3 Float"  
        Print #nr, "[" & strTXTFile2Name & "]"  
        Print #nr, "Format = TabDelimited"  
        Print #nr, "ColNameHeader = True"  
    Close #nr  
 
    strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _  
                          "Data Source=" & strTXTFilesPath & ";" & _  
                          "Extended Properties=""text"""  
  Złaczenia tabel w SQL
    strSQL = "SELECT A.[wartosc1], A.[wartosc3], B.[Nazwa], B.[Adres], B.[Telefon] " & _  
             "FROM " & strTXTFile1Name & " AS A " & _   SQL JOIN 
             "LEFT OUTER JOIN " & strTXTFile2Name & " AS B " & _  
             "ON A.[Id] = B.[Id] " & _  
             "WHERE A.[data] = #07/19/2010#;"  
 
    Set objRecordset = CreateObject("ADODB.Recordset")  
    objRecordset.Open strSQL, _  
                      strConnectionString, _  
                      adOpenStatic  
    [A1].CopyFromRecordset objRecordset  
 
ZłączenieNaTXT_Exit:  
    On Error Resume Next  
      
    If Not (objRecordset Is Nothing) Then  
        With objRecordset  
            If CBool(.State And adStateOpen) Then  
                If .EditMode <> adEditNone Then .CancelUpdate  
                .Close  
            End If  
        End With  
        Set objRecordset = Nothing  
    End If  
      
    VBA.Kill strSchemainiFilePath  
    Exit Sub  
 
ZłączenieNaTXT_Error:  
    MsgBox "Błąd Nr - " & Err.Number & vbCrLf & vbCrLf & _  
            Err.Description, vbExclamation, "VBAProject - WyłDłu"  
Resume ZłączenieNaTXT_Exit  
 
End Sub  
 
Procedura zwraca następujący zestaw danych  
 
1 40,86 Nazwa1 Adres1 01 234 5678  
6 20,27 Nazwa2 Adres2 02 234 5678  
11 77,48 Nazwa3 Adres3 03 234 5678  
 
Ameryki pewnie nie odkryję poniższym stwierdzeniem ale ...  
Złączenia wykonywane na plikach txt nie różną się zatem niczym od złączeń jakie można wykonywać na tabelach w Accesie czy zakresach w plikach Excela.  
Główną różnicą jest fakt, że obiekt połączenia do Pliku ACC czy XLS w Parametrze Date Sourse przyjmuje pełną ścieżkę do pliku. Połączenie takie do pliku txt   
w tym parametrze przyjmuje ścieżkę do folderu z plikiem txt. Zatem tak jak tabele czy zakresy w plikach ACC czy XL'a tu za odrębne tabele należy traktować całe  
pliki i wykonywać na nich złączenia.