Tabelle füllen mit externer Datei

Hallo Rainer,

kannst du mir bitte einen Tipp geben…
Mein Code läuft nur, wenn ich in dem Exceptionfeld einen Eintrag mache. Ansonsten ist die Variabel „e“ null und der Code arbeitet genauso als wenn ich einen gültigen Namen drin stehen hätte, überspringt also die restlichen Files…

While objRS.EOF = False
If objRS(„SDS-Name“) e Then
ReDim Preserve Pfd(i)
Pfd(i) = objRS(„SDS-Name“)
i = i + 1
End If
objRS.MoveNext
Wend

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Gerd,

kannst du mir bitte einen Tipp geben…
Mein Code läuft nur, wenn ich in dem Exceptionfeld einen
Eintrag mache. Ansonsten ist die Variabel „e“ null

Die ist ‚NULL‘? So etwas kann zu Problemen führen, das kann die Ursache sein, müsste ich testen. Mein VB6 kann sich an der Stelle aber auch anders verhalten als Dein VBA, deshalb ist das schwierig.

objRS(„SDS-Name“) ist aber immer ein String, damit vergleichst Du ‚e‘, ich würde ‚e‘ dann als String deklarieren. Der ist dann „“ wenn nichts drin steht. Hast Du ‚e‘ deklariert? (Dim e as String)

Gruß Rainer

Hi Gerd,

Test mit VB6 …

Private Sub Command1\_Click()
 Dim a As String
 a = "Test"
 If a e Then
 DoEvents '

funktioniert. In VB6 würde Dein Code laufen.

Gruß Rainer

Hallo Rainer,

funktioniert nicht.
Wenn ich a = „Test“ schreibe, habe ich ja einen Wert, aber das Feld
Exception ist ja leer und darum funktioniert es nicht. Wenn ich Dim e As String schreibe, bleibt er in der Zeile e = Forms!SDS!Ex1 'Text für Exception hängen.

Mir ist aber gerade eingefallen, könnte ich diesen Fehler nicht durch eine If-Klausel abfangen?

If e = istnull then
e = Test
end if

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Gerd,

Mir ist aber gerade eingefallen, könnte ich diesen Fehler
nicht durch eine If-Klausel abfangen?

If e = istnull then
e = Test
end if

Keine Ahnung, ob das geht. Einen Versuch ist es wert.
Aber dann hast du drei Syntaxfehler in dem Code.

Ist ist deutsch, Englisch heißt das is.
Hinter is fehlt ein Leerzeichen, das erkennt VB so nicht.
Test ist so geschreiben eine Variable, die ebenfalls NULL ist, da fehlen Anführungszeichen.

If e IsNull Then
 e = "Test"
End If

Aber warum willst Du nicht die Variable vernünftig deklarieren?

Dabei fällt mir ein, daß ich doch tatsächlich die ganze Zeit vergessen habe, über den Code zu schreiben ‚Option Explicit‘.
Das mache ich sonst immer, das hilft sehr Tippfehler vermeiden. Dann kannst Du e gar nicht ohne Deklaration verwenden.

Wenn Du e als string deklarierst, kann es nicht mehr Null sein, und das Problem ist ohne Prüfung und Manipulation gelöst.

Wenn sich das Programm tatsächlich an der NULL stört, dann ist das eine Folge der fehlenden Deklaration, also unsauberer Programmierung.

Daß ich in den Codes überall extra hin geschrieben habe …
Dim i As Integer
nur weil ich i in Zählschleifen verwende, hat schon einen Sinn.

Wenn Du bei der Aktion hier nur lernst, daß Du jede Variable, die Du verwenden möchtest auch deklarierst, hat es sich schon gelohnt. :smile:

Gruß Rainer

Hallo Rainer,

ich habe e ja als String deklariert, aber er bleibt „null“.
Ja bei isnull hatte ich mich nur verschrieben, sorry.

Das mit der if geht übrigens nicht, jedenfalls schaffe ich es bis jetzt noch nicht das if e = null genau zu definieren. Er springt zum end if, so als ob e einen Wert hätte.

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Rainer,

ich glaub ich hab’s… so muss der code lauten:

If IsNull(Me.Ex1) Then
e = Leer
End If

Ex1 ist übrigens das Textfeld in meinem Formular.

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Gerd,

ich glaub ich hab’s… so muss der code lauten:

If IsNull(Me.Ex1) Then

*gg* die Syntax für IsNull habe ich auch gerade in der Hilfe gefunden, noch nie gebraucht. :smile:

e = Leer

Leer ist doch auch NULL. Schreib lieber:

e = „“

Gruß Rainer

Hallo Rainer,

jetzt denkst du schon wie ein Computer :smile:

Leer wird in diesem Fall als das Wort leer erkannt…
Teste gerade alles aus, bis jetzt sieht es gut aus mein Freund.

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Gerd,

jetzt denkst du schon wie ein Computer :smile:

*gg* ja, schon lang. :smile:

Leer wird in diesem Fall als das Wort leer erkannt…

Jaaa??? In VB6 nicht. Da würde das als nicht deklarierte Variable verstanden und die ist ‚NULL‘. :smile: das ist dann ein Unterschied zwischen VB6 und VBA, den ich nicht kannte.

Teste gerade alles aus, bis jetzt sieht es gut aus mein
Freund.

Wunderbar! Es wächst doch!

Gruß Rainer

Hallo Rainer,

bis jetzt sieht alles super gut aus.

Tausend Dank nochmal, ohne Dich hätte ich es NIE geschafft!!!

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Gerd,

bis jetzt sieht alles super gut aus.

sehr schön. :smile:

Tausend Dank nochmal, ohne Dich hätte ich es NIE geschafft!!!

Dafür ist w-w-w doch da.
Wenn mal wieder Jemand über die bösen MODs hier schimpft, rufe ich Dich zu Hilfe!

Gruß Rainer

Bin für Dich da, weißt ja wo du mich findest :smile:

Danke & Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Guten Morgen, Rainer!

HAbe mir den Code in Ruhe angesehen und wenn du Zeit hast, können wir kurz (wir müssen nicht in Detail gehen, nur so grob mal anreißen, damit ich in einem Fachbuch das richtige Kapitel finde)darüber reden:

Den oberen Teil mit den Konstanten hatten wir ja schon grob besprochen, nun kommt der Teil darunter:

Private Sub Start_Click()
Dim i As Integer

e = Forms!SDS!Ex1 'Textfeld für Exception
d = Forms!SDS!Ex2 'Textfeld für Exception
r = Forms!SDS!Ex3 'Textfeld für Exception

OpenDB ’ öffnen der DB
strSQL = „SELECT [Sds-task].* FROM [Sds-task]“

OpenRS strSQL ’ aber warum dann openrs strsql?
Transfer „c:\server1\sds-task.lst“
Transfer „c:\server2\sds-task.lst“
Transfer „c:\server3\sds-task.lst“
Transfer „c:\server4\sds-task.lst“

objRS.Close

strSQL = „SELECT DISTINCT [Sds-task].[SDS-Typ], [Sds-task].[SDS-Name], [Sds-task].[CDS-ID], [Sds-task].Datum From [Sds-task] WHERE ((([Sds-task].[SDS-Typ]) Like ‚allusers‘));“

OpenRS strSQL

objRS.MoveFirst
ReDim Pfd(i)
While objRS.EOF = False
If objRS(„SDS-Name“) e And objRS(„SDS-Name“) d And objRS(„SDS-Name“) r Then 'Exception von SDS-Load
ReDim Preserve Pfd(i)
Pfd(i) = objRS(„SDS-Name“)
i = i + 1
End If
objRS.MoveNext
Wend

objRS.Close
objConnection.Close

Sync
End Sub

Was mich gerne wissen würde, warum:
objRS.Close und objConnection.Close

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Guten Morgen Gerd,

Private Sub Start_Click()
Dim i As Integer

e = Forms!SDS!Ex1 'Textfeld für Exception
d = Forms!SDS!Ex2 'Textfeld für Exception
r = Forms!SDS!Ex3 'Textfeld für Exception

hmmm. Du übergibst an die Variable den Namen des Steuerelements.
Hier verlässt Du Dich darauf, daß der Text übergeben wird. Bei Textfeldern funktioniert das auch, weil es eine Default-Eigenschaft gibt. Mit anderen Steuerelementen funktioniert das so nicht, es wäre besser, wenn Du Dir das so gar nicht angewöhnst. Gib immer an, welche Eigenschaft gemeint ist, auch wenn VB in diesem Sonderfall errät, was Du meinst. Ich hätte das so geschrieben:

e = Forms!SDS!Ex1.Text 'Textfeld für Exception
d = Forms!SDS!Ex2.Text 'Textfeld für Exception
r = Forms!SDS!Ex3.Text 'Textfeld für Exception

Was mich gerne wissen würde, warum:
objRS.Close und objConnection.Close

Wir haben eine Verbinding zur Datenbank aufgebaut und ein Recordset erstellt. Die Engine der Datenbank legt daraufhin ein File mit der Endung .ldb an, in dem vermerkt ist, wer worauf zugreift. Versuchst Du nun z.B. in dieser Zeit die Datenbank zu reparieren, bekommst Du eine Fehlermeldung. Die Daten weden erst wieder ordentlich frei gegeben, wenn Du die Verbindungen ordentlich schließt.

Beim Beenden des gesamten Projekts, beim Schließen der Anwendung, sollen diese Verbindungen auch beendet werden, darauf soll man sich aber nicht verlassen. Zum Einen wird hier die Verbindung wieder getrennt, sobald sie nicht mehr benötigt wird, auch wenn das Projekt noch offen ist, zum anderen, könnte Windows beim Schließen des Projekts Fehler machen und Deine Datenbank wäre defekt. Dann müsstest Du erst alle möglichen Anwender aus der Datenbank jagen und sie reparieren, ein unnötiger Aufwand, der durch korrekte Programmierung zu vermeiden ist.

Gruß Rainer

Hallo Rainer,

Danke für den Tipp und die super Erklärung!!!

Melde mich wieder mit Fragen zu dem anderen Code wenn ich mir noch etwas im Buch durchgelesen habe (damit du weniger arbeit hast).

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Guten Morgen Rainer,

die Änderung der Eigenschaft Text habe ich übernommen. Nochmal DANKE für den Tipp.

Bevor wir mit der Code-Erklärung weiter machen, habe ich noch eine große Bitte. Ich habe doch noch einen Fehler in dem Ergebnis bekommen, kannst du mir bitte helfen es zu lösen, hab wohl wieder Mist gebaut.

Wir lesen ja aus der Datei sds-task.lst immer 4 Felder, wobei jede Zeile ungefähr so aussieht:
„ALLUSERS“ „OFFICE03PF–7“ „hteckgg“ „07/07/2008“
und in unsere Tabelle geschrieben wird.
Soweit ist alles prima, aber dann passiert etwas sehr merkwürdiges…

Die Files die wir danach auslesen um zu synchronisieren (die Filenamen ziehen wir ja aus der Query) haben den Syntax:
„nig100hqp1j1j“,„12:58:55“,„01/17/08“ also als Trennzeichen ein Komma und kein blank wie oben und es sind nur 3 Felder pro Zeile zum auslesen und nicht 4 wie bei der sds-task.lst

Und jetzt kommt das Merkwürdige! Trotzdem läuft alles fast perfekt, die Daten werden super eingelesen und die synchronisation läuft auch perfekt aber jetzt kommts…

Manchmal, steht in der Datei die wir auslesen um zu synchronisieren in der Zeile nicht:
„nig100hqp1j1j“,„12:58:55“,„01/17/08“
sondern zwei Zeilen in einer:
„nig100hqp1j1j“,„12:58:55“,"01/17/08"„nfk100g8tt81j“,„14:15:06“,„01/17/08“

Und unser Programm liest alles perfekt aus, schreibt es aber in dem gleichen Syntax wieder zurück, also die Synchronisation in dem Teil wo zwei Zeilen zu einer wurde genau so zurück.

Verstehst du das???

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Gerd,

Und unser Programm liest alles perfekt aus, schreibt es aber
in dem gleichen Syntax wieder zurück, also die Synchronisation
in dem Teil wo zwei Zeilen zu einer wurde genau so zurück.

Verstehst du das???

ja. :smile:
Die Dateien, die synchronisiert werden werden anders gelesen.
Bei denen lese ich nur ganze Zeilen und vergleiche die Zeilen miteinander. Die werden nicht in Felder zerlegt.
Fehlerhafte Zeilen sind dann einfach nicht mit anderen, vorhandenen Zeilen identisch und werden unverändert zurückgeschrieben.

Das ist kein Fehler im Programm, ich hatte verstanden, daß das so gewollt ist. Wenn ich das falsch verstanden habe, ist das zu korrigieren.

Gruß Rainer

Hallo Rainer,

ja aber dass 2 Zeilen zu 1 Zeile zusammengesetzt ist, kommt vielleicht alle 100 Zeilen einmal vor, wenn überhaupt und unser Programm übernimmt es genau so… das verstehst du wirklich?

Ich hatte bis gestern Abend ein richtig gutes Gefühl, weil ich dachte halbwegs diesen Code zu verstehen :frowning:

Nicht du hast etwas falsch verstanden, ich habe nur nicht an alles gedacht und bei der Programmierung so habe ich gelernt, sollte man an wirklich ALLES denken.

Im Grunde muss beim zurück schreiben in die synchronisierten Files „nur“ nach 3 Daten ein „Return“ auf die nächste Zeile kommen.
Also so:
„nig100hqp1j1j“,„12:58:55“,„01/17/08“
„nfk100g8tt81j“,„14:15:06“,„01/17/08“

Kannst du mir bitte dabei nochmal helfen, ich weiß nicht wo und vorallem wie ich da einen neuen Zeilenbeginn nach genau 3 Daten setzen soll.

Gruss Gerd

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Gerd,

ja aber dass 2 Zeilen zu 1 Zeile zusammengesetzt ist, kommt
vielleicht alle 100 Zeilen einmal vor, wenn überhaupt und
unser Programm übernimmt es genau so… das verstehst du
wirklich?

Ja, ich hab’s ja so geschrieben. :smile:

Ich habe die Fehlerkorrektur jetzt mal eingebaut. Nachdem der Fehler so eindeutig beschrieben ist, war das nicht schwer.
Ich habe dazu einen kompletten Code von weiter oben kopiert und bearbeitet.

Bitte kopiere nicht den gesamten Code! Du hast inzwischen etwas geändert, nicht, daß Du das weg wirfst.

Ich markiere die geänderten Stellen fett, nur das sollst Du kopieren. Der restliche Code ist nur dazu da, daß Du weißt, was wo hin gehört.

Das sind zwei Stellen! Die einzelne Zeile, die die neue Prozedur aufruft, bitte nicht vergessen. :smile:

Gruß Rainer

Private Declare Function PathFileExists Lib "shlwapi.dll" Alias "PathFileExistsA" (ByVal pszPath As String) As Long

Dim objRS As ADODB.Recordset
Dim objConnection As ADODB.Connection
Dim Feld() As String
Dim Pfd() As String

Private Sub Befehl0\_Click()
 Dim i As Integer

 OpenDB
 strSQL = "SELECT [Sds-task].\* FROM [Sds-task]"

 OpenRS strSQL

 Transfer "c:\server1\sds-task.lst"
 Transfer "c:\server2\sds-task.lst"
 Transfer "c:\server3\sds-task.lst"
 Transfer "c:\server4\sds-task.lst"

 objRS.Close

 strSQL = "SELECT DISTINCT [Sds-task].[SDS-Typ], [Sds-task].[SDS-Name], [Sds-task].[CDS-ID], [Sds-task].Datum From [Sds-task] WHERE ((([Sds-task].[SDS-Typ]) Like 'allusers'));"

 OpenRS strSQL

 objRS.MoveFirst
 ReDim Pfd(i)
 While objRS.EOF = False
 ReDim Preserve Pfd(i)
 Pfd(i) = objRS("SDS-Name")
 i = i + 1
 objRS.Movenext
 Wend

 objRS.Close
 objConnection.Close

 Sync
End Sub

Private Sub Transfer(ByVal Datei As String)
 Dim ff As Integer, Zl As String
 Dim Fld() As String, i As Integer

 ff = FreeFile
 Open Datei For Input As #ff
 While Not EOF(ff)
 Line Input #ff, Zl
 Fld = Split(Zl, " ")
 objRS.AddNew
 For i = 0 To 3
 objRS(i) = Replace(Fld(i), """", "")
 Next
 objRS.Update
 Wend
 Close #ff
End Sub

Private Sub OpenDB()
 Dim strSQL As String
 Dim DB As String
 DB = "c:\SDS.mdb"
 Set objConnection = New ADODB.Connection
 With objConnection
 .CursorLocation = adUseClient
 .Mode = adModeShareDenyNone
 .Provider = "Microsoft.Jet.OLEDB.4.0"
 .ConnectionString = DB
 .Open
 End With
End Sub

Private Sub OpenRS(ByVal strSQL As String)
 Set objRS = New ADODB.Recordset
 With objRS
 Set .ActiveConnection = objConnection
 .CursorLocation = adUseClient
 .CursorType = adOpenStatic
 .LockType = adLockOptimistic
 .Source = strSQL
 Call .Open
 End With
End Sub

Private Sub QuickSort(ByVal LB As Long, ByVal UB As Long)
 Dim P1 As Long, P2 As Long, Ref As String, TEMP As String
 P1 = LB
 P2 = UB
 Ref = Feld((P1 + P2) / 2)
 Do
 Do While (Feld(P1) Ref)
 P2 = P2 - 1
 Loop
 If P1 P2)
 If LB Zl Then
 Tmp(n) = Feld(i)
 n = n + 1
 Zl = Feld(i)
 End If
 Next
 ReDim Feld(n - 1)
 For i = 0 To n - 1
 Feld(i) = Tmp(i)
 Next
End Sub

**Private Sub Repair()  
 Dim i As Long, Pos As Integer, Zl As String  
 For i = LBound(Feld) To UBound(Feld)  
 Zl = Feld(i)  
 Pos = InStr(1, Feld(i), """""")  
 If Pos 0 Then  
 Feld(i) = Left(Zl, Pos)  
 ReDim Preserve Feld(UBound(Feld) + 1)  
 Feld(UBound(Feld)) = Right(Zl, Len(Zl) - Pos)  
 End If  
 Next  
End Sub**  

Private Sub Sync()
 Dim Txt As String, Daten As String
 Dim i As Integer, c As Integer, ff As Integer, l As Long
 Dim Server(3) As String, Pfad As String, Pos As Integer
 Server(0) = "c:\Server1\"
 Server(1) = "c:\Server2\"
 Server(2) = "c:\Server3\"
 Server(3) = "c:\Server4\"
 ff = FreeFile
 For i = LBound(Pfd) To UBound(Pfd)
 Daten = ""
 For c = 0 To 3
 Pfad = Server(c) + Pfd(i) + ".yes"
 If PathFileExists(Pfad) Then
 l = FileLen(Pfad)
 Txt = Space(l)
 Open Pfad For Binary As #ff
 Get #ff, , Txt
 Close #ff
 Daten = Daten + Txt
 End If
 Next
 If Trim(Daten) "" Then
 Feld = Split(Daten, vbCrLf)
**Repair**
 QuickSort LBound(Feld), UBound(Feld)
 Clean
 Daten = Join(Feld, vbCrLf)
 For c = 0 To 3
 Pfad = Server(c) + Pfd(i) + ".yes"
 Open Pfad For Output As #ff
 Print #ff, Daten
 Close #ff
 Next
 End If
 Next
End Sub