Cursorpositie in Access formulier

Status
Niet open voor verdere reacties.

Martin4Scale

Nieuwe gebruiker
Lid geworden
8 aug 2023
Berichten
3
Hallo allemaal,
Ik heb een Access applicatie waarin op meerdere plaatsen in meerdere forms een listbox wordt gebruikt. Deze listboxes bevatten meerdere kolommen en worden gevuld op basis van een query. Zo wordt de historie weergegeven van eerder ingevulde waarden van dat scherm.
Sommige kolommen in de listbox bevatten langere teksten waarvan slechts een klein deel wordt getoond. Als deze kolom wordt aangeklikt wordt een pop up venster getoond met de volledige tekst. Andere kolommen bevatten een link naar een bijlage, wanneer die wordt aangeklikt wordt de bijlage geopend in de bijbehorende applicatie. Sommige kolommen bevatten een datum of een korte tekst en hebben geen achterliggende actie bij aanklikken.
Omdat in Access een listbox alleen een index heeft voor de rij maar de kolom niet bekend is bij aanklikken, heb ik op basis van de functie GetCursorPos de X-positie bepaald van de cursor en op die manier kan ik bepalen in welke kolom de muisklik heeft plaatsgevonden. Dat werkt allemaal prima.
Het gaat mis als ik de applicatie op een andere PC uitvoer want dan zijn de schermverhoudingen plotseling anders en kan ik er niet meer op vertrouwen dat de ingestelde kolom-grenzen nog juist zijn. Ik heb geprobeerd met behulp van de functie ScreenToClient dit te tackelen maar ik krijg dat niet aan de praat.
Heeft iemand hier ervaring mee en/of weet iemand een manier waarop ik de X-positie van de cursor onafhankelijk van de hardware kan gebruiken t.o.v. schermposities

Alvast dank voor jullie reacties.
 
Allereerst welkom bij HelpMij! Als je deze applicatie zelf hebt gebouwd, dan ben je geen beginner :). Wellicht verklaart dat ook het nutteloze gebruik van Engelse woorden voor woorden die echt een Nederlands equivalent hebben. Althans: ik neem aan dat je wel eens gehoord hebt van de woorden 'formulier' en 'keuzelijst' :). Aan de andere kant: met Engelse woorden maak je geheid meer indruk op je publiek :d. (Niet hier overigens ;))

Zelf zou ik deze oplossing nooit gekozen hebben, al was het maar vanwege de nogal technische aspecten die er bij komen kijken, zoals het juist interpreteren van de cursorpositie. Mijn oplossing zou zijn geweest: meerdere keuzelijsten die je dan netjes tegen elkaar aan zet, en (uiteraard) op dezelfde bron baseert. Ik weet niet of er een keuzelijst wordt gebruikt om een waarde te selecteren (je hebt het over historische gegevens, dus ik vermoed dat ze standaard geladen worden bij een OnCurrent gebeurtenis). Denk het van niet.
In dat geval zet je de gevens die aangeklikt kunnen worden voor een actie dus in een eigen keuzelijst en dan is de Click event dus automatisch altijd goed. Een andere truc die ik wel eens gebruik: maak transparante knoppen die over de juiste kolommen vallen, en hang dáár de gebeurtenis achter. Dat werkt sowieso perfect op een doorlopend formulier (de derde optie: een doorlopend formulier met click acties op de juiste velden), maar wellicht ook op een keuzelijst, dat heb ik nog niet uitgeprobeerd.

Wellicht heb je wat aan de tips; zelf zou ik geen tijd steken in de weg die je nu hebt bewandeld, want ik zou dus gelijk al met één van mijn alternatieven zijn begonnen :).
 
Beste Octa, bedankt voor je suggesties maar ik vrees dat dat een beetje mosterd na de maaltijd is want dat vergt erg veel aanpassingen. Het beschreven fenomeen zit op 28 plaatsen in de diverse schermen! Ik had zelf al als alternatief bedacht dat ik een subformulier kan gebruiken ter vervanging van de listbox (ik heb alleen een engelse versie :D) maar dat vergt een inspanning die ik liever zou vermijden tenzij het onontkomelijk is.
grt. Martin
 
28 schermen? Als ik dat lees, denk ik gelijk: slecht ontworpen database :). Zeker als die schermen dezelfde layout hebben (al kan dat een verkeerde indruk nu zijn natuurlijk). Maar dan nog: dat is best nog te doen. Zelf zou ik sowieso de voorkeur geven aan systemen die foolproof zijn, en op meerdere systemen goed kunnen draaien, ongeacht deinrichting. Het probleem wat je nu hebt, lijkt mij dan óók voor 28 schermen nodig, en dat kost dan ook tijd.
 
Mmmm.... lijkt me niet erg gefundeerd om deze kwalificaties te geven aan een project dat je nooit hebt gezien en waar ruim 2 jaar aan gewerkt is. Maar goed.... ik heb mijn licht ook elders opgestoken en heb inmiddels een manier gevonden om de kolom te bepalen waar de muis zich bevindt bij de klik. Getest in verschillende omgevingen.

Voor de onbevooroordeelden:
Private Sub Txt_Historie_Opvolging_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim colWidths As Variant
Dim columnBoundaries() As Single
Dim clickedColumn As Integer

colWidths = Split(Txt_Historie_Opvolging.ColumnWidths, ";")
ReDim columnBoundaries(UBound(colWidths))

Dim i As Integer
Dim boundary As Single
boundary = 0

For i = 0 To UBound(colWidths)
columnBoundaries(i) = boundary
boundary = boundary + CSng(colWidths(i))
Next i

For i = 0 To UBound(columnBoundaries)
If X >= columnBoundaries(i) And X <= columnBoundaries(i) + CSng(colWidths(i)) Then
clickedColumn = i
Exit For
End If
Next i

MsgBox "Kolom: " & clickedColumn + 1 ' omdat split begint bij 0

End Sub
 
Ik ben absoluut onbevooroordeeld :). Zoals ik al zei: vermoedelijk een verkeerde indruk van mij. Maar mooi dat je er wat op gevonden hebt. De code de volgende keer graag in CODE tags zetten, dan ziet-ie er een stuk leesbaarder uit. Dus zo:

Code:
Private Sub Txt_Historie_Opvolging_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)Dim colWidths As Variant
Dim columnBoundaries() As Single, Boundary As Single
Dim clickedColumn As Integer, i As Integer


    colWidths = Split(Txt_Historie_Opvolging.ColumnWidths, ";")
    ReDim columnBoundaries(UBound(colWidths))
    For i = 0 To UBound(colWidths)
        columnBoundaries(i) = Boundary
        Boundary = Boundary + CSng(colWidths(i))
    Next i
    
    For i = 0 To UBound(columnBoundaries)
        If X >= columnBoundaries(i) And X <= columnBoundaries(i) + CSng(colWidths(i)) Then
            clickedColumn = i
            Exit For
        End If
    Next i
    MsgBox "Kolom: " & clickedColumn + 1 ' omdat split begint bij 0


End Sub

Voor code waar al twee jaar aan gewerkt is, zitten er wat vreemde zaken in, alhoewel die de werking niet beïnvloeden.

Zo heb je een (in mijn ogen) vreemde manier van variabelen declareren: je begint met een paar declaraties, dan begin je met de code, en dan prop je er nog een paar nieuwe variabelen tussen. Ik zet ze altijd aan het begin, want op jouw manier loop je de kans dat je het overzicht verliest en er teveel of te weinig declareert. Wat jij doet mag, maar of het handig is?
En dan heb je nog de variabele boundary.
Code:
[COLOR=#333333]Dim boundary As Single[/COLOR]
[COLOR=#333333]boundary = 0[/COLOR]
Die wordt gedeclareerd, en daarna op 0 gezet? Elke programmeur weet dat een nieuw gedeclareerde variabele altijd leeg is, of, bij getallen, 0. Dus waarom zou je dit doen? Nergens voor nodig. Nogmaals: niet fout, maar nutteloos.

Maar goed, ik wou dus even de CODE tags demonstreren voor de volgende keer :).
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan