Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

VBA Code - Import Daten aus einer .CSV-Datei

Begonnen von dobby110, März 14, 2023, 09:10:08

⏪ vorheriges - nächstes ⏩

dobby110

Hallo zusammen,

kann mir jemand bei dem nachfolgenden VBA-Code helfen?
Ich würde gerne Daten aus einer .CSV-Datei in eine Tabelle meiner Access-Datenbank importieren.
Aber nur die Datensätze, bei denen die ISIN übereinstimmt.

Generell würde ich sagen, dass der Code funktionieren müsste, WENN ES DENN KEINE .CSV-Datei wäre.
Über die Debug-Funktion habe ich die Parameter soweit überprüft.
Aber es scheitert daran, dass er keine Datensätze mit der entsprechenden ISIN findet.

Hat jemand eine Idee, wie ich das Problem lösen könnte? Alternativ könnte man ja die gesamte .CSV-Datei erst einmal in eine Temp-Tabelle importieren und die Daten von dort abgreifen. Aber da die .CSV-Datei über 25.000 Datensätze hat, würde ich das ungern machen, da ich die Vermutung habe, dass mir so die Datenbank zugemüllt wird?

Vielleicht hat ja jemand eine Idee. Würde mich über Hilfe freuen.

Private Sub cmdBestände_Click()
   
    ' Bestand-Import
   
    ' Pfad zur CSV-Datei
    Dim strDateiname As String
    Dim strPfad As String
    Dim dtDatum As Date
   
    dtDatum = DateAdd("d", -1, Date) ' Setzen Sie das Datum auf den Vortag
    Do
    strDateiname = "BEST_CA1_" & Format(dtDatum, "yyyymmdd")
    strPfad = "C:\CA\" & strDateiname & ".csv"
        If Dir(strPfad) <> "" Then Exit Do
        dtDatum = InputBox("Die Datei für das Datum " & Format(dtDatum, "dd.mm.yyyy") & " wurde nicht gefunden." & vbNewLine & "Bitte geben Sie ein neues Datum im Format TT.MM.JJJJ ein.", "Datum ändern", Format(dtDatum, "dd.mm.yyyy"))
        If dtDatum = 0 Then Exit Sub ' Abbruch, falls der Benutzer auf "Abbrechen" geklickt hat
        dtDatum = DateValue(dtDatum)
    Loop

    ' Überprüfen, ob die Datei existiert
    If Dir(strPfad) = "" Then
        MsgBox "Die Datei " & strDateiname & " konnte nicht gefunden werden.", vbExclamation, "Datei nicht gefunden"
        Exit Sub
    End If
   
    ' Setzen der ID, unter der die Daten importiert werden sollen
    Dim lngID As Long
    lngID = Me.ID
   
    ' Verbinden mit der Datenbank
    Dim db As DAO.Database
    Set db = CurrentDb()
   
    ' Öffnen der Tabelle für den Import
    Dim rsImport As DAO.Recordset
    Set rsImport = db.OpenRecordset("tblBestände", dbOpenDynaset)
   
    ' Öffnen der CSV-Datei für den Import
    Dim objExcel As Object
    Set objExcel = CreateObject("Excel.Application")
    Dim wb As Object
    Set wb = objExcel.Workbooks.Open(strPfad)
    Dim ws As Object
    Set ws = wb.Worksheets(1)
   
    ' Importieren der Daten
    Dim lngZeile As Long
    For lngZeile = 2 To ws.Cells(ws.Rows.Count, "B").End(-4162).Row
        If ws.Cells(lngZeile, "B").Value = Me.txtISIN Then
            rsImport.AddNew
            rsImport!CA_ID = lngID
            rsImport!txtISIN = ws.Cells(lngZeile, "B").Value
            rsImport!txtWPName = ws.Cells(lngZeile, "F").Value
            rsImport!txtSER = ws.Cells(lngZeile, "G").Value
            rsImport!txtDepotNr = ws.Cells(lngZeile, "A").Value
            rsImport!dblBestand = ws.Cells(lngZeile, "C").Value
            rsImport!txtWPL = ws.Cells(lngZeile, "Z").Value
            rsImport!datBestandsdatum = ws.Cells(lngZeile, "L").Value
            rsImport.Update
        End If
    Next lngZeile
   
    ' Schließen der CSV-Datei und den Recordset
    wb.Close
    Set rsImport = Nothing
   
    ' Ausgabe Bestätigungsmeldung
    MsgBox "Die Bestände wurden erfolgreich importiert.", vbInformation, "Import erfolgreich"
End Sub


Vorab vielen Dank !

andyfau

Guten Morgen,

der Umweg über Excel ist da vielleicht etwas aufwendig. CSV-Dateien sind ja eigentlich kein Excelformat, sondern ein reines Textformat. Dabei gibt es aber diverse Interpretationsmöglichkeiten der Definitionen.
Feldtrennzeichen "," oder ";". Stringkennzeichen sind meistens ". Zeilenende mit LF und CF.
Also mal prüfen wie das bei deiner Datei ist und dann als Textfile lesen
als einfachen Open for Input as textfile.
String dann mit Split zerlegen, usw.

Beispiele:
https://www.thespreadsheetguru.com/blog/vba-guide-text-files#:~:text=VBA%20Commands%20For%20Text%20File%201%20For%20Output,bottom%20of%20your%20text%20file%20content.%20Weitere%20Elemente

Beste Grüße
Andreas
Beste Grüße
Andreas

MzKlMu

#2
Hallo,
eine CSV muss auch nicht importiert werden, die kann man auch nur verlinken und dann mit Anfügeabfrage(n) die Daten aufbereiten und in die Access Tabelle übertragen.
Mit einer Importspezifikation lassen sich auch viele Parameter einstellen, diese mit Namen speichern und beim Verlinken verwenden.
Für eine CSV braucht man (wie bereits geschrieben) auch kein Excel, zumal keinesfalls sichergestellt ist, dass die CSV von Excel richtig erkannt wird bzw interpretiert wird.
Gruß Klaus

ebs17

Zitatkann mir jemand bei dem nachfolgenden VBA-Code helfen?
Muss das sein?
Den Vorgang kann man ganz anders, aber einfacher schreiben. Läuft dann auch schneller und sicherer.

Einzelne Punkte wurden teilweise schon erwähnt:
- Eine CSV im Standardformat ist eine Textdatei und hat mit Excel nichts zu tun. Ein Umweg über Excel, was selber ein großes Objekt darstellt, ist umständlich und kostet Laufzeit, bietet Raum für zusätzliche Fehler. Außerdem erwartest Du, dass die Spaltentrennung im Excelsheet erfolgt. Das ist keineswegs sicher.
- Eine CSV im Standardformat ist eine Tabelle. Man kann sie also in seine DB (temporär) verknüpfen und nutzen wie eine Tabelle, also auch in Abfragen verwenden. Damit die CSV als Tabelle richtig gelesen werden kann, sollte man zur Sicherstellung eine Importspezifikation (einmalig) erstellen und einsetzen. In dieser wird fixiert, welche Zeichen der Spaltentrennung dienen, welche Datentypen zu welchen Spalten zugeordnet werden, ob es Feldnamen gibt usw.
- Ehe man da loslegt, würde man sich vergewissern, wie Struktur und Inhalt der CSV wirklich aussehen (Prüfen, nicht Glauben).

ZitatAber nur die Datensätze, bei denen die ISIN übereinstimmt.
Hat man die verwendbare Tabelle, kann man diese unmittelbar auf das genannte Kriterium filtern und diese Menge seiner Zieltabelle anfügen.
INSERT INTO Zieltabelle ([Feldliste])
SELECT [Feldliste] FROM VerlinkteCSV
WHERE ISIN IN (SELECT DISTINCT ISIN FROM ZielTabelle)
Mit freundlichem Glück Auf!

Eberhard

dobby110

Vielen Dank für die hilfreichen Hinweise. Eine Frage habe ich dazu noch. Ich habe die .csv verknüpft, nach Semikolon getrennt. Dann kann auf die Daten wunderbar über Access zugreifen.
Jetzt besteht nur ein Problem. Die Datei welche ich verknüpfe ist nicht immer die gleiche. Ich will immer auf die Datei mit Tagesdatum -1 zugreifen.

Wie bekomme ich das denn geregelt, dass es täglich eine andere Datei ist, auf die zugegriffen werden soll?
Oder habe ich an der Stelle irgendwas nicht richtig verstanden?
Füge mal ein Screenshot an, wie das jetzt bei mir aussieht.

Beaker s.a.

ZitatIch will immer auf die Datei mit Tagesdatum -1 zugreifen.
Diese kopierst du einfach mit dem Namen, den du in der Spezifikation verwendest.
Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

ebs17

#6
ZitatWie bekomme ich das denn geregelt, dass es täglich eine andere Datei ist, auf die zugegriffen werden soll?
Alte Verknüpfung löschen. Neue Verknüpfung mit neuer Datei erstellen.

Ich persönlich übernehme die Verknüpfungsdaten direkt in die Abfrage und führe die Abfrage per VBA aus. Dabei kann auch der Dateiname getauscht werden:
Sub EasyImport()
    Dim sPath As String
    Dim sFile As String
    Dim sSQL As String

    sPath = "X:\"
    sFile = "xxx20230310.csv"
   
    sSQL = "INSERT INTO Zieltabelle ([Feldliste])" & _
           " SELECT [Feldliste]" & _
           " FROM [Text;DSN=NameDerSpezifikation;FMT=Delimited;HDR=yes;IMEX=2;CharacterSet=850;" & _
           "DATABASE=" & sPath & "].[" & sFile & "] AS T" & _
           " WHERE T.ISIN IN (SELECT DISTINCT ISIN FROM ZielTabelle)"
    CurrentDb.Execute sSQL, dbFailOnError
End Sub
In der Prozedur müsste nur noch übersichtlich der neue Dateiname ermittelt werden. Mein Favorit dabei wäre eine Dir-Schleife über die Dateien im Ordner mit automatischer Erfassung. Da bereits importierte Dateien aus dem Ordner entfernt werden würden (Löschen / Verschieben in Archiv), könnte man gleich alle anfallenden Dateien verarbeiten, ohne große Dialoge.
Man müsste nur verwaltungstechnisch organisieren, dass zu importierende CSV's in den betrachteten Ordner eingefügt werden.
Mit freundlichem Glück Auf!

Eberhard