Maatwerk Posted May 12, 2004 Posted May 12, 2004 Ik zoek naar een goed alternatief voor het automatisch genereren van serienummers. In eerste instantie heb ik geprobeerd via de functie Max(selfjoin) +1. Echter het gaat hier om een grote database met ca 20000 record. En werkt zeer vertragend. Ook wil ik graag het serienummer resetten. Dus bv. van 1000 naar 1500. Is er een alternatieve manier om unieke serienummer te genereren. B.v. via een globale variabele? Quote
0 Dr_Flash Posted May 12, 2004 Posted May 12, 2004 Je kunt als je in je invoer-layout staat, klikken met rechts op een numeriek veld, en kiezen "replace contents..." met de optie "replace by serial numbers" en vervolgens in je velddefinities Auto-enter serial number doen. Hoezo zoek je daar een alternatief voor als ik vragen mag? Wat is er mis met de "normale" methode? Resetten zou je dan met een scriptje kunnen doen: Show all records Go to record [First] Loop Set field [serienummer; Serienummer + 500] Go to record [Next; exit if last] End loop Bijvoorbeeld Vergeet niet om tijdelijk je validatie van het veld Serienummer af te halen, tussendoor kom je natuurlijk wel dubbele serienummers tegen in jouw geval..... Quote
0 Maatwerk Posted May 12, 2004 Author Posted May 12, 2004 Wat er mis is met de normale methode? Ik werk aan een app. waar nogal veel maatwerk bij komt. Dus vaak aanpassingen in de database structuur... Dat betekend dat ik regelmatig een import moet draaien. Op zich zelf werkt dit wel redelijk echter ik moet dan zorgen dat het serienummer elke keer weer juist word opgehoogd. Om dat ik bij de autoenter optie bij importeren heb uitgeschakeld. Hij overschrijft anders mijn oude serienummers. Voor wat betreft het resetten bij ik een beetje vaag geweest. Wat ik wil is dat de oude serienummers ongemoeid worden gelaten. Ik wil dus dat na het resetten de unieke nummering start van bv 10000 naar 15000. Quote
0 Nico Posted May 12, 2004 Posted May 12, 2004 Ik weet niet of je met Filemaker 6 werkt. Zo ja dan zou je een script kunnen maken dat na de import sorteerd op het serienummer. Vervolgens ga je naar het laatste record en zet het serienummer in een globaal veld, pakt de script stap 'Volgende volgnummer invoeren', met als waarde het globaal veld + 1 Misschien dat dat iets is? Quote
0 Henk R Posted May 12, 2004 Posted May 12, 2004 In één van mijn databasefiles moet ik kiezen tussen 2 soorten records, Voor elk soort record moet bij het laatste nummer 1 worden opgeteld. Om dit op te lossen heb ik 5 velden gemaakt. 1 voor elk soort record met het volgnummer, 1 die voor deze serie de hoogste waarde geeft en 1 berekeningsveld dat de juiste waarde in elke layout laat zien. Om de snelheid er in te houden heb ik een extra veld met de keuze ja/nee wat bijhoud welke records meedoen voor de telling. Ja wel en nee dus niet. Een script stuurt de aanmaak van records aan, zoekt alle ja's op, Maakt een nieuw record (vraagt om het soort record) en pakt het hoogste nummer voor het juiste soort record en verhoogt dit met 1 In jou geval gaat het maar om 1 nummer dat moet doorlopen dus je zou met minder velden toe kunnen Quote
0 Theo Tromp Posted May 12, 2004 Posted May 12, 2004 als je bij het toevoegen van een nieuw record een script uitvoert kan je in het script de nieuwe volgnummer berekenen. Zet het hoogst gebruikte nummer in een record in een (algemeen) bestand met slechts 1 record. Direct nadat je het record hebt opgehoogd moet je natuurlijk ook het volgnummer met 1 ophogen in het algemene bestand. Om te voorkomen dat je een record lock krijgt moet het algemene record niet door iemand kunnen worden vastgezet (dus nergens op een layout zetten behalve de layout hieronder beschreven). Omdat het nog steeds mogelijk is dat twee personen tegelijkertijd het nummer ophogen moet je in het script wel zorgen voor een record lock. Script ophogen bestand (staat in Algemeen bestand) Set error capture OFF (Anders werkt de record lock niet!) Ga naar Layout "Blokkeer algemene record" Ga naar Veld "Hoogste waarde" (kan maar op 1 terminal tegelijk) Veld instellen "Hoogste waarde" + "Hoogste waarde +1" Veld instellen "Globaal hulpveld" = "Hoogste waarde" Exit Record Vervolgens wordt de waarde van het globale veld overgezet naar het volgnummerveld. Quote
0 Maatwerk Posted May 12, 2004 Author Posted May 12, 2004 Bedankt Theo! Maar wat gebeurt er wanneer 2 gebruikers op het zelfde moment een record toevoegen? We spreken hier over een MultiU situatie. Als 2 gebruikers op het zelfde moment het veld "Hoogste waarde" willen instellen. Dan krijg je toch een recordlock voor dit veld? Werkt dit bij jou ook in een multiU situatie? Quote
0 Theo Tromp Posted May 13, 2004 Posted May 13, 2004 Inderdaad moet je daar rekening mee houden. In de door mij gegeven oplossing wordt dat gedaan doordat je de hoogste waarde overzet naar een GLOBAAL veld. Het ophogen van het nummerveld (Algemeen bestand) kan maar op 1 scherm tegelijk plaatsvinden. De cursor staat in het veld op de daarvoor gecreerde layout (Blokkeer algemene record). Vervolgens wordt het nieuwe hoogste nummer in het globale veld geplaatst. Pas daarna wordt het script en daarmee ook het algemene bestand verlaten. Het moment van verlaten van het record is gemarkeerd met Exit Record statement - dit statement is echter niet strict noodzakelijk omdat het record automatisch wordt verlaten bij het verlaten van het bestand. Pas na EXIT Record kan een andere gebruiker het nummerveld aanpassen. Het kan dus zijn dat één van de twee gebruikers een fractie van een seconde moet wachten. Dat merkt die gebruiker niet. En als het record om de een of andere reden toch niet vrij is gegeven (iemand staat toch in een veld van het record) dan verschijnt er een melding dat het record niet beschikbaar is. Deze melding verschijnt alleen als SET ERROR CAPTURE OFF is uitgevoerd (weliswaar is dit de standaard setting, voor de duidelijkheid heb ik het wel toegevoegd aan het script). Is het zo duidelijker? Quote
0 AvD Posted May 13, 2004 Posted May 13, 2004 (edited) Het kan dus zijn dat één van de twee gebruikers een fractie van een seconde moet wachten. Dat merkt die gebruiker niet. Moet hij gewoon wachten - gelukkig zonder dat hij het merkt - of wordt die scriptstap voor hem dan als niet uitvoerbaar overgeslagen? De Kazar-methode checkt binnen een loop met wachttijd 1 sec op Error 301. Is dat dan niet nodig? Dat zou een hele verademing zijn, maar ik zou het wel graag zeker weten! Edited May 13, 2004 by Guest Quote
0 Stef Posted May 13, 2004 Posted May 13, 2004 Ik ben praktisch overtuigd dat je hier nog een loop moet inbouwen, Theo! Zonder dit gebeurt er verder niets! Aan André: waarom pause met 1 sec? Hoeft toch niet? Ik denk deze manier: -loop -gotofield "hoogste nummer" -exit loop if (status current error = 0) -end loop ...en dan de rest HTH Stef Quote
0 Theo Tromp Posted May 13, 2004 Posted May 13, 2004 ik heb mijn oplossing niet getest. Tot nu toe dacht ik dat bij een record lock het systeem zelf gaat wachten en na enkele seconden een boodschap geeft aan de gebruiker welke terinal het record nog bezet houdt. Let op: wel SET ERROR CAPTURE OFF gebruiken. De loop-oplossing werkt natuurlijk ook. Quote
0 Rony Rabijns Posted May 13, 2004 Posted May 13, 2004 -loop -gotofield "hoogste nummer" -exit loop if (status current error = 0) -end loop ...en dan de rest Stef, Moet rond deze loop geen SetErrorCapture(On) geplaatst worden. Anders kan je toch die foutmelding niet afvangen ? dus : set error capture on ... de loop Set error capture off Quote
0 Maatwerk Posted May 13, 2004 Author Posted May 13, 2004 De Kazar-methode checkt binnen een loop met wachttijd 1 sec op Error 301. Is dat dan niet nodig? Dat zou een hele verademing zijn, maar ik zou het wel graag zeker weten! De Kazar-methode? Can somebody enlighten me? Quote
0 Rony Rabijns Posted May 13, 2004 Posted May 13, 2004 De Kazar-methode checkt binnen een loop met wachttijd 1 sec op Error 301. De Kazar-methode? Can somebody enlighten me? Beste Maatwerk, het is precies deze methode die hierboven wordt uitgelegd, zij het bloemlezingsgewijs door AvD en scripttechnisch door o.a. Stef. Quote
0 AvD Posted May 13, 2004 Posted May 13, 2004 (edited) De Kazar-methode dus: de grote Ilyse Kazar (foto van deze schitterende dame elders op dit forum*) liet op 25 oktober 1999 het licht schijnen op de hele FileMaker-gemeenschap door dé methode voor Auto-entering ID's te publiceren op Blue World: Example (in external file where "next serial" is stored): Loop Go To Field [Nextserial] Exit Loop if [status(CurrentError) <> 301 Pause/Resume [0:00:00] End Loop Set Field [gSerial in your main file, NextSerial] Set Field [NextSerial, NextSerial + 1] Nu ik het terugzie, zie ik ook dat de wachttijd van 1 seconde niet nodig is. Je kan blijkbaar ook 0 seconden wachten en toch nog wachten. Ik zal daar aan denken als ik nog eens met bloemen onder een lantaarnpaal sta. Maar we wijken af. ---------- Tot op dit moment al 408 keer bekeken! Edited May 27, 2004 by Guest Quote
0 Maatwerk Posted May 14, 2004 Author Posted May 14, 2004 Aangezien ik een bestaande appl. zit om te bouwen in filemaker 7 kan ik gebruik maken van de nieuwe scriptstap: "Set Next Serial Value". Import Records [Restore, No Dialog] Go To Record [Last] Set Next Serial Value ["Volgnummer", "Volgnummer" + 1] Quote
0 Sanne Posted May 14, 2004 Posted May 14, 2004 Nou , ik zal het maar heel zachtjes zeggen: De scriptstap "Set Next Serial Value" was ook in versie 6 al aanwezig Quote
0 JeanWM Posted May 14, 2004 Posted May 14, 2004 Indien je zo'n 'systeem' dikwijls gebruikt, kun je evengoed een afzonderlijk bestand hebben vanwaaruit je de 'sequence' haalt via een 'sequence sleutel'. Bv : de eerstvolgende waarde moet 1 groter zijn, de eerstvolgende moet 5 groter zijn, om de drie volgende 1 groter.... enkel de pare/onpare moeten 1 groter zijn....mogelijkheden genoeg.... Dat gebeurt dmv een calculatie en 3 velden - low, next en step....en een relatie... Zo kun je oa 'problemen' vermijden bij het ex- importeren... Maar dat is misschien wat te veel gevraagd.... Quote
0 Maatwerk Posted May 24, 2004 Author Posted May 24, 2004 Ik heb toch gekozen voor de "Kazar-methode". Nu alleen afwachten hoe het een en ander werkt in een multi-u omgeving... Quote
0 Koen Van Hulle Posted May 27, 2004 Posted May 27, 2004 Dit is inderdaad een leuke methode maar vaak wat omslachtiger dan nodig. Ik zoek naar een goed alternatief voor het automatisch genereren van serienummers. In eerste instantie heb ik geprobeerd via de functie Max(selfjoin) +1. Echter het gaat hier om een grote database met ca 20000 record. En werkt zeer vertragend. Ook wil ik graag het serienummer resetten. Dus bv. van 1000 naar 1500. Als je nu eens die relatie aan sort geeft waarbij je een omgekeerde sort op je serienummer plaats dan kun je gewoon de volgende functie toepassen selfjoin:serienummer + 1 Hierbij gaat hij de waarde van het eerste gerelateerde record gebruiken, in ons geval zal dat door de sortering op de relatie, het record met het hoogste serienummer zijn. Truukje blijft werken ook als je sprongen naar omhoog wenst te maken. Stel dat je elk jaar een reset doet van je nummering zou je ook hier weer de relatie kunnen sorteren op jaar en serienummer ... Koen Quote
0 Maatwerk Posted May 27, 2004 Author Posted May 27, 2004 Hierbij gaat hij de waarde van het eerste gerelateerde record gebruiken, in ons geval zal dat door de sortering op de relatie, het record met het hoogste serienummer zijn. Truukje blijft werken ook als je sprongen naar omhoog wenst te maken. Koen Interessante methode Koen! Welke methode gebruik je dan om het serienumummer te resetten met een sprong van bv 1000 naar 1500? Quote
0 AvD Posted May 27, 2004 Posted May 27, 2004 Dit is inderdaad een leuke methode maar vaak wat omslachtiger dan nodig. Ik zou blij zijn als dit waar is (ik zeg niet: "was"!). Maar... hoe gedraagt deze methode zich in een multi-user omgeving met zeer intensief gebruiksprofiel? Hoe groot is de kans op "dubbele" nummering? Is dit "certified" en 100 percent betrouwbaar? Niet dat ik van Kazar vanaf wil, integendeel - 't is een fantastisch mens - maar dit lijkt me beter, tenminste... indien het werkt in alle omstandigheden. Please, Murtje, zeg dat het waar is! Quote
0 Stef Posted May 27, 2004 Posted May 27, 2004 Ik heb Murtjes techniek al eens in een ver verleden toegepast. Absoluut niet aan te raden, Filemaker is hier met duizenden records véél te traag voor, en dit is alleen maar erger geworden in FM7. 't Is nu eenmaal geen Oracle of SQL. Volgens mij is de enige goede oplossing een apparte tabel met jaar en nummer die op de juiste manier gelocked wordt. HTH Stef Quote
0 Maatwerk Posted May 27, 2004 Author Posted May 27, 2004 Dat kan ik dus niet gebruiken. Mijn opdrachtgever heeft een database van ca 9000 relaties gemiddels 50 projecten per klant. Quote
0 Koen Van Hulle Posted May 28, 2004 Posted May 28, 2004 Ik kan alleen maar beamen dat de "Kazar methode" de betere methode is hoor. Ik heb bij een bulk van data nog nooit dubbelesleutels mogen ervaren op deze manier. Wat betreft dat sprongetje maken, zodra je een record een waarde 1500 hebt gegeven zal die uiteraart groter zijn dan 1000 en door de sortering over de relatie bovenaan komen te staan. Weet ook dat de Kazar methode niet meer zal werken in FileMaker 7 omdat die op een andere manier record-locking doet. Een "go to field" zal dus geen fout boodschap geven. Ik post hier nog wel eens een voorbeeldje hoe je het dan wel kan simuleren. Koen Quote
0 AvD Posted May 28, 2004 Posted May 28, 2004 Ik post hier nog wel eens een voorbeeldje hoe je het dan wel kan simuleren. Kan je dat al vrij vlug doen? We zijn echt benieuwd - in de meest letterlijke zin van het woord! Dank! Quote
Question
Maatwerk
Ik zoek naar een goed alternatief voor het automatisch genereren van serienummers.
In eerste instantie heb ik geprobeerd via de functie Max(selfjoin) +1.
Echter het gaat hier om een grote database met ca 20000 record. En werkt zeer
vertragend. Ook wil ik graag het serienummer resetten. Dus bv. van 1000 naar
1500.
Is er een alternatieve manier om unieke serienummer te genereren. B.v. via een
globale variabele?
30 answers to this question
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.