INSERT INTO met 2 tabellen als bron

Status
Niet open voor verdere reacties.

VB noob

Gebruiker
Lid geworden
11 feb 2009
Berichten
78
Kan het INSERT INTO statement gebruikt worden met 2 tabellen als bronnen?

Ik moet een tabel vullen met waardes vanuit 2 verschillende andere tabellen.

Ik zie zo 1,2,3 niet hoe die syntax zou moeten zijn en of het uberhaupt mogelijk is (ook niet met google...).
 
Dat is geen enkel probleem; maar een selectiequery die de records met de velden voor je oplevert, en verander het type query in een Toevoegquery, en klaar ben je! Als je slim bent, zorg je ervoor dat de veldnamen van je query overeenkomen met de veldnamen in je tabel, dan heb je gelijk een visuele controle of je de velden goed matcht met de tabel waar de records inmoeten.
Voorbeeld: in de tabel Opdracht wil je het veld <aNaam> vullen met het veld <Achternaam> uit de tabel Klanten. In je selectiequery selecteer je dan uiteraard het veld <Achternaam>. Vervolgens zet je vóór de veldnaam "aNaam:". Er staat dan dus: "aNaam:Achternaam". Vervolgens kies je het querytype Toevoegen, en selecteer je de tabel Opdrachten. Je zult dan zien, dat het veld <Achternaam> automatisch is gekoppeld aan het veld aNaam.
Uiteraard hoef je dit niet te doen; je kunt de velden altijd handmatig koppelen of aanpassen.
 
Thanks voor je antwoord! Dat leek inderdaad niet zo moeilijk.
Maar...het werkt niet zoals het hoort.

Ik heb dus drie tabellen

'Dogs' met o.a. de kolom:
- DogID (text)
- Current (= de naam van de groep waar de hond zich in bevindt, hier filter ik op zodat de keuzelijsten beperkt blijven)

'Sightings' met o.a. de kolom:
- SightingID (primary key, autonumber)

'DogsatSighting' met 3 kolommen:
- ID (autonumber en primary key)
- SightingID
- DogID

De selectiequery die ik hiervoor maakte was als volgt:

Code:
SELECT Dogs.DogID, Sightings.SightingID
FROM Dogs, Sightings
WHERE (((Sightings.SightingID)=[Sighting]) AND ((Dogs.Current)=[Pack seen]));

Run ik deze query met als parameter voor Sighting '16' en Pack seen naam pack dan krijg ik keurig de ID's van de 3 honden te zien bij dat pack en in de SightingID kolom '16'.

De append query werd vervolgens als volgt (gewoon het type query verandert):
Code:
INSERT INTO DogsatSighting ( DogID, SightingID )
SELECT Dogs.DogID, Sightings.SightingID
FROM Dogs, Sightings
WHERE (((Sightings.SightingID)=[Sighting]) AND ((Dogs.Current)=[Pack seen]));

Hier krijg ik nog de juiste resultaten.
Vervolgens plaats ik een multi select list box op een form wat mij bij het openen de SightingID en Pack name vraagt.
Die vul ik in en ik krijg netjes de honden in de multi select box te zien die bij het pack horen.
Vervolgens heb ik een knop die die data naar de goeie tabel zou moeten schrijven.
Daar had ik de volgende VB code voor, maar die werkte alleen voor de DogID's:

Code:
Option Compare Database
Option Explicit
Private Sub cmdOK_Click()
On Error GoTo Err_Handler
' Declare variables
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim varItem As Variant
Dim strCriteria As String
Dim strSQL As String
' Get the database and stored query
Set db = CurrentDb()
Set qdf = db.QueryDefs("qryAppendSelectDogsatSighting")
' Loop through the selected items in the list box and build a text string
If Me!lstDogIDs.ItemsSelected.Count > 0 Then
For Each varItem In Me!lstDogIDs.ItemsSelected
strCriteria = strCriteria & "Dogs.DogID = " & Chr(34) _
& Me!lstDogIDs.ItemData(varItem) & Chr(34) & "OR "
Next varItem
strCriteria = Left(strCriteria, Len(strCriteria) - 3)
Else
MsgBox "Must Select An Item From The List First"
Exit Sub
End If
' Build the new SQL statement incorporating the string
strSQL = "[B]INSERT INTO DogsatSighting ( DogID ) " & _
"SELECT Dogs.DogID FROM Dogs " & _
"WHERE " & strCriteria & ";"[/B]
' Apply the new SQL statement to the query
qdf.SQL = strSQL
' Open the query
DoCmd.SetWarnings False
DoCmd.OpenQuery "qryAppendSelectDogsatSighting"
DoCmd.SetWarnings True
' Empty the memory
Set db = Nothing
Set qdf = Nothing

Exit_Handler:
Exit Sub

Ook als ik het vetgedrukte stuk verander naar een nieuwe INSERT INTO statement werkt het nog niet.
Deze heb ik geprobeert:
Code:
strSQL = "INSERT INTO DogsatSighting ( DogID, SightingID ) " & _
"SELECT Dogs.DogID, Sightings.SightingID FROM Dogs, Sightings " & _
"WHERE " & strCriteria & ";"

Ik snap dat er nog meer aangepast moet worden, maar hoe en wat weet ik niet precies (zie mij nick...).

Nog idealer zou zijn als de 'SightingID' en 'Pack name' reeds automatisch ingevuld worden aan de hand van zojuist op het formulier ingevulde velden (SightingID is een autonumber) zodat ik alleen de DogIDs hoeft te selecteren en met de knop kan toevoegen aan de tabel 'Dogs at Sighting'.
 
Kun je een voorbeeld posten, dan kunnen we er wat gemakkelijker naar kijken. Hoeven we ook niet alles over te tikken in een testomgeving...
 
Hier is een voorbeeld van de database. Ik ben er nog steeds niet uit hoe dit netjes werkend te krijgen.


Ik hoop niet dat jullie het vervelend vinden dat ik even inbreek in dit probleem.

Het zit hem nl. niet in de INSERT into, maar in de criteria dit je opmaakt in je VBA code.
Doordat je gebruik maakt van de 'OR' in je criteria weet Sql niet meer welke twee waarden hij moet inserten in de tabel.

Onderstaande code gaat per geselecteerde waarde een INSERT doen en doet dat netzo lang als er een selectie is.

Code:
[COLOR="Red"]' Loop through the selected items in the list box and build a text string
[/COLOR]If Me!lstDogIDs.ItemsSelected.Count > 0 Then
  For Each varItem In Me!lstDogIDs.ItemsSelected
    strCriteria = "((Sightings.SightingID=[Sighting]) AND (Dogs.DogID = " & Chr(34) _
                      & Me!lstDogIDs.ItemData(varItem) & Chr(34) & "));"
' Build the new SQL statement incorporating the string
    strSQL = "INSERT INTO DogsatSighting ( DogID, SightingID ) " & _
                  "SELECT Dogs.DogID, Sightings.SightingID FROM Dogs, Sightings " & _
                  "WHERE " & strCriteria    
    Docmd.RunSql strSQL
 Next varItem
Else
 MsgBox "Must Select An Item From The List First" 
 Exit Sub
End If
[COLOR="red"]' Empty the memory[/COLOR]

LETOP: Ik heb deze code niet getest maar alleen maar aangepast.
Mocht er iets niet werken dan ligt dat alleen aan de opbouw van strSQL, dus daar moet je dan even naar kijken.

Succes,
Wim
 
Bedankt! Dat is weer een stap in de juiste richting.
Maar nadat ik de DogIDs in de Listbox geselecteerd heb krijg ik bij het drukken op de knop om ze naar de tabel weg te schrijven voor elke geselecteerde DogID een popup scherm waar ik het SightingID in moet vullen.

Dit komt volgens mij hierdoor:
Code:
  strCriteria = "((Sightings.SightingID=[B][Sighting][/B]) AND (Dogs.DogID = " & Chr(34) _
                      & Me!lstDogIDs.ItemData(varItem) & Chr(34) & "));"

Sightings.SightingID moet net als Dogs.DogID in the strCriteria opgenomen worden. De SightingID wordt wel in de query geselecteerd maar wordt verder niet in de Listbox weergegeven. Hoe dit te doen gaat me een beetje boven mijn pet op dit moment.
 
Bedankt! Dat is weer een stap in de juiste richting.
Maar nadat ik de DogIDs in de Listbox geselecteerd heb krijg ik bij het drukken op de knop om ze naar de tabel weg te schrijven voor elke geselecteerde DogID een popup scherm waar ik het SightingID in moet vullen.

Dit komt volgens mij hierdoor:
Code:
  strCriteria = "((Sightings.SightingID=[B][Sighting][/B]) AND (Dogs.DogID = " & Chr(34) _
                      & Me!lstDogIDs.ItemData(varItem) & Chr(34) & "));"

Sightings.SightingID moet net als Dogs.DogID in the strCriteria opgenomen worden. De SightingID wordt wel in de query geselecteerd maar wordt verder niet in de Listbox weergegeven. Hoe dit te doen gaat me een beetje boven mijn pet op dit moment.

Je moet ook gebruik maken van de 'Sighting' die op je formulier al is geselecteerd, denk ik.
Dat kan ddor Me.Sighting te gebruiken. De Me. geeft aan dat de waarde uit je formulier wordt gebruikt en die zal niet veranderen.

Succes
Wim
 
Dank voor de hulp!
Heb de code aangepast naar:
Code:
' Loop through the selected items in the list box and build a text string
If Me!lstDogIDs.ItemsSelected.Count > 0 Then
  For Each varItem In Me!lstDogIDs.ItemsSelected
  strCriteria = "(([b]Me!SightingID[/b]) AND (Dogs.DogID = " & Chr(34) _
                      & Me!lstDogIDs.ItemData(varItem) & Chr(34) & "));"
' Build the new SQL statement incorporating the string
    strSQL = "INSERT INTO DogsatSighting ( DogID, SightingID ) " & _
                  "SELECT Dogs.DogID, Sightings.SightingID FROM Dogs, Sightings " & _
                  "WHERE " & strCriteria
    DoCmd.RunSQL strSQL
 Next varItem
Else
 MsgBox "Must Select An Item From The List First"
 Exit Sub
End If
' Empty the memory

Maar nu krijg ik na het selecteren van de DogIDs nog steeds een popup, in dit geval vragend naar Me!SightingID. Vul ik daar een SightingID in dan wordt die SightingID ingvuld bij alle DogIDs die er in de database staan.

Als ik gebruik maak van Me!SightingID zou dan ik ook SightingID uit de selectiequery kunnen laten als Sightings.[SightingID] (waar ik hem dus zelf in moet vullen)?

En moet er dan niet iets aangepast worden in het INSERT INTO statement?
 
Laatst bewerkt:
Dank voor de hulp!
Heb de code aangepast naar:
[/CODE]' Loop through the selected items in the list box and build a text string
If Me!lstDogIDs.ItemsSelected.Count > 0 Then
For Each varItem In Me!lstDogIDs.ItemsSelected
strCriteria = "((Me!SightingID) AND (Dogs.DogID = " & Chr(34) _
& Me!lstDogIDs.ItemData(varItem) & Chr(34) & "));"
' Build the new SQL statement incorporating the string
strSQL = "INSERT INTO DogsatSighting ( DogID, SightingID ) " & _
"SELECT Dogs.DogID, Sightings.SightingID FROM Dogs, Sightings " & _
"WHERE " & strCriteria
DoCmd.RunSQL strSQL
Next varItem
Else
MsgBox "Must Select An Item From The List First"
Exit Sub
End If
' Empty the memory[/CODE]

Maar nu krijg ik na het selecteren van de DogIDs nog steeds een popup, in dit geval vragend naar Me!SightingID. Vul ik daar een SightingID in dan wordt die SightingID ingvuld bij alle DogIDs die er in de database staan.

Als ik gebruik maak van Me!SightingID zou dan ik ook SightingID uit de selectiequery kunnen laten als Sightings.[SightingID] (waar ik hem dus zelf in moet vullen)?

En moet er dan niet iets aangepast worden in het INSERT INTO statement?

Je moet het volgende stukje even aanpassen
Code:
strCriteria = [COLOR="Red"][B]"((" & Me!SightingID & ") [/B][/COLOR]AND (Dogs.DogID = " & Chr(34) _
                      & Me!lstDogIDs.ItemData(varItem) & Chr(34) & "));"
Want je moet de variabele wel kunnen gebruiken en niet opnemen in een string

Succes
Wim
 
Internet up and running hier!

Geen popup meer nu, maar de in de multi-list box geselecteerde DogIDs worden nu aan alle bestaande SightingIDs toegevoegd ipv aan alleen de SightingID welke op dat moment op het formulier getoond wordt...Enig idee hoe dat komt?
Is het misschien handiger om het in een subforum te plaatsen?
 
Laatst bewerkt:
Internet up and running hier!

Geen popup meer nu, maar de in de multi-list box geselecteerde DogIDs worden nu aan alle bestaande SightingIDs toegevoegd ipv aan alleen de SightingID welke op dat moment op het formulier getoond wordt...Enig idee hoe dat komt?
Is het misschien handiger om het in een subforum te plaatsen?

Je mist nog een stukje in je selectiecriteria. Had ik zelf ook niet gezien

Code:
strCriteria = "((Sightings.SightingID = " & Me!SightingID & ") AND (Dogs.DogID = " & Chr(34) _
                      & Me!lstDogIDs.ItemData(varItem) & Chr(34) & "));"
 
Het werkt! Top! Ontzettend bedankt.

Nog een fine-tuning vraagje.
Als ik de geselecteerde DogIDs wegschrijf naar de tabel door op de knop te drukken krijg ik een popup scherm voor elke DogID die weggeschreven wordt ('U staat op het punt om 1 rij(en)....'). Selecteer ik 3 DogIDs dan krijg ik dus 3 keer dat pop up scherm.
Niet heel erg, maar wel een beetje irritant.
Is er een makkelijke manier om dat popup scherm te onderdrukken?
 
Het werkt! Top! Ontzettend bedankt.

Nog een fine-tuning vraagje.
Als ik de geselecteerde DogIDs wegschrijf naar de tabel door op de knop te drukken krijg ik een popup scherm voor elke DogID die weggeschreven wordt ('U staat op het punt om 1 rij(en)....'). Selecteer ik 3 DogIDs dan krijg ik dus 3 keer dat pop up scherm.
Niet heel erg, maar wel een beetje irritant.
Is er een makkelijke manier om dat popup scherm te onderdrukken?

Code:
DoCmd.SetWarnings False

LETOP: aanhet einde van je script MOET je
Code:
DoCmd.SetWarnings True
neerzetten anders blijven de boodscahppen uit staan.

Dus ook als er een andere fout in hje script zit dan moet je daar op reageren.
Dus gebruik ON ERROR GOTO label

Succes
Wim
 
Oei...volgens mij heb ik er nog te weinig van begrepen om dit helemaal te begrijpen.
Ik heb beid DoCmd's erin geplakt en het werkt, krijg niet meer een hele rits meldingen. Eigenlijk zou 1 melding die aangeeft hoeveel rijen er toegevoegd worden aan de tabel de gebruiker misschien wel iets meer vertrouwen geven maar er zijn maar 2 of 3 gebruikers dus zoveel maakt dat niet uit.

Maar ik snap het volgende stukje niet helemaal:
Dus als er een andere fout in hje script zit dan moet je daar op reageren.
Dus gebruik ON ERROR GOTO label

Ik snap dat aan het eind van het script DoCmd.SetWarnings True moet staan om foutmeldingen weer toe te kunnen laten. Maar hoe en waarom en waar moet dat ON ERROR GOTO label dan komen?

De code is nu als volgt:
Code:
Private Sub cmdOK2_Click()
On Error GoTo Err_Handler

Do[B]Cmd.SetWarnings False[/B]

' Declare variables
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim varItem As Variant
Dim strCriteria As String
Dim strSQL As String
' Get the database and stored query
Set db = CurrentDb()
Set qdf = db.QueryDefs("qryAppendSelectDogsatSighting")
' Loop through the selected items in the list box and build a text string
If Me!lstDogIDs.ItemsSelected.Count > 0 Then
For Each varItem In Me!lstDogIDs.ItemsSelected
strCriteria = "((Sightings.SightingID = " & Me!SightingID & ") AND (Dogs.DogID = " & Chr(34) _
                      & Me!lstDogIDs.ItemData(varItem) & Chr(34) & "));"
' Build the new SQL statement incorporating the string
strSQL = "INSERT INTO DogsatSighting ( DogID, SightingID ) " & _
"SELECT Dogs.DogID, Sightings.SightingID FROM Dogs, Sightings " & _
"WHERE " & strCriteria
DoCmd.RunSQL strSQL
Next varItem
Else
MsgBox "Must Select An Item From The List First"
Exit Sub
End If
' Empty the memory
Set db = Nothing
Set qdf = Nothing

Exit_Handler:
Exit Sub

Err_Handler:
MsgBox Err.Description
Resume Exit_Handler
[B]
DoCmd.SetWarnings True[/B]

End Sub
 
VB noob,

Even twee zaken:
Het is (bijna) altijd aan te bevelen om alle foutboodschappen af te vangen.
Daarom heb je nu ook de ON ERROR GOTO opgenomen.
In de Error-Handler wordt dan iedere foutboodscahpe die zich voor doet weergegeven.
Super, helemaal goed opgelost.
Alleen....
Je moet je code even aanpassen met het voglende
Code:
Exit_Handler:
[B]DoCmd.SetWarnings True[/B]
Exit Sub
Dit omdat de SetWarning NOOIT wordt bereikt in jouw script.
Loop je script maar even na dan zie je wat ik bedoel. TIP: De End Sub wordt nooit gehaald.

Tweede vraag is niet zo moeilijk. Je kunt gewoon een MsgBox opnemen en daar in de aantallen weergeven.
Code:
Next varItem
[B]MsgBox "The Selected " & varItem & " Item(s) Inserted From The List"[/B]
Else
[B][COLOR="Red"]Goto Exit_Handler[/COLOR][/B]
End If
De Rode regel moet je toepassen ipv Exit Sub
 
Thanx WimenBeer!
Je uitleg bij de eerste vraag snap ik, maar de uitleg bij de 2e vraag volg ik niet helemaal.
Waar precies zou die code moeten komen?
Als ik hem plaats op de plek van de code van de 'andere' messagebox (Must select an item from the list first) dan krijg ik alleen maar de volgende tekst te zien: The Selected Item(s) Inserted From The List.

Ik ben nog niet zover dat een nieuwe messagebox plaatsen in een script voor mij 'gewoon' is...:rolleyes:
 
Thanx WimenBeer!
Je uitleg bij de eerste vraag snap ik, maar de uitleg bij de 2e vraag volg ik niet helemaal.
Waar precies zou die code moeten komen?
Als ik hem plaats op de plek van de code van de 'andere' messagebox (Must select an item from the list first) dan krijg ik alleen maar de volgende tekst te zien: The Selected Item(s) Inserted From The List.

Ik ben nog niet zover dat een nieuwe messagebox plaatsen in een script voor mij 'gewoon' is...:rolleyes:


Ik dacht dat ik het duidelijk had aangegeven, maar hier onder de hele aangepaste code
Code:
Private Sub cmdOK2_Click()
On Error GoTo Err_Handler

DoCmd.SetWarnings False

' Declare variables
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim varItem As Variant
Dim strCriteria As String
Dim strSQL As String
' Get the database and stored query
Set db = CurrentDb()
Set qdf = db.QueryDefs("qryAppendSelectDogsatSighting")
' Loop through the selected items in the list box and build a text string
If Me!lstDogIDs.ItemsSelected.Count > 0 Then
For Each varItem In Me!lstDogIDs.ItemsSelected
strCriteria = "((Sightings.SightingID = " & Me!SightingID & ") AND (Dogs.DogID = " & Chr(34) _
                      & Me!lstDogIDs.ItemData(varItem) & Chr(34) & "));"
' Build the new SQL statement incorporating the string
strSQL = "INSERT INTO DogsatSighting ( DogID, SightingID ) " & _
"SELECT Dogs.DogID, Sightings.SightingID FROM Dogs, Sightings " & _
"WHERE " & strCriteria
DoCmd.RunSQL strSQL
Next varItem
[B][COLOR="red"]MsgBox "The Selected " & varItem & " Item(s) Inserted From The List"[/COLOR][/B]
Else
MsgBox "Must Select An Item From The List First"
[B][COLOR="red"]Goto Exit_Handler[/COLOR][/B]
End If
' Empty the memory
Set db = Nothing
Set qdf = Nothing

Exit_Handler:
[B][COLOR="Red"]DoCmd.SetWarnings True[/COLOR][/B]
Exit Sub

Err_Handler:
MsgBox Err.Description
Resume Exit_Handler

End Sub

ALs je wil kan je de tekst van de MsgBox natuurlijk nog aanpassen naar wat je zelf wilt.

Succes
Wim
 
Bedankt voor de hulp, ik zat op de goede weg maar had nog (lang) niet verzonnen dat het op deze manier moest.
Heb de code aangepast, maar ik zie niet wat het stukje " & varItem & " doet. Ik krijg alleen de volgende tekst in de messagebox: "The Selected Item(s) Inserted From The List"
Moet zeggen dat ik nog niet echt gekeken heb naar waarom niet (tikfoutje ergens ofzo). Was namelijk al bezig met onderstaande tekst...

Ik wilde nog zo'n knop inbouwen op een ander formulier.
Dit keer betreft het een formulier welke ingevuld moet worden met data die verzameld wordt als een dier verdoofd is.
Maar tijdens zo'n 'event' worden ook samples verzameld die normaal ook verzameld worden.
Het betreft het formulier 'frmCollaring' gebaseerd op de tabel tblCollaring.
Hierin zijn velden opgenomen als CollaringID, DogID en CollarDate die ook opgeslagen moeten worden, samen met het type sample, in de tabel tblSamples.

Op basis van de code in dit topic de volgende code geschreven (heb het onderdrukken van meldingen nog even uitgezet):
Code:
Private Sub cmdSaveSamples_Click()
On Error GoTo Err_Handler

'DoCmd.SetWarnings False

' Declare variables
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim varItem As Variant
Dim strCriteria As String
Dim strSQL As String
' Get the database and stored query
Set db = CurrentDb()
Set qdf = db.QueryDefs("appendSamples")
' Loop through the selected items in the list box and build a text string
If Me!CollectedSamples.ItemsSelected.Count > 0 Then
For Each varItem In Me!CollectedSamples.ItemsSelected
strCriteria = "((tblCollaring.DogID = '" & Me!DogID & "') " & _
"AND (tblCollaring.CollaringID = " & Me!CollaringID & ") " & _
"AND (tblCollaring.Date = #" & Me!CollarDate & "#) " & _
"AND (SampleTypes.SampleType = '" & Chr(34) _
                                   & Me!CollectedSamples.ItemData(varItem) & Chr(34) & "'));"
' Build the new SQL statement incorporating the string
strSQL = "INSERT INTO tblSamples ( DogID, CollaringID, [Date], SampleType ) " & _
"SELECT tblCollaring.DogID, tblCollaring.CollaringID, tblCollaring.Date, SampleTypes.SampleType " & _
"FROM tblCollaring, SampleTypes " & _
"WHERE " & strCriteria
DoCmd.RunSQL strSQL
Next varItem
Else
MsgBox "Must Select An Item From The List First"
Exit Sub
End If
' Empty the memory
Set db = Nothing
Set qdf = Nothing

Exit_Handler:
'DoCmd.SetWarnings True
Exit Sub

Err_Handler:
MsgBox Err.Description
Resume Exit_Handler

End Sub

Het resultaat is: 'U staat op het punt om 0 rijen toe te voegen...

De data wordt wel juist geselecteerd (gechecked door een foutje in de strCriteria te maken waarna een melding kwam waarin de geselecteerde waardes wel worden weergegeven). Ik vermoed dus dat het misgaat in de INSERT INTO maar ik kan geen verschil ontdekken met de andere wel werkende code.
Enig idee?
 
VB noob,

Volgens mij gebruik je nu twee posts om je probleem op te lossen.

Een van de twee zal je moeten sluiten. Ik denk deze want dit is wel opgelost.
Ik ga hier dan ook niet meer op reageren.

Op de ander post heb ik ook al gereageerd.


Wim
 
Status
Niet open voor verdere reacties.

Nieuwste berichten

Terug
Bovenaan Onderaan