Query resultaat weergeven in tekstvak

Status
Niet open voor verdere reacties.

rvdsch

Gebruiker
Lid geworden
18 jun 2009
Berichten
170
Ik wil graag met de volgende SQL code de Som van de Hoeveelheid van een bepaald product in een bepaalde periode weergeven in een tekstvak.

Code:
SELECT AlleOrders.Datum, Bedrijfsonderdelen.Bedrijfsonderdeel, Leverancier.Leverancier, Producten.Product, Sum(AlleOrders.Hoeveelheid) AS SomVanHoeveelheid
FROM Leverancier INNER JOIN (Bedrijfsonderdelen INNER JOIN (Producten INNER JOIN AlleOrders ON Producten.ProductID = AlleOrders.ProductID) ON Bedrijfsonderdelen.LocatieID = AlleOrders.LocatieID) ON Leverancier.LeverancierID = AlleOrders.LeverancierID
GROUP BY AlleOrders.Datum, Bedrijfsonderdelen.Bedrijfsonderdeel, Leverancier.Leverancier, Producten.Product, AlleOrders.LocatieID, AlleOrders.LeverancierID
HAVING (((AlleOrders.Datum) Between [forms]![VoorraadBCNederweert].[Startdatum] And [forms]![VoorraadBCNederweert].[Einddatum]) AND ((Producten.Product)=[forms]![VoorraadNederweert].[ProductID_NW]) AND ((AlleOrders.LocatieID)<>2) AND ((AlleOrders.LeverancierID)=7));

Nu heb ik iets over DSum gelezen maar ik heb geen idee waar de lepel hangt. Moet ik nu van het besturingselement van het tekstvak op het formulier een DSum functie maken? Of moet ik in de query zelf een DSum functie maken en het resultaat daarvan dan op de een of andere manier in dat tekstvak zien te krijgen?
 
Ik zou in het query-ontwerp het veld Datum niet als groepveld gebruiken, maar daar de functie Where gebruiken. Je wilt, neem ik aan, alleen filteren op de datumperiode, en geen totalen over die datums zien.
Eigenlijk moet je, als je van een bepaald veld de totalen wilt zien, zo weinig mogelijk velden toevoegen die het eindresultaat differentiëern.
Je zou, als je alleen het totaal wilt zien, dus het veld Hoeveelheid kunnen tonen en de rest als filtering gebruiken.
je krijgt dan zoiets:

SELECT Product, Sum(AlleOrders.Hoeveelheid) AS SomVanHoeveelheid
FROM Producten INNER JOIN AlleOrders ON Producten.ProductID = AlleOrders.ProductID
GROUP BY Producten.Product, Sum(AlleOrders.Hoeveelheid) AS SomVanHoeveelheid
WHERE ((AlleOrders.Datum Between [forms]![VoorraadBCNederweert].[Startdatum] And [forms]![VoorraadBCNederweert].[Einddatum]) AND ((Producten.Product)=[forms]![VoorraadNederweert].[ProductID_NW]) AND (AlleOrders.LocatieID<>2) AND (AlleOrders.LeverancierID=7));

Deze code overigens niet zomaar overnemen, want hij is meer als demo gemaakt. Zal niet werken!

Michel
 
Ik ben inmiddels wat verder aan het gaan met het probleem. Ik heb er nu voor gekozen om de query afhankelijk van het formulier te maken daarbuiten kan hij niet lopen. De SQL is al volgt:

SELECT Sum(AlleOrders.Hoeveelheid) AS SomVanHoeveelheid
FROM Leverancier INNER JOIN (Bedrijfsonderdelen INNER JOIN (Producten INNER JOIN AlleOrders ON Producten.ProductID = AlleOrders.ProductID) ON Bedrijfsonderdelen.LocatieID = AlleOrders.LocatieID) ON Leverancier.LeverancierID = AlleOrders.LeverancierID
GROUP BY AlleOrders.Datum, Bedrijfsonderdelen.Bedrijfsonderdeel, Leverancier.Leverancier, Producten.Product, AlleOrders.LocatieID, AlleOrders.LeverancierID
HAVING (((AlleOrders.Datum) Between [forms]![VoorraadBCNederweert].[Startdatum] And [forms]![VoorraadBCNederweert].[Einddatum]) AND ((Producten.Product)=[forms]![VoorraadBCNederweert].[ProductID_NW]) AND ((AlleOrders.LocatieID)<>2) AND ((AlleOrders.LeverancierID)=7));


Deze loopt buiten het formulier goed. Alleen nu krijg ik hem binnen het formulier niet aan de praat. Ik gebruik deze VBA om hem te laten werken.
Private Sub InternLev_GotFocus()
Dim strTabel1 As String
strTabel1 = "InterneLeveringenBCNW"
strSQL1 = "Select * From " & strTabel1 & vbCrLf
Me.RecordSource = strSQL1
Me.Requery
End Sub

Ik heb al eerder met een soortgelijk probleem gezeten. Is het in dit geval ook weer handiger om de gehele SQL in VBA te laten lopen of kan het ook op mijn manier?
 
De query die je los gebruikt, en die goed werkt(?) is niet dezelfde als die je op het fomulier gebruikt, tenzij [nterneLeveringenBCNW] dezelfde query is.

De queryopbouw die je beschrijft, doet op dit moment eigenlijk helemaal niks; je vraagt eigenlijk alleen de onderliggende bron op (met strTabel=[nterneLeveringenBCNW] en hangt die onder het formulier als RecordSource.
Je kunt dan net zo goed de tabel of query [nterneLeveringenBCNW] als formulierbron definieren.

Ik zou dus, als je de querytekst wilt gebruiken, deze in zijn geheel aan de variabele strTabel toewijzen, en de recordbron op het formulier leeglaten.
Het toewijzen van de recordsource doe je immers al via de code.
 
Nog een extra vraagje:

Waarom heb de de code op het GotFocus() event gezet?
Nu wordt elke keer als je het formulier (ik ga ervan uit, dat InternLev een subformulier is) selecteert de recordset vernieuwt met
Me.RecordSource = strSQL1
Me.Requery

Ik zou de code dus op het event <Bij Laden> van het subformulier zetten, of eventueel <Bij Aanwijzen>, al vermoed ik dat de laatste optie ook averechts gaat werken.

Michel
 
Hey Michel,

Ik heb gewoon random voor GotFocus gekozen. Eigenlijk wou ik de code onder een knop zetten waar al een query onder liep. Ik kon ze niet tegelijkertijd plaatsen. Ik heb zowel de SQL als de code verandert. Deze query kan niet de RecordSource zijn want dat is namelijk al een andere query. Ik wil van deze query alleen dat hij dus de Som van de hoeveelheid weergeeft in een tekstvak. Ik heb als nieuwe SQL en VBA het volgende:

Dim strTabel1 As String
strTabel1 = "[InterneLeveringenBCNW]"
strSQL1 = "Select * From " & strTabel1 & vbCrLf _
& "And WHERE((([Datum])>=#" & Me.Startdatum.Value & "# And ([Datum])<=#" & Me.Einddatum.Value & "#) " _
& "And ([Product]=Me.ProductID_NW)" _
& "And ([LocatieID]<>2)" _
& "And ([LeverancierID]=7))"
Me.RecordSource = strSQL1
Me.Requery

Maar ik realiseer me nu dat dit totaal niet klopt. Ik moet dus slechts in 1 tekstvak het resultaat krijgen.

SELECT Sum(AlleOrders.Hoeveelheid) AS SomVanHoeveelheid
FROM Leverancier INNER JOIN (Bedrijfsonderdelen INNER JOIN (Producten INNER JOIN AlleOrders ON Producten.ProductID = AlleOrders.ProductID) ON Bedrijfsonderdelen.LocatieID = AlleOrders.LocatieID) ON Leverancier.LeverancierID = AlleOrders.LeverancierID
GROUP BY AlleOrders.Datum, Bedrijfsonderdelen.Bedrijfsonderdeel, Leverancier.Leverancier, Producten.Product, AlleOrders.LocatieID, AlleOrders.LeverancierID;

Het lijkt mij nu ik er zo over nadenk het beste om mijn oorspronkelijke SQL te gebruiken en die dan op de een of andere manier te dwingen het resultaat in het tekstvak weer te geven.
 
Ik ben al weer iets verder. Ik gebruik nu de volgende VBA:


Dim strTabel1 As String
strTabel1 = "[InterneLeveringenBCNW]"
strSQL1 = "Select InterneLeveringenBCNW.Hoeveelheid * From " & strTabel1 & vbCrLf _
& "And WHERE((([Datum])>=#" & Me.Startdatum.Value & "# And ([Datum])<=#" & Me.Einddatum.Value & "#) " _
& "And ([Product]=Me.ProductID_NW)" _
& "And ([LocatieID]<>2)" _
& "And ([LeverancierID]=7))"
Me.InternLev.Value = strSQL1
Me.Requery

Hij loopt nog steeds niet lekker maar hij geeft nu iig wel iets weer in het tekstvak. Ik ga weer verder met de code
 
Sluit anders even je bestand bij, in Access 2003 formaat.

Grtz,

Tardis
 
Er ontbreken wat spaties op het eind van de regels, waardoor je een foutmelding kan krijgen.
Dit is in ieder geval een schone versie van je query:

Code:
Dim strTabel1 As String
strTabel1 = "[InterneLeveringenBCNW]"
strSQL1 = "Select InterneLeveringenBCNW.Hoeveelheid * From " & strTabel1 & vbCrLf _
& "WHERE(([Datum]>=#" & Me.Startdatum.Value & "# And [Datum]<=#" & Me.Einddatum.Value & "#) " _
& "And ([Product]=Me.ProductID_NW) " _
& "And ([LocatieID]<>2) " _
& "And ([LeverancierID]=7)) "
Me.InternLev.Value = strSQL1
Me.Requery

Je filtering hoeft ook niet met AND te beginnen, dus die heb ik ook weggehaald.

Michel
 
Bedankt voor het opschonen van de code. Toch gaat er nog iets mis. In het tekstvak komt ipv het juiste getal, de code te staan. Dus als ik op de knop druk staat er Select bla bla, kortom de hele code ipv de uitkomst. Heeft iemand daar enig idee voor
 
Dat gaat op deze manier niet lukken.
Stel de besturingselementbron van je veld in op

=DSum("naamvanjekolom"; "naamvanjetabel"; "zet hier je condities zonder WHERE ervoor")

Hoe je precies je besturingselementbron zou moeten instellen valt zonder verdere info/voorbeeldbestand onmogelijk te zeggen.

Grtz,

Tardis
 
Ik had niet zoveel tijd, dus ik heb alleen de code geschoond. De code die je maakt moet wel als Recordbron aan een object worden gehangen, en niet als Value. Dus bijvoorbeeld zo:

Code:
Dim strTabel1 As String
strTabel1 = "[InterneLeveringenBCNW]"
strSQL1 = "Select InterneLeveringenBCNW.Hoeveelheid * From " & strTabel1 & vbCrLf _
& "WHERE(([Datum]>=#" & Me.Startdatum.Value & "# And [Datum]<=#" & Me.Einddatum.Value & "#) " _
& "And ([Product]=Me.ProductID_NW) " _
& "And ([LocatieID]<>2) " _
& "And ([LeverancierID]=7)) "
Me.InternLev.[B]RecordSource[/B]= strSQL1
Me.Requery

Michel
 
@Michel,

en dat gaat dus op deze manier niet lukken.
De vraag is om een totaal weer te geven in een control ("formulierveld").
Een control heeft geen rijbron ;)

Grtz,

Tardis
 
Dat weten wij uiteraard ook! Ik ga er dan ook van uit, zonder het formulier erbij te hebben, dat de query op een keuzelijst hangt.
Om een resultaat in een tekstveld te krijgen, moet je een selectiestring maken, zoals hier dus wel gebeurt, waarna je de recordset opent, het resultaat op het tekstveld zet, de recordset weer sluit en vervolgens de db-links afsluit.

Michel
 
TS heeft het expliciet over een tekstveld.
De rest van je relaas volg ik niet.

Grtz,

Tardis
 
Laten we het weer eens over de topic hebben:
Om een waarde uit een query in een tektsveld te krijgen, moet de query door Access worden uitgevoerd.
Omdat de query afhankelijk is van gegevens uit het formulier, moet je die gegevens eerst hebben ingevuld, waarna je de query kunt bouwen en laten draaien.
Als laatste moet het resultaat van de quey weer worden teruggelezen, en in een tekstveld worden gezet.

Code:
Dim strTabel1 As String
Dim strSQL1 as String
Dim sWaarde as String
Dim dbs As DAO.Database
Dim rst As DAO.Recordset

	strTabel1 = "[InterneLeveringenBCNW]"
	strSQL1 = "Select InterneLeveringenBCNW.Hoeveelheid As Aantal * From " & strTabel1 & vbCrLf _
	& "WHERE(([Datum]>=#" & Me.Startdatum.Value & "# And [Datum]<=#" & Me.Einddatum.Value & "#) " _
	& "And ([Product]=Me.ProductID_NW) " _
	& "And ([LocatieID]<>2) " _
	& "And ([LeverancierID]=7)) "

	Set rst = dbs.OpenRecordset(strSQL1)
	rst.MoveFirst
	rst.Edit
	sWaarde = rst.Fields("Aantal").Value 
	rst.Close
	dbs.Close
	Set rst = Nothing

	Me.InternLev.Value= sWaarde

In deze code wordt de query gebouwd, met de code zoals we die nu hebben.
Vervolgens wordt een recordset gedefinieerd, en wordt de query geopend.
In de volgende stap (rst.Edit) wordt de recordset uitgelezen, en wordt de opgezochte waarde in een variabele gezet.
Daarna wordt de recordset gesloten, en wordt de variabele toegewezen aan het tekstobject.

Probeer dit eens uit?
Werkt overigens alleen als je ook de DAO bibliotheek hebt draaien, maar die staat standaard wel aan.

Michel
 
Laatst bewerkt:
@Michel,

dat kan dus ook anders en in mijn beleving veel makkelijker.
Jammer dat niet iedereen het gegeven is om buiten zijn eigen percepties te denken.

Zal je niet meer lastig vallen, gemiste kans om nog eens wat van anderen op te steken ;)

Grtz,

Tardis
 
@Tardis:
Je hoeft mij niet te overtuigen, want ik heb de vraag niet gesteld.... Als je een betere oplossing hebt, dan neem ik aan dat de vraagsteller er maar wat graag van zou horen. Al heb ik van jouw kant nog geen fatsoenlijke oplossing gezien... (maar dat is een heel andere discussie)

Mijn oplossing werkt, en is een stuk sneller dan DSum, dat je ook niet kunt gebruiken voor een gecombineerde filtering. Daarom doe ik het op deze manier. Maar ik houd mij altijd aanbevolen voor een betere oplossing, want je zult van mij niet horen dat ik de wijsheid in pacht heb. En ik maar denken dat we hier van elkaar kunnen leren...

Michel
 
Wat zaken die mij opvallen in dit 'draadje'

Mijn oplossing werkt, en is een stuk sneller dan DSum, dat je ook niet kunt gebruiken voor een gecombineerde filtering

Domain aggregate functies zijn in het algemeen een stuk trager dan recordsets. Als het gaat over één of een beperkt aantal records is het meetbare verschil nauwelijks aantoonbaar.

Filtering van domain aggregate functies kan net zo uitgebreid zijn als van recordsets

In de volgende stap (rst.Edit) wordt de recordset uitgelezen
Edit zet de recordset in ... edit mode, om een recordset uit te lezen hoeft alleen de recordset worden geopend.

Value is de 'default' eigenschap, en hoeft dus niet expliciet te worden vermeld

Wanneer in VBA wordt gefilterd op een datum moet die datum het amerikaanse datum formaat hebben (mm-dd-yyyy)

Als er gebruik wordt gemaakt van recordsets dan kun je het beste gebruik maken van de functie With ... End With
Dus ipv
Code:
	Set rst = dbs.OpenRecordset(strSQL1)
	rst.MoveFirst
	rst.Edit
	sWaarde = rst.Fields("Aantal").Value 
	rst.Close
	dbs.Close
	Set rst = Nothing

wordt het dan
Code:
With CurrentDB.OpenRecordset(strSQL1)
	sWaarde = !Aantal
End With
Dus geen declaratie van rst en dbs, en dus ook geen vrijmaken daarvan
 
Harry, bedankt voor de aanvullingen! Ze snijden op zich prima hout, al heb ik uiteraard ook wel weer een paar opmerkingen:

Code:
Value is de 'default' eigenschap, en hoeft dus niet expliciet te worden vermeld[/QUOTE]

De standaard instelling gebruiken is prima als je weet wat je doet, maar voor beginnende programmeurs is het wel zo jofel om de complete syntax te zien, zodat ze snappen wat er precies gebeurt. Hierdoor wordt het ook wat makkelijker te begrijpen als je eens iets anders wilt uitlezen, zoals de naam van een veld. Daarom gebruik ik ook vaak variabelen als tussenstap; dat hoeft vaak ook niet.

[QUOTE]Wanneer in VBA wordt gefilterd op een datum moet die datum het amerikaanse datum formaat hebben (mm-dd-yyyy)[/QUOTE]

Heb ik in een ander draadje onlangs nog uitgelegd:
ik zet een datum om naar een getal, en gebruik vervolgens CDate in de filtering om het getal weer terug te zetten naar een datum.
Iets als dit:

[CODE]sDatum = CDate(InputBox("Typ de datum:", "Datumselectie", Date))
iDatum = CDbl(sDatum)
strSQL = strSQL & "WHERE ([Datum]= cDate(" & iDatum & "));"

Verder zijn er uiteraard meerdere wegen die naar Rome leiden; je moet er gewoon eentje uitzoeken en daar een tijdje mee werken, en als je die doorhebt, kun je altijd nog kijken of het beter/sneller kan. Ik probeer zelf ook nog steeds allerlei zaken uit, omdat ik uiteraard ook lang niet alles weet...

Michel
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan