Searchdialogs zijn ontstaan uit een idee van Eric ten Westenend om op een eenvoudige manier zoekfaciliteiten in een database applicatie in te kunnen bouwen. Niet meer steeds opnieuw een zoekscherm porgrammeren, niet meer telkens op een andere manier zoeken, niet meer per applicatie een andere oplossing maken. Een uniforme manier van zoeken die voor de gebruiker prettig werkt en voor de programmeur gemakkelijk is om in te bouwen.
Hoewel Eric zijn idee tot een goed niveau heeft uitgewerkt zag ik nog mogelijkheden tot uitbreiding en wilde ik ook andere Delphi ontwikkelaars gebruik kunnen laten maken van deze krachtige oplossing. Met Erik Stok search dialogs is dit een feit geworden.
Dit document beschrijft het volgende:
Download
Installatie
Het gebruik
De components
Voorbeelden
Versie historie
De nieuwste versie van ErikStok search dialogs is hier te downloaden.
Pak het bestand uit op een locatie naar keuze. Open het package EstSearchDialog.dpk en compileer dit. Open vervolgens het package EstSearchDialogDesignTime.dpk en installeer dit.
Open vervolgens voor de data access layer naar keuze het runtime package (voor ADO is dit bijvoorbeeld EstSearchDialogAdo.dpk) en compileer dit. Open vervolgens het designtime package voor de data access layer (voor ADO is dit bijvoorbeeld EstSearchDialogAdoDesignTime.dpk) en installeer dit.
Op het component palette zijn op de tab Erik Stok de search dialog components te vinden voor alle data access layers waarvoor geïnstalleerd is.
Het searchdialog is een non-visual component dat op een willekeurige plaats in de applicatie door middel van Execute kan worden aangeroepen om de gebruiker een zoekmogelijkheid aan te bieden. De Execute method geeft via zijn result terug of de gebruiker iets gevonden heeft of niet. Door middel van de ResultFieldAs... functies kan vervolgens informatie worden vekregen over het record wat de gebruiker gevonden heeft.
De basis van het zoeken is een door de programmeur te maken query. Dit kan een eenvoudige query op een enkele tabel zijn, maar er kunnen ook verschillende gegevens bij elkaar gezocht worden om de gebruiker uit deze gecombineerde gegevens te laten kiezen. De programmeur kan bepalen op welk van de velden uit de query gezocht mag worden.
Een groot probleem bij het aanbieden van dergelijke flexibele zoekfunctionaliteit is performance van de database. Een gebruiker zou een query kunnen starten die heel veel records oplevert. Daarom is de mogelijkheid toegevoegd om een maximum aantal resultaatrecords in te stellen. Indien er een maximum is ingesteld, wordt eerst gecontroleerd hoeveel records een zoekopdracht oplevert. Alleen indien die maximum niet bereikt wordt zal de zoekopdracht worden uitgevoerd. Anders krijgt de gebruiker een melding nauwkeuriger zoekspecificaties op te geven.
Ook is het niet altijd wenselijk dat gebruikers ontzettend veel combinaties van zoekcriteria kunnen maken. Daarom is er de mogelijkheid om het aantal zoekcriteria dat een gebruiker kan toepassen te beperken.
De componenten die beschikbaar zijn, zijn allemaal afgeleid van hetzelfde basiscomponent: TEstSearchDialog. Voor de data access layers BDE, DB Express, ADO, Interbase Express, Zeos, NexusDB en FlashFiler zijn implementaties gemaakt.
De componenten hebben de volgende properties:
Designtime
AdditionalWhere |
Als aan de uiteindelijke zoekquery nog een additionele where clausule toegevoegd moet worden dan kan dit via deze property worden gedaan. Dit kan bijvoorbeeld worden gebruikt als voor het starten van het searchdialog al bekend is dat het resultaat op bepaalde waarden gefilterd moet worden. Via deze property kan dan zonder de SearchQuery property aan te passen de resultaatset worden beperkt. |
CompareFormatDate |
Databases maken verschillende vergelijkingen als het datum velden betreft. De ene database vergelijk een datumveld in YYYMMDD formaat (zonder quotes), de ander verwacht 'M/D/YYYY' of zelfs #DDMMYYYY#. Om dit flexibel in te kunnen stellen kan via CompareFormatDate de formatting string die gebruikt wordt met de FormatDateTime functie die wordt toegepast op de te zoeken datumwaarde worden gemanipuleerd. Let er op dat als een database quotes verwacht bij het vergelijken van de waarde, deze dienen te worden aangegeven via de QuotedDateTime property. Let er ook op dat een / betekent: de date separator. Wil je een letterlijke /, gebruik dan '/'. |
CompareFormatTime |
Als CompareFormatDate, maar dan voor tijd vergelijkingen. |
CompareFormatDateTime |
Als CompareFormatDate, maar dan voor velden die zowel een datum als een tijd bevatten. |
Connection |
Dit is de database connection waarmee het search dialog naar de database verbindt. Voor de verschillende data access layers zijn dit verwijzingen naar de verschillende connection componenten (TSQLConnection, TAdoConnection, TIBDatabase etcetera). |
CountQuery |
Dit is de query waarmee een eventuele telling van het aantal records wordt gedaan als de Max property op een andere waarde dan 0 staat. Deze kan designtime het beste worden ingesteld via de component editor of de property editor van de SearchDialogFieldList property. Het is van belang dat de CountQuery qua velden en aliassen overeenkomt met de SearchQuery, omdat dezelfde WHERE clausule wordt opgebouwd als bij de SearchQuery. |
CriteriaCount |
Dit is het aantal zoekcriteria waarmee het searchdialog initieel opent. Dit kan nooit meer zijn dan MaxCriteria. Indien ervoor is gekozen om de laatste zoekopdracht op te slaan door middel van de instelling van de Store property, dan wordt CriteriaCount hierdoor overschreven. |
DecimalChar |
Decimaal teken dat in de SQL query gebruikt wordt voor float fields. |
DialogCaption |
Caption die boven het search dialog komt te staan. |
DialogHeight |
Hoogte van het dialog. Indien dit op 0 gezet wordt heeft het dialog de standaard hoogte. |
DialogWidth |
Breedte van het dialog. Indien dit op 0 gezet wordt heeft het dialog de standaard breedte. |
Max |
Dit is het maximum aantal resultaatrecords dat een zoekopdracht mag opleveren. Indien er meer records dan het gegeven aantal wordt gevonden, dan wordt de gebruiker verzocht nauwkeuriger zoekcriteria op te geven. Als Max op een andere waarde dan 0 gezet is, moet ook de CountQuery ingevuld zijn. Als Max op 0 gezet wordt dan is er geen maximum aantal records (de standaard instelling). |
MaxCriteria |
Dit geeft het maximum aantal criteria aan waarop een gebruiker mag zoeken. |
QuoteChar |
Het teken wat gebruikt wordt om bij het zoeken op string waarden om de string heen te zetten in de WHERE clausule die wordt opgebouwd. Sommige databases verwachten " in plaats van ' en dat kan via deze property worden ingesteld. |
QuotedDateTime |
Als de datumvergelijking van de database op basis van een quoted string van de datumwaarde gebeurd (voor de meeste databases is dit het geval), dan dient deze property op True te worden gezet. |
RegistryPath |
Indien via de Store property is ingesteld dat de laatste zoekopdracht moet worden opgeslagen, dan kan via de RegistryPath property worden ingesteld waar onder HKEY_CURRENT_USER deze instellingen moeten worden opgeslagen. Als hier niets worden ingesteld, dan wordt gebruik gemaakt van HKEY_CURRENT_USER\Software\ErikStok\<FormClass>\<ComponentName>. |
SearchDialogFieldList |
Een collection van velden waar het search dialog gebruik maakt. Per veld kunnen verschillende eigenschappen worden ingesteld. De FieldName van een veld bepaald welke veldnaam in de door de gebruiker opgegeven query overeenkomt met dit veld. De WhereSyntax is de naam van het veld in de query inclusief eventuele veld-aliassen zoals het veld in een WHERE clausule zou worden genoteerd. Het DisplayLabel is de kop boven de resultaatgridkolom van het betreffende veld en de DisplayWidth is de breedte van die kolom. Het FieldType bepaald welk soort veld het betreft en dus op welke waarden gezocht kan worden met behulp van dit veld. Via Search kan worden aangegeven of op het betreffende veld kan worden gezocht of dat het veld alleen in het resultaat wordt weergegeven. |
SearchQuery |
Dit is de query waarmee het daadwerkelijke resultaat wordt bepaald. Deze kan designtime het beste worden ingesteld via de component editor of de property editor van de SearchDialogFieldList property. Aan deze query wordt aan de WHERE clausule een reeks condities toegevoegd op basis van de door de gebruiker opgegeven zoekopdracht. Dit gebeurt door een where tag, %WHERE%, te vervangen door een where clausule. |
SearchStyle |
Het is mogelijk om de zoekactie niet modaal te laten verlopen door deze property aan te passen. Als SearchStyle op ssNormal gezet wordt, dan wordt het dialog niet modaal getoond. Met de waarde ssMDIChild kan het dialog zelfs als MDIChild form worden getoond (voorwaarde is dan natuurlijk wel dat er een MDIForm aanwezig is). Als er gekozen wordt voor ssNormal of ssMDIChild, dan geeft de Execute method altijd False terug. Via het OnSelect event kan worden afgehandeld dat een gebruiker iets gevonden heeft. Via het OnClose event kan worden afgehandeld dat de gebruiker het dialog gesloten heeft. |
StartOpen |
Door deze property te zetten start het dialog met een resultaat op basis van de query met in de WHERE clausule de TrueExpression en eventuele AdditionalWhere. Pas op met deze property, het kan ervoor zorgen dat er veel dat overgehaald wordt. Tevens kan het een conflict met Max veroorzaken. |
Store |
Via Store kan worden ingesteld of en hoe de laaste zoekopdracht moet worden opgeslagen. Er gekozen worden voor dsNone (de laatste zoekopdracht wordt niet opgeslagen), dsFields (alleen de veldselectie van de laatste zoekopdracht wordt opgeslagen) en dsFieldsAndValues (zowel de veldselectie als de ingevulde zoekwaarden worden opgeslagen. De laatste zoekopdracht wordt opgeslagen in de registry op de locatie die is ingesteld via de RegistryPath property. |
TrueExpression |
Indien bij het vaststellen van de where clausule geen enkel zoekcriterium wordt vastgesteld (treedt alleen op in designtime of als StartOpen gezet is) wordt de where clausule gevuld met de waarde van deze property. Op deze manier is het mogelijk om queries designtime te openen en een resultaat te bepalen. |
Runtime
ResultQuery |
Na het uitvoeren van een zoekopdracht kan via de ResultQuery property worden bepaald welke query gebruikt is om tot het resultaat te komen waaruit de gebruiker een resultaat gekozen heeft. |
Execute |
Via de Execute method wordt het search dialog opgeroepen. Indien de gebruiker het dialog afsluit met OK (dan is er altijd een record geselecteerd) geeft de method True terug. Indien de gebruiker het dialog afsluit met Cancel geeft de method False terug. Als is ingesteld via de SearchStyle property dat het dialog niet modaal getoond moet worden dan geeft Execute altijd False terug en zal met behulp van OnSelect en OnClose het resultaat moeten worden uitgevraagd. |
ResultFieldAsString |
Van het door de gebruiker geselecteerde record kunnen veldwaarden worden opgevraag met de ResultFieldAs... methods. Deze method wordt gebruikt om de waarde van string velden uit het resultaatrecord te lezen. |
ResultFieldAsInteger |
Als bij ResultFieldAsString, maar deze method wordt gebruikt om de waarde van integer velden uit het resultaatrecord te lezen. |
ResultFieldAsFloat |
Als bij ResultFieldAsString, maar deze method wordt gebruikt om de waarde van float velden uit het resultaatrecord te lezen. |
ResultFieldAsDateTime |
Als bij ResultFieldAsString, maar deze method wordt gebruikt om de waarde van datetime velden uit het resultaatrecord te lezen. |
ResultFieldExists |
Er kan worden gekeken of een veld bestaat in het resultaatrecord. |
FullRegistryPath |
Als het registrypath waar de Store property gebruik van maakt tijdens runtime moet worden uitgelezen dan kan van deze method gebruik gemaakt worden. |
OnAfterExecuteCountQuery |
Dit event treedt op net nadat de telling is uitgevoerd. |
OnAfterExecuteSearchQuery |
Dit event treedt op net nadat de zoekopdracht is uitgevoerd. |
OnBeforeExecuteCountQuery |
Dit event treedt op net voordat de telling wordt uitgevoerd. |
OnBeforeExecuteSearchQuery |
Dit event treedt op net voordat de zoekopdracht wordt uitgevoerd. |
OnClose |
Dit event treedt op als het dialog gesloten wordt. Via dit event kan worden vastgesteld dat de gebruiker is gestopt met het selecteren van records bij dialogs met een SearchStyle anders dan ssModal. |
OnFilterRecord |
Dit event werkt net als het OnFilterRecord event op een dataset, alleen in dit geval betreft het de dataset van het searchdialog resultaat. |
OnInitControls |
Dit event treedt op als er een veld of vergelijking geselecteerd wordt door de gebruiker. |
OnSelect |
Dit event treedt op als er een record geselecteerd wordt bij een dialog met een SearchStyle anders dan ssModal. |
In de map EstSearchDialogDemo van de download staat een demo applicatie die de mogelijkheden laat zien. Voor deze demo wordt gebruik gemaakt van de DBDemos Access database via ADO, dus deze database moet beschikbaar zijn en de ADO variant van het EstSearchDialog moet geïnstalleerd zijn om deze demo te kunnen uitvoeren.
02-01-2004: Momenteel bevinden de componenten zich nog in Alpha fase.
04-01-2004: Overgestapt naar andere koppeling met de BDE. Alias als string wordt
nu gebruikt.
11-01-2004: Diverse fixes gemaakt, AdditionalWhere, events en special date values
toegevoegd.
12-01-2004: Verschillende bugfixes gedaan en DecimalChar property toegevoegd.
18-01-2004: Er kan nu ook niet modaal gezocht worden met gebruik van de SearchStyle
property. Demo toegevoegd.
24-01-2004: Er is nu ook engelstalige documentatie beschikbaar.
28-01-2004: Bugfixes op sluiten via X en ontrekende properties in AssignTo.
05-05-2004: Toevoeging van TEstSearchDialogInternational voor vertalingen.
18-06-2004: Toevoeging van InitControls en SearchCase.
Met dank voor de bijdrage van: Alice Dijkstra, Frank van Boven en Marc Geldon.