Access 2016. Formuier bij laden op bepaald ID openen

Status
Niet open voor verdere reacties.

KPTPTT

Gebruiker
Lid geworden
2 mrt 2018
Berichten
321
Hallo. Ik heb een voor mij lastige issue. Er zijn twee formulieren Werkorder en Verzamelstaat. Beide formulieren worden geopend vanuit het Access Navigatieformulier. Dit werkt uitstekend en is betrouwbaar is gebleken. Echter openen beide formulieren met de eerste ID van de tabel, ID=2.
Het zou mooi zijn als beide formulieren wederkerig openen op basis van het geselecteerde record ID van het andere formulier. Beide formulieren beschikken over een keuzevak waarin een willekeurig record kan worden gekozen bv. gegevens van record ID 119 c.q. [o_Opdracht ID].
Als form Verzamelstaat 119 worden getoond en via het Navigatieformulier Werkorder wordt gekozen, dan moet Werkorder 119 worden getoond en ook omgekeerd.
De huidige structuur is dat het Navigatieformulier het formulier opent en de VBA Private Sub Form_Load() wordt doorlopen echter met de eerste record ID (2).

Ik heb voor elkaar dat, dmv. Private Sub Form_Current() en string sFormulierid, zodra in één van de formulieren een selectie wordt gemaakt van een record, de string sFormulierid wordt geladen met de geselecteerde ID bv. sFormulierid heeft de waarde 119. Deze waarde is in beide formulieren beschikbaar. Hoe kan ik deze waarde toepassen om het geladen formulier te veranderen naar de waarde van sFormulierid?

Voorbeeld: In formulier Verzamelstaat record 119 gekozen en daarna omgeschakeld naar formulier Werkorder, daarna bij load Werkorder een foutmelding.
Formulier Verzamelstaat
Code:
Private Sub Form_Current()
             sFormulierid = Me.[o_Opdracht ID] 'Bij verandering in het keuzevak van record wordt sFormulierid geladen met current ID.
End Sub

Formulier Werkorder
Code:
Private Sub Form_Current()
           sFormulierid = Me.[o_Opdracht ID] 'Bij verandering in het keuzevak van record wordt sFormulierid geladen met current ID
End Sub

Code:
Private Sub Form_Load()
           Me.[o_Opdracht ID] = sFormulierid       'Dit werkt niet. Foutmelding "Kan veld niet bijwerken"
'Verdere invulling van het formulier Werkorder
End Sub

sFormulierid werkt goed. Deze string geeft steeds de goede waarde van de ID tussen de formulieren door.
Welke instructie kan ik toepassen bij het laden van het formulier? (Het is niet mogelijk meer om het laden van formulieren of het toepassen van Docmd OpenForm . . . te veranderen of toe te passen)
 
Zonder een bijgesloten voorbeeld is het lastig om je vraag goed te doorgronden.
Als ik het goed begrijp wil je een ander form openen met een id die in het actuele form staat.
Dit kan toch gewoon met een query die als basis het id heeft van te verbergen form.
 
Ik snap je werkwijze niet helemaal, maar de gebeurtenis <Bij laden> moet je in ieder geval niet gebruiken, want die wordt maar één keer uitgevoerd, als het formulier geladen wordt. En dat gebeurt bij jou maar één keer, en dan is er dus nog niks gekozen, en valt er ook niks te filteren.
Je zult een filter op het andere manier moeten zetten vanuit de twee keuzelijsten. Dus het andere formulier filteren vanuit de keuzelijst van het actieve formulier.
Overigens blijf je dit soort hele specifieke Access vragen in het algemene VBA forum zetten. Ontbreekt bij jou het Access forum? :D
 
Dank voor je bijdrage. Vanuit formulier Verzamelstaat wordt door een knop in het navigatieformulier automatisch het formulier Werkorder geopend c.q. geladen Vandaar "Load". Het wordt inderdaad maar eenmaal geladen met de begin ID (2) maar direct daarna moet de ID veranderd worden met de waarde van sFormulierid. Kan ik niets in de <Private Sub Form_Load()> plaatsen zodat bij het laden direct het ID wordt aangepast.

Ik dacht dat het een vraag VBA programmering betreft en niet een algemene Access vraag. Het blijft altijd lastig te bepalen welke rubriek maar vooral een goede titel van de vraag, zodat anderen er op kunnen zoeken.
 
Hallo,

ik denk dat je niet de ID wil aanpassen, maar de filter of de recordsource property. Je kan hiervoor de OnOpen event gebruiken en dan de bv. de recordsource aanpassen bv. me.recordsource = "select * from MyTable where ID = " & forms(MyForm).MyFieldName.
Als je spaties in de objectnamen hebt gebruikt (wat niet aan te raden is), moet je deze namen tussen vierkante haakjes zetten zoals [Mijn Veldnaam].
Of als je alleen een filter wil zetten, iets in de aard van:

Code:
        strFilter = "[MyField]= " & forms(MyForm).MyFieldName 
        Me.Filter = strFilter
        Me.FilterOn = True
 
Laatst bewerkt door een moderator:
Algemene VBA vragen zijn vragen m.b.t. loops bijvoorbeeld. Jij vraagt (consequent) zaken die specifiek met Access te maken hebben, en die horen dus in eerste instantie in het Access forum thuis. Kijk eens in het Excel forum, waar dezelfde methodiek wordt gebruikt (ook niet consequent overigens).
De Load procedure wordt maar één keer uitgevoerd, en is voor jou situatie dus onwerkbaar. Hetzelfde geldt voor de OnOpen event, die ook maar één keer wordt uitgevoerd. Zinloos dus om daar wat mee te doen, ook al omdat je beide formulieren tegelijk opent. Wat in mijn ogen overigens een zinloze actie is, omdat je maar één formulier tegelijk kunt bewerken. Zelfs als je beide formulieren op het scherm kunt zien, zijn de Load en Open gebeurtenissen zinloos, omdat je als deze worden uitgevoerd, nog niks hebt kunnen doen op het formulier. Ze openen dus altijd met het eerste record (dat in de recordset zit).

Kortom: de enige manier is degene die ik al aangaf: vanuit de keuzelijsten (op eender welk formulier) het andere formulier filteren. En dan niet op de manier die Noella aangaf, want die filtert het formulier van het actieve formulier, en dat is nu juist het formulier waarin je de keuze hebt gemaakt. Je moet dus het andere formulier filteren. Kan prima als je dat in een objectvariabele zet.
 
Verplaatst.
 
Voor de duidelijkheid: Myfield verwijst naar het veld met de opdrachtID in het formulier dat geopend wordt en forms(MyForm) moet natuurlijk naar het andere open formulier verwijzen.
Tip: je kan eerst testen of een formulier open staat via het SysCmd object : (form is open als SysCmd(acSysCmdGetObjectState, intObject, strName) <> 0 waarin voor een formulier intObject gelijk is aan acForm en strName de naam van het formulier is).

vrGroeten
Noëlla
 
Dank. Ik zie dat de moderator "ïets" heeft verplaatst, waarom? Mijn vraag betreft een vraag over VBA programmering, zoals Load van een formulier etc. Ik ben met de antwoorden een beetje het spoor kwijt. Ik heb een bestaande VBA programmering en die kan ik enigszins aanpassen op het vlak van de ID, grote veranderingen brengen in een bedrijfssituatie teveel risico mee. Ik nu misschien anders gekozen dan een navigatieformulier met eigen verborgen macro's.

Het Access navigatieformulier zorgt er automatisch voor, met onderliggende macro's of VBA, dat slechts één formulier tegelijk is geopend, Werkorder of Verzamelstaat. Beide formulieren worden geopend met < Private Sub Form_Load()> om wat knoppen etc. in het formulier te initialiseren. De macro van het navigatieformulier zorgt er voor dat het gekozen <object Formulier> (OBJECT) wordt geladen met de eerste ID van de query. Volgens mij kan ik niet bij de macro van de verzamelstaat om deze aan te passen. Ik zou deze willen overrullen met de ID waarde van de variabele sFormulierid. Hier staat de ID die bepaald is in het eerste formulier voordat wordt omgeschakeld naar het tweede formulier, bv. van Verzamelstaat naar Werkorder. Ik dacht misschien "iets" te doen met de instructie < Private Sub Form_Load()> (tussen de haakjes) om een filter te plaatsen met de gewenste ID van sFormulierid.
 
Hi,

wat je eerste vraag betreft: als alle Excel VBA vragen niet naar het excel forum moeten verplaatst worden, dan is het inderdaad wat verwarrend dat een Access VBA vraag niet in het VBA forum mag blijven.

Wat je VBA vraag betreft:
als de variabele sFormulierID beschikbaar is op het moment dat je het andere formulier opent kan je proberen om in the Onload of OnOPen event de volgende filter te zetten:

Code:
strFilter = "[MyField]= " & sFormulierID  
Me.Filter = strFilter
Me.FilterOn = True

Als je het probeert kan je ook een waypunt instellen en dan door de code steppen zodat je precies ziet wat er gebeurt (of niet gebeurt )
 
Ik kan het blijven zeggen, geloof ik: de Load of Open procedures doen helemaal niets, omdat je de formulieren al geopend hebt. Daarnaast worden die procedures uitgevoerd voordat de gebruiker iets uitvoert op een formulier. Vergeet deze procedures dus voor zover het deze vraag betreft.

Wat betreft het verplaatsen: ik ben het daar (zal je niet verbazen) helemaal mee eens, omdat formulieren in Access een specifiek Access onderdeel zijn. Deze formulieren zijn totaal niet te vergelijken (en te gebruiken) als formulieren in Excel of Word. Het VBA forum moet je gebruiken voor algemene programmeervragen, zoals de vraag hoe je een email adres kunt testen met VBA. En zelfs die functie is in Word, Excel of Access anders in de toepassing.

Wat betreft je vraag: heb je al gekeken naar mijn voorstel? Want dat kom ik in jouw antwoorden dus totaal niet tegen...
 
Dank. Ik heb vanuit de keuzelijsten een ID gedestilleerd. Dit ID heb ik beschikbaar in het te openen formulier. Het punt is dat ik in het navigatievenster geen mogelijkheid heb om in te grijpen in de VBA code. Het navigatieformulier zorgt er voor dat het formulier gepresenteerd wordt met de laagste ID. De Load procedure heb ik zelf toegepast om wat knoppen te initialiseren en komt dus niet vanuit het navigatieformulier. Ik kan ook geen Cmd.Open form met een filter gebruiken want dan krijg ik twee dezelfde formulieren te zien. Je schrijft: "Kan prima als je dat in een objectvariabele zet", maar hoe gaat dat in zijn werk?
 
Hallo,

één van de mogelijkheden is om via klasse modules je eigen data -objecten aan te maken, zodat je tussen de formulieren en de tabellen een data layer kunt maken (3-tier applicatie in plaats van 2-tier) zoals bv. in JAVA en C # applicaties. Dit maakt je front-end onafhankelijk van de database en kan je de back-end gemakkelijk switchen naar een ander database type (SQL, Oracle, XML,...). Bovendien kan je vanuit deze layer ook data synchroniseren.
Eenvoudiger kan je in het navigatie formulier (dat waarschijnlijk blijft openstaan) een extra eigenschap aanmaken OrderID of zo. Dit kan je dan zetten op het moment dat in één van de formulieren een ander record wordt gezocht, en meegeven op het moment dat je een nieuw formulier opent in de Onopen of Onload eigenschap. Als je meer dan één formulier tegelijk openhoudt en synchroon wil houden kan je bv. in beide formulieren een methode SyncOrder aanmaken dat de recordsource/filter van het formulier2 aanpast en opgeroepen wordt op het moment dat er zich een OnCurrent event in formulier1 voordoet.

Vriendelijke groeten
Noëlla
 
Het punt is dat ik in het navigatievenster geen mogelijkheid heb om in te grijpen in de VBA code.
Natuurlijk wel, waarom zou je geen VBA kunnen gebruiken op een navigatie formulier? Nogmaals: Load en OnOpen zijn nutteloos...
 
Tja, na zoveel antwoorden ben ik de weg kwijt. Er wordt gesproken over "Datalayer maken, etc.", Load en OnOpen is nutteloos, kan wel VBA toepassen, maar ik heb in item 12 gevraagd Hoe? Ik bedoelde te zeggen dat het navigatieformulier een eigen onderliggend mechanisme heeft, en daar kan ik niet bij. Dus moet ik wat anders verzinnen, maar concreet hoe?
Dit kan je dan zetten op het moment dat in één van de formulieren een ander record wordt gezocht
. Het navigatieformulier doet de ID setting onderliggend en dat kan ik niet beïnvloeden. Kortom, ik denk dat het niet gaat worden wat ik zou willen en besluit het zo te laten zoals het nu is. Een ieder bedankt voor het meedenken.
 
Tja, zonder voorbeeldje kunnen we weinig doen qua help. Ik werk eigenlijk zelf nooit met het Navigatieformulier (zie het nut er niet van in), maar heb er ooit wel een gemaakt voor een klant en die doet perfect wat ik wil :). Het ligt dus niet aan de techniek.
 
Dag KTTPT,

het navigatieformulier kan dan wel een eigen werking hebben, maar je kan het waarschijnlijk wel openen in het VBA venster. Je hoeft niet aan het bestaande mechanisme te komen, maar je kan waarschijnlijk wel dingen toevoegen. Je kan in de publieke sectie van dat formulier een nieuwe property aanmaken door:
- maak in de algemene (general) sectie een private variabele toe bv. lngOrderID
- maak in dezelfde sectie een property procedure dat deze variabele uitleest (de get procedure) of zet (de let procedure)
Als je niet vertrouwd bent met eigenschaps procedures kijk naar : https://sourcedaddy.com/ms-access/using-property-procedures.html of voeg gewoon een publieke variabele lngOrderID toe. Deze werkt in principe dan ook als een nieuwe formulier eigenschap, maar zonder extra kontroles.
Je zorgt ervoor dat dit navigatieformulier steeds in de achtergrond open staat (wat waarschijnlijk reeds zo is). Je kan deze ID dan uitlezen in andere formulieren als elke andere eigenschap van het formulier als als Forms("NaamNavigatieform").OrderID

Om het formulier Werkorder te openen met de focus op dit ID zet je in de OnOPen of Onload van het Werkorder formulier (persoonlijk werk ik liever met OnOPen) :

**Eventueel doe je een kontrole dat het navigatieformulier wel degelijk openstaat zoals ik in een eerdere respons heb aangegeven
Code:
If Forms("NaamNavigatieform").OrderID > 0 then
**'zet hier de filter of recordsource property op de juiste ID
End If

Op het moment dat je een nieuw record navigeert (de OnCurrent event van het formulier Werkorder) zet je:
Code:
Forms("NaamNavigatieform").OrderID = me.[NaamWerkorderIDControl]

In het tweede formulier doe je hetzelfde. Dit zou ervoor zorgen dat een formulier opent met hetzelfde ID als het vorige formulier.

Wil je 2 reeds openstaande formulieren blijvend synchroniseren, dan schrijf je in elk formulier een extra methode SyncForm dat de filter of recordsource met de navigatie OrderID synchroniseert (ongeveer zelfde code als in de OnOPen/OnLoad) en die je in de OnCurrent event van de formulieren schrijf je een publieke methode die:
-eerst controleert of het andere formulier openstaat
- als dit zo is de SyncForm methode van dat andere formulier oproept.

Vriendelijke groeten
Noëlla
 
Laatst bewerkt door een moderator:
Hallo,

ik heb deze middag eens in mijn oude voorbeelden gesnuffeld, en het bijgesloten voorbeeldbestand opgekuist en in 2016 formaat opgeslagen. Mijn excuses als er nog wat fouten mochten inzitten, het maakte deel uit van een groter geheel en ik heb het proberen te vereenvoudigen, maar volgens mij doet dit wat je vraagt.
 

Bijlagen

  • Database1.zip
    39 KB · Weergaven: 77
@Noella: ik heb je voorbeeldje bekeken, maar dit is geen navigatieformulier :). Wél de werkwijze die ik ook in essentie gebruik, dus met aparte formulieren die los starten. En die dus veel makkelijker werken, en minder heisa opleveren dan die (volgens mij voor beginnelingen bedoelde) navigatieformulieren. Die dan overigens best handig werken. Mits je dus niks extra's wilt. En daar gaat het dan vaak gelijk fout. Zeg maar: mensen die een volautomatische camera willen voor kiekjes, en zich dan verbazen dat ze geen HDR opnames kunnen maken in een door hunzelf in te stellen aantal opnames en belichtingsrange :D.
 
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan