Hallo

Welkom, Gast. Alsjeblieft inloggen of registreren.

Recent

376 gasten, 0 leden

Welkom, Gast. Alsjeblieft inloggen of registreren.

29 maart 2024, 12:32:54

Login met gebruikersnaam, wachtwoord en sessielengte

Nieuws

Welkom op het vernieuwde NL Computer Forum!

Auteur Topic: Access: CasE-seNSiTivE  (gelezen 15790 keer)

0 leden en 1 gast bekijken dit topic.

Offline NLCOMP

  • Forumheld
  • *****
  • Berichten: 14.666
    • NL Computer Forum
Access: CasE-seNSiTivE
« Gepost op: 9 november 2009, 19:14:51 »
Bericht 1 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:Hugo KornelisDatum:12-10-2004
 Aan:AllenMsgID:1463.1
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
Hoi allemaal,

In Access 97 probeer ik een formulier zodanig te dresseren dat bij overschakelen naar een ander formulier de huidige positie wordt "onthouden"; bij her-activeren van het betreffende formulier moeten dan eventuele wijzigingen in de recordbron zichtbaar worden, maar zo mogelijk (als het record niet verwijderd is) moet de "onthouden" positie worden hersteld. Ik heb daarvoor de volgende gebeurtenisprocedures gemaakt:

Private Sub Form_Activate()
  Me.Requery
  Me.RecordsetClone.FindLast "Sleutel <= '" & OudeSleutel & "'"
  NieuweSleutel = Me.RecordsetClone!Sleutel
  If NieuweSleutel <= OudeSleutel Then
    DoCmd.FindRecord NieuweSleutel, , True
  End If
End Sub

Private Sub Form_Deactivate()
  OudeSleutel = Me.Sleutel
End Sub

Dit werkt prima, zolang de sleutels allemaal met een hoofdletter beginnen, of allemaal met een kleine letter. Maar niet als het gemengd is. Dan worden de sleutelwaardes in het formulier gesorteerd op ASCII-waarde (dus eerst alle hoofdletters alfabetisch, dan de kleine letters alfabetisch), maar de FindLast en en daaropvolgende vergelijking in de Activate procedure beschouwt kleine en grote letters als gelijk.

Is hier een oplossing voor?

Alvast bedankt!

Groetjes, Hugo


Bericht 2 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:John Kopmels (Sysop)Datum:12-10-2004
 Aan:Hugo KornelisMsgID:1463.2
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
Hoi Hugo

> In Access 97 probeer ik een formulier zodanig te dresseren dat bij
overschakelen naar ander form de huidige positie wordt "onthouden"

Code iets aangepast

Option Explicit
'
' maak Sleutel een Public (in een globale module)
' als j'm ook na het sluiten en opnieuw openen wil
'
Private Sleutel As String
------------------------------------------------------

Private Sub Form_Activate()
'
' haal nieuw waardes op bij activeren
Me.Requery
'
' ga terug naar vorige record pointer
With Me.RecordsetClone
.FindLast "au_id=" & Chr(34) & Sleutel & Chr(34)
If Not .NoMatch Then Me.Bookmark = .Bookmark
End With
'
End Sub

Private Sub Form_Deactivate()
'
' bewaar record pointer
Sleutel = Me.au_id
'
End Sub

> Dit werkt prima, zolang de sleutels allemaal met een hoofdletter
beginnen, of allemaal met een kleine letter. Maar niet als het gemengd is.
Dan worden de sleutelwaardes in het formulier gesorteerd op ASCII-waarde
(dus eerst alle hoofdletters alfabetisch, dan de kleine letters alfabetisch),
maar de FindLast en en daaropvolgende vergelijking in de Activate procedure
beschouwt kleine en grote letters als gelijk. Is hier een oplossing voor?


Zoals je al gemerkt hebt is Access is niet Case Sensitive maar er zijn
verschillende workarounds mogelijk, de makkelijkste lijkt me in de query
een verborgen kolom met daarin de Ascii waarde te maken en daarop te sorteren

SELECT dbo_authors.au_id,
dbo_authors.au_fname,
dbo_authors.au_lname
FROM dbo_authors
ORDER BY (Asc([au_lname]))

Andere mogelijkheden:
- In code met een rs werken en dan
StrComp of Option Compare Binary

- een String 2 Hex functie en daarop sorteren

Groetjes --John



Bericht 3 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:Hugo KornelisDatum:13-10-2004
 Aan:John Kopmels (Sysop)MsgID:1463.3
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
Hoi John,

> verschillende workarounds mogelijk

Bedankt voor de suggesties! Ik ga er morgen meteen mee aan de slag en laat je weten hoe het verder gaat.

Groetjes, Hugo

PS: Had je mijn andere bericht ook gezien? Bericht nummer #191140.


Bericht 4 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:John Kopmels (Sysop)Datum:13-10-2004
 Aan:Hugo KornelisMsgID:1463.4
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
>> PS: Had je mijn andere bericht ook gezien? Bericht nummer #191140. <<

Hoi Hugo,

Ja zelfs heel even naar gekeken :-)

Maar (meestal) begin van de week heel erg druk, maar kom er
later deze week nog op terug (als ik een goeie ingeving heb)

Groetjes --John



Bericht 5 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:John Kopmels (Sysop)Datum:13-10-2004
 Aan:Hugo KornelisMsgID:1463.5
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
>> Dan worden de sleutelwaardes in het formulier gesorteerd op ASCII-waarde
(dus eerst alle hoofdletters alfabetisch, dan de kleine letters alfabetisch) <<

PS ik hoop dat ik het goed begrepen heb en het hier niet goed staat

Access is by default niet case sensitive en sorteerd dus alles door elkaar
a 97
A 65
b 98
B 66

De oplossing sorteren op Asc(Veldnaam) sorteerd ze dus wel gegroepeerd
A 65
B 66
a 97
b 98

Een andere is nog, eerst naar UCASE omzetten

SELECT dbo_authors.au_id,
dbo_authors.au_fname,
dbo_authors.au_lname,
UCase([au_lname]) AS U
FROM dbo_authors
ORDER BY UCase([au_lname]);

Groetjes --John



Bericht 6 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:John Kopmels (Sysop)Datum:13-10-2004
 Aan:Hugo KornelisMsgID:1463.6
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
Hoi Hugo

> Ik heb daarvoor de volgende gebeurtenisprocedures gemaakt:

Ook nog even wat verder naar gekeken en het volgende voor je
gemaakt, als je nu het debug venster vertikaal ernaast schikt
en open houd dan zie je precies wat er gebeurt, de extra code
is nodig vanwege de requery en de volgorde van de events ...

' in een Globale module's declaratie sectie :

Public Sleutel As String
'------------------------------------------------------------
' In de Form klasse module's declaratie sectie :

Option Explicit

'
Private bOpen As Boolean
' ------------------------------------------------------------

' In de Form klasse module zelf :

Private Sub Form_Activate()
'
Debug.Print "Activate" & vbTab & Sleutel
'
If bOpen Then
  Me.Requery
  Debug.Print "Requery" & vbTab & Sleutel
End If
'
With Me.RecordsetClone
  .FindLast "au_id=" & Chr(34) & Sleutel & Chr(34)
  If Not .NoMatch Then
    Me.Bookmark = .Bookmark
    Debug.Print Sleutel & " gevonden"
  Else
    Debug.Print Sleutel & " niet gevonden"
  End If
End With
'
bOpen = True
'
End Sub

Private Sub Form_Deactivate()
'
If bOpen Then Sleutel = Me.au_id
  Debug.Print "De-Activate" & vbTab & Sleutel
'
End Sub

Private Sub Form_Load()
  Debug.Print "Laad"
  bOpen = False
End Sub

Private Sub Form_Close()
  Debug.Print "Sluit"
End Sub

Private Sub Form_Open(Cancel As Integer)
  Debug.Print "Open"
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Debug.Print "Ontlaad"
  bOpen = False
  Sleutel = Me.au_id
End Sub

Groetjes --John



Bericht 7 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:Hugo KornelisDatum:14-10-2004
 Aan:John Kopmels (Sysop)MsgID:1463.7
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
Hoi John,

> De oplossing sorteren op Asc(Veldnaam) sorteerd ze dus wel gegroepeerd
> A 65
> B 66
> a 97
> b 98

Helaas is het veld meer dan n teken lang. En ook de onderlinge sortering van AA, Ab en AC moet goed zijn.

> Een andere is nog, eerst naar UCASE omzetten
>
> SELECT dbo_authors.au_id,
> dbo_authors.au_fname,
> dbo_authors.au_lname,
> UCase([au_lname]) AS U
> FROM dbo_authors
> ORDER BY UCase([au_lname]);

Die vind ik leuk. Dat heeft namelijk als voordeel dat de volgorde op het scherm meteen ook wat logischer overkomt.

Wat is eigenlijk beter: deze query opgeven als recordbron voor het formulier, of deze query maken, opslaan in de database en dan de naam van die query opgeven als recordbron?

Bedankt voor deze goede tip!!

Groetjes, Hugo


Bericht 8 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:Hugo KornelisDatum:14-10-2004
 Aan:John Kopmels (Sysop)MsgID:1463.8
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
Hoi John,

> Ook nog even wat verder naar gekeken en het volgende voor je
> gemaakt

Geweldig! Ik heb hem niet zo gehouden als 'ie was (ik wil namelijk niet dat de oude positie ook bewaard wordt als het formulier gesloten en dan weer geopend wordt; daarentegen wil ik wel in het geval een record niet meer bestaat positioneren op het daar direct aan voroafgaande record). De code die ik nu gebruik is als volgt:

* In de recordbron heb ik een veld "Sleutel" toegevoegd waarin de UCase functie wordt gebruikt om de sleutel vand e tabel in uppercase te zetten; hier is de recordbron ook op gesorteerd.

In de declaraties van het formulier:

Option Explicit
Public OudeSleutel As String

En dan de volgende gebeurtenisprocedures:

Private Sub Form_Activate()
  Me.Requery
  With Me.RecordsetClone
    .FindLast "Sleutel <= " & Chr(34) & OudeSleutel & Chr(34)
    If Not .NoMatch Then Me.Bookmark = .Bookmark
  End With
End Sub

Private Sub Form_Deactivate()
  OudeSleutel = Me.Sleutel
End Sub

Private Sub Form_Open(Cancel As Integer)
  If Me.Filter <> "" Then
    Me.Koptekst.Caption = Me.Koptekst.Caption & " (selectie)"
  Else
    Me.Koptekst.Caption = Me.Koptekst.Caption & " (overzicht)"
  End If
End Sub

Door in de activate te zoeken op Sleutel <= OudeSleutel vindt ik f de oude positie, f (als die niet meer bestaat) de positie daar onmiddelijk aan voorafgaand. Als de oude positie de eerste was (en nu dus verwijderd), dan geeft deze zoek-operatie het laatste record als resultaat, daarom wijzig ik Me.Bookmark alleen als er geen sprake is van een NoMatch. Goed truk overigens met die bookmark - die kende ik niet (vandaar dat ik in mijn code zo'n lelijke kludge had staan).

Omdat ik bij sluiten en daarna weer openen van het formulier NIET de oude positie wil vasthouden heb ik geen gebeurtenisprocedures meer nodig voor laden, onladen en sluiten en geen extra acties in de gebeurtenisprocedure voor openen. Ook de lokale variabele bOpen is niet nodig; OudeSleutel kan een globale variabele voor het formulier worden en hoeft niet in een globale module.

Het nadeel van deze methode is dat ik nu voor alle tabellen waar ik een formulier voor maak een query moet maken om het extra veld Sleutel en de juiste sortering toe te voegen. Het voordeel is echter dat ik de bovenstaande code zonder enige wijziging kan knippen en plakken in alle formulieren (tot nu toe moest ik steeds de naam van de sleutelvelden overal aanpassen, en dat vergeet je atlijd op ten minste n plaats). Bovendien werkt deze truc ook voor tabellen met composite key (dan komt in de query gewoon zoiets als SELECT UCase(Kol01) & UCase(Kol02) AS Sleutel, ...

Ontzettend bedankt, John! Zonder jouw hulp zou ik hier voorlopig nog niet uit zijn gekomen.

Groetjes, Hugo


Bericht 9 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:John Kopmels (Sysop)Datum:14-10-2004
 Aan:Hugo KornelisMsgID:1463.9
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
Hoi Hugo

> Wat is eigenlijk beter: deze query opgeven als recordbron voor het formulier, of deze
query maken, opslaan in de database en dan de naam van die query opgeven als recordbron?

Een opgeslagen query is altijd sneller, deze wordt de eerst keer dat hij runt gecompileerd
net als in sql server wordt het beste executie plan bepaalt, oa mbv de Rushmore technology

Er is zelfs een ongedocumenteerde truc om het showplan uit te lezen, je daarvoor wel de
registry tweaken, voor Access97 is dat (als de Debug subsleutel er nog niet is dan maken)

SOFTWARE\MICROSOFT\JET\3.5\Engines\Debug

In deze sleutel in hoofdletters een nieuwe string waarde aanmaken : JETSHOWPLAN en de waarde
instellen op ON (of OFF als j'm weer uit wil zetten, let op: het bestand kan groot worden)

Onder Windows XP wordt in de data folder (systeeminstelling) een bestandje
showplan.out gemaakt, oudere versies in de zelfde map als de database zelf

Verschil is pas meetbaar bij complexe queries of qeuries die vaak gerunt
worden, vaak hou je de query in een form of in code vanwege portability.

Groetjes --John



Bericht 10 van 10

NL Computer Forum ~ SQL & Programmeren
 Van:Hugo KornelisDatum:14-10-2004
 Aan:John Kopmels (Sysop)MsgID:1463.10
 Onderwerp:Access: CasE-seNSiTivEForum:ws-nlcomputer
Hoi John,

> > Wat is eigenlijk beter: deze query opgeven als recordbron voor het
> formulier, of deze
> query maken, opslaan in de database en dan de naam van die query opgeven
> als recordbron?
>
> Een opgeslagen query is altijd sneller, deze wordt de eerst keer dat hij
> runt gecompileerd
> net als in sql server wordt het beste executie plan bepaalt, oa mbv de
> Rushmore technology

Ok, dan is dat hoe ik het ga doen. Bedankt!!

Groetjes, Hugo