Oktober 22, 2020, 11:57:39

Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!


Ist es mögliche bestimmte Zeilen aus Excel IN eine Access-DB zu exportieren?

Begonnen von derilzemer, Juni 12, 2020, 17:30:01

⏪ vorheriges - nächstes ⏩

derilzemer

Hallo Eberhard,
danke für dein Angebot.
Heute morgen habe ich noch mit meinem AK gesprochen, der Programmierer ist und er hat mich gebeten die Zeile
" SELECT SpalteA, SpalteB, SpalteC, SpalteD FROM" & _
mit
" SELECT * FROM" & _

zu ersetzen und zu testen. Und siehe da, ratzfatz waren die Daten in den DB-Tabellen drin. Zuerst dachte ich mit * legt das Makro auch viele neue "Felder" in der DB an. Aber da habe ich falsch gedacht, er legt genau die Daten aus den 4 Spalten an, nicht mehr und nicht weniger.
Im Gegensatz zum copy Daten Exceltabelle & paste in Tabelle Access-DB Verfahren muss man das Schlüsselfeld (Autowert) befüllen, sonst erzeugt Access eine Importfehler in der DB, auch wenn die Datensätze korrekt anlegt werden. Diesen "Mehraufwand" stört mich nicht die Bohne. Wenn die Boardmember und Experten jetzt nicht irgendein Argument liefern, dass diese Vorgehensweise als absolutes NoGo ist, dann würde ich das Problem für mich als gelöst markieren. Wie siehst du das?

Gruß Andreas
Grüße und Dank im voraus
Andreas

ebs17

Ich sehe das deutlich anders.

Ein Autowert heißt Autowert, weil sich das Feld selber füllt. Eine Zuweisung von außen ist da deutlich problematischer. Daneben werden Autowerte ja oft als Primärschlüssel verwendet und pflanzen sich über Beziehungen als Fremdschlüssel in anderen Tabellen fort. Das hat man per Zuweisung alles fehlerfrei im Griff?
Ein Autowertfeld lässt man also einfach aus der Auflistung heraus, oder aber wenn man zuweisen will, nimmt man doch eher ein normales Longfeld.

" SELECT * " ... heißt ja: Nimm alles. Auch das ist prinzipiell problematisch (auch wenn es im Augenblick passen kann).
Da bekommt man Probleme,
- wenn Quellfeld und Zielfeld nicht den gleichen Namen haben,
- wenn es unterschiedliche Anzahlen von Feldern gibt. Könnte ja sein, man hängt irgendwo mal eine Spalte an.

Nur mit Einzelnennung hat man eine gesicherte Feldzuordnung.

Daneben ist es eine Frage des Stils, der Funktionalität und der Performance, nur genau die Felder zu nehmen und diese folglich zu benennen, die man braucht.

Mit solch einer Schreibarbeit sparenden "Schlauheit" legt man sich faule Eier ins Nest. Kann sein, dass die dann "plötzlich und unerwartet" anfangen zu stinken, obwohl man doch "nichts" gemacht hat und immer alles funktioniert hat.
Mit freundlichem Glück Auf!

Eberhard

derilzemer

Hallo Eberhard,
ich stimme in den Punkten, in welchen du interveniert hast zu, es ist Fehleranfällig, definitiv. Wegen dem Schlüsselwert muss man natürlich immer wie in meinem Fall 3 Tabellen abgleichen, das stimmt also dein Einwand. Wie gesagt, bei copy&paste kann man die Felder leer lassen und Access macht den Rest, ergo muss ich in der Spalte in Excel was definieren, dass Access das schnallt und keinen Importfehlerreport anlegt.
Ich werde morgen mit meinem Kollegen versuchen das genau herauszuarbeiten. Die select * Variante ist jetzt nur mal eine Möglichkeit, die ich in der Hinterhand habe, mehr nicht.
Fakt ist, dass man nicht allzuviel dazu findet, wie der korrekte Weg ist, außer heute ein "ergoogelter" Hinweis, dass man den select wohl so gestalten muss


" SELECT tblQuartette.columnA, tblQuartette.columnB, tblQuartette.columnC, tblQuartette.columnD FROM" & _

Bei Jeder Spalte muss der Name der Source Tabelle nochmal mit. Auch hier habe ich dann schon 3 Varianten durchgetestet, mit .SpalteA, .Spalte1, .A und eben das oben aufgeführte. Die Fehlermeldung blieb die gleiche. Die 4 übergebenen Parameter sind falsch  :-\. Das schauen wir uns morgen mal in einer freien Minute an und schauen mal nach dem korrekten Lösungsansatz. Ich werde es hier posten.

Gruß Andreas
Grüße und Dank im voraus
Andreas

derilzemer

Hallo Eberhard,
gerade eben habe ich eine alte Expertise von dir gefunden zu genau meinem Thema.
https://www.ms-office-forum.net/forum/showthread.php?t=247467
https://www.ms-office-forum.net/forum/showthread.php?t=247042#7

Was ich gleich gesehen habe, dass es alles andere als einfach ist :).
Schau ich mir morgen mal genauer an.

Gruß Andreas
Grüße und Dank im voraus
Andreas

derilzemer

Hallo Eberhard,
ich habe mal versucht, deinen Code für mich anzupassen und anzuwenden (1 Tabelle mit einer Autowert Spalte und einer "Datenspalte"). Spalte A hat in A1 ID und Spalte B in B1 Testdaten als Überschrift. Die Tabelle selbst ist in einer Arbeitsmappe mit mehreren Tabellen (6 insg.), die Tabelle selbst heiß tblTest. In Access habe ich eine Tabelle nach identischem Muster erstellt, tblTest, 2 Felder, Feld 1 ID, Feld 2 Testdaten. Diese Accesstabelle ist noch leer. Jetzt habe ich folgenden Code verwendet:


Sub InsertAccTab()

   ' Verweis auf Microsoft DAO 3.6 Object Library
   Dim db As DAO.Database
   Dim ws As Worksheet
   Dim i As Long
   Set db = OpenDatabase("C:\Users\linus\Familie\Quartette\Datenbank\Access-DB\QuartettDB.accdb")
   Set ws = ActiveWorkbook.Worksheets("tblTest")
   
   ' Annahmen:
   ' 1) Exceltabelle hat Feldnamen
   ' 2) Spalte A enthält die Schlüsselnummer (Datentyp Zahl)
   ' 3) Spalte B enthält die anzufügenden Daten (Datentyp kurzer Text)
   For i = 2 To ws.Cells(Cells.Rows.Count, 2).End(xlUp).Row
      If Len(ws.Cells(i, 2)) > 0 Then _
         [b]db.Execute "INSERT INTO tblTest (Testdaten) Values (" & ws.Cells(i, 2) & ")"[/b]
   Next

   db.Close
   Set db = Nothing
   Set ws = Nothing

End Sub


Ich bekomme beim Testen an der Fett markierten Zeile wieder den Fehler 3061 :(
1 Parameter wurde erwartet, aber es wurden zu wenig Parameter übergeben.

In der ExcelTabelle habe ich zum testen Zelle B2-B4 befüllt mit B2-->Test|B3-->Diamant|B4-->Pech. A2-A4 ist leer.
Ich kann mit der Fehlermeldung nichts anfangen, da ich der Meinung war/bin, dass ich ihm alles übergeben habe. Was mache ich falsch und wo kann ich mir zu solchen Fehlersituationen besseres Verständnis holen, nur durch "Programmiererfahrung"?

Gruß Andreas
Grüße und Dank im voraus
Andreas

ebs17

SQL ist eine andere Programmiersprache als VBA. Das muss man sich bewusst machen, auch wenn man SQL in VBA einbauen kann.

Bei der Zuweisung von Quelle zu Ziel müssen die Datentypen kompatibel sein. das hatten wir schon besprochen. Wenn die Werte allerdings nicht von einer SQL-Tabelle stammen, sondern von außen kommen (Variable, Excelzelle, Arrayfeld usw.), müssen diese zusätzlich datentypgerecht formatiert werden, damit sie sie akzeptiert werden. Texte sind bspw. in zusätzliche Gänsefüßchen (ersatzweise einfache Hochkommata) einzuschließen.
Zitatdb.Execute "INSERT INTO tblTest (Testdaten) Values ('" & ws.Cells(i, 2) & "')"

Grundlagen - SQL ist leicht (5) - Datentypbehandlung für VBA
Mit freundlichem Glück Auf!

Eberhard

derilzemer

Hallo Eberhard,
so funktioniert das jetzt aus unserer Sicht sauber. Danke für das immer wieder drauf hinweisen.
Gruß Andreas

Sub InsertAccTab()

    ' Verweis auf Microsoft DAO 3.6 Object Library
    Dim db As DAO.Database
    Dim ws As Worksheet
    Dim i As Long
    Set db = OpenDatabase("C:\Users\linus\Familie\Quartette\Datenbank\Access-DB\QuartettDB.accdb")
    Set ws = ActiveWorkbook.Worksheets("tblTest")
   
   ' Annahmen:
   ' 1) Exceltabelle hat Feldnamen
   ' 2) Spalte A enthält die Schlüsselnummer (Datentyp Zahl)
   ' 3) Spalte B|C|D enthalten die anzufügenden Daten (Datentyp kurzer Text und Zahl)
    For i = 2 To ws.Cells(Cells.Rows.Count, 2).End(xlUp).Row
            db.Execute "INSERT INTO tblTest (Material,Gewicht,Einheit) Values ('" & ws.Cells(i, 2) & "','" & ws.Cells(i, 3) & "','" & ws.Cells(i, 4) & "')"
    Next
       MsgBox "Es wurden Datensätze angefügt."

   db.Close
   Set db = Nothing
   Set ws = Nothing

End Sub
Grüße und Dank im voraus
Andreas