Avatar billede bbkdk Seniormester
03. november 2004 - 13:44 Der er 12 kommentarer og
3 løsninger

Automatisk finde bruger ved start

Jeg er ansat i et firma der skal bruge et flexsystem til at holde orden på medarbejderne registrerede arbejdstid(kunne for den sags skyld også være et tidsregisteringssystem eller en kombination af begge)
På de flexsystemer jeg har set (både fra Access og Excel) starter denne automatisk, så den enkelte bruger på maskinen kun kan flexe ind på sit eget billede, og kun kan se sine egne data.
Administrator kan så selvfølgelig se alle data.
Ved opstart af maskinerne (enten indgang på Windows eller indgang på serveren) angiver vi et kendeord.
Det må jo så være det kendeord, der anvendes som identifikation ved start af flexsystemet, hvor der ikke skal angives yderligere identifikation.
Men hvordan finder man dette kendeord på maskinen, og hvordan får man det lagt ind i så Acces finder det ved start.
Jeg har en ide om, at kendeordet skal lægge i tabellen over brugere (men hvordan så når kendeordet skiftes) og at det er funktionen CurrentUser, der skal anvendes.
Avatar billede overchord Nybegynder
03. november 2004 - 13:50 #1
Den nemmeste metode til at hive folks windows-brugernavn user er Environ("username") som returnerer dit login navn direkte.
Avatar billede madschristensen Nybegynder
03. november 2004 - 14:24 #2
Der er også en lidt anden løsning. Du kan bruge WnetGetUser().. Jeg prøver lige at lægge et eksempel:

Opretter en global variabel med indhold at brugernavn:

Option Compare Text
Option Explicit
    Global Bruger As String
   
      Type WKSTA_INFO_101
        wki101_platform_id As Long
        wki101_computername As Long
        wki101_langroup As Long
        wki101_ver_major As Long
        wki101_ver_minor As Long
        wki101_lanroot As Long
      End Type

      Type WKSTA_USER_INFO_1
        wkui1_username As Long
        wkui1_logon_domain As Long
        wkui1_logon_server As Long
        wkui1_oth_domains As Long
      End Type

      Declare Function WNetGetUser& Lib "Mpr" Alias "WNetGetUserA" _
        (lpName As Any, ByVal lpUserName$, lpnLength&)
      Declare Function NetWkstaGetInfo& Lib "Netapi32" _
        (strServer As Any, ByVal lLevel&, pbBuffer As Any)
      Declare Function NetWkstaUserGetInfo& Lib "Netapi32" _
        (reserved As Any, ByVal lLevel&, pbBuffer As Any)
      Declare Sub lstrcpyW Lib "kernel32" (Dest As Any, ByVal src As Any)
      Declare Sub LStrCpy Lib "kernel32" Alias "lstrcpy" (Dest As Any, ByVal src As Any)
      Declare Sub RtlMoveMemory Lib "kernel32" _
        (Dest As Any, src As Any, ByVal size&)
      Declare Function NetApiBufferFree& Lib "Netapi32" (ByVal Buffer&)


      Function GetWorkstationInfo()
        Dim ret As Long, Buffer(512) As Byte, i As Integer
        Dim wk101 As WKSTA_INFO_101, pwk101 As Long
        Dim wk1 As WKSTA_USER_INFO_1, pwk1 As Long
        Dim cbusername As Long, userName As String
       
        userName = ""

        ' Windows 95 or NT - call WNetGetUser to get the name of the user.
        userName = Space(256)
        cbusername = Len(userName)
        ret = WNetGetUser(ByVal 0&, userName, cbusername)
        If ret = 0 Then
            ' Success - strip off the null.
            userName = Left(userName, InStr(userName, Chr(0)) - 1)
        Else
            userName = ""
        End If

 
    Bruger = userName
      End Function
Avatar billede madschristensen Nybegynder
03. november 2004 - 14:26 #3
Og hvis du vil vide hvilke grupper der er medlemskab af (eks. admin):

*Kontrollere medlemskab af gruppen administratorer;
Function Admin() As Boolean
    DoCmd.Hourglass True
    Skriv_til_Status ("Vent - undersøger rettigheder")
    Admin = False
    If listUserGroups("Administratorer") = True Then Admin = True
    DoCmd.Hourglass False
    Nulstil_Status
End Function

Modul:
Option Compare Database
Option Explicit

Private Declare Function LStrCpy Lib "kernel32" (ByVal Dest As String, ByVal Source As Any) As Integer

'Netværk
Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long

Private Declare Function NetGetDCName Lib "NETAPI32.DLL" (ServerName As Any, DomainName As Any, DCNPtr As Long) As Long

Private Declare Function NetUserGetInfo Lib "NETAPI32.DLL" (ByVal server As String, ByVal userName As String, ByVal Level As Integer, Buffer As Any, ByVal cbBuffer As Integer, pcbTotal As Integer) As Integer

Private Declare Function NetUserGetGroups0 Lib "NETAPI32.DLL" Alias "NetUserGetGroups" (ServerName As Byte, userName As Byte, ByVal Level As Long, Buffer As Long, ByVal PrefMaxLen As Long, EntriesRead As Long, TotalEntries As Long) As Long

Private Declare Function NetApiBufferFree Lib "NETAPI32.DLL" (ByVal pBuffer As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long

Private Declare Function PtrToStr Lib "kernel32" Alias "lstrcpyW" (retVal As Byte, ByVal Ptr As Long) As Long
Private Declare Function StrToPtr Lib "kernel32" Alias "lstrcpyW" (ByVal Ptr As Long, Source As Byte) As Long
Private Declare Function PtrToInt Lib "kernel32" Alias "lstrcpynW" (retVal As Any, ByVal Ptr As Long, ByVal nCharCount As Long) As Long

Private Declare Function StrLen Lib "kernel32" Alias "lstrlenW" (ByVal Ptr As Long) As Long

Private Type MungeLong
    X As Long
    Dummy As Integer
End Type

Private Type MungeInt
    XLo As Integer
    XHi As Integer
    Dummy As Integer
End Type

Private Declare Function GetVersionExA Lib "kernel32.dll" (lpVersionInformation As OSVERSIONINFO) As Integer

Private Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128
End Type

Const winver9x As Integer = 1
Const winverNT As Integer = 2

Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (pTo As Any, uFrom As Any, ByVal lSize As Long)
Public Function listUserGroups(Groupname As String) As Boolean
listUserGroups = False

        Dim Result As Long, BufPtr As Long, EntriesRead As Long
        Dim TotalEntries As Long, ResumeHandle As Long, BufLen As Long
        Dim SNArray() As Byte, GNArray(99) As Byte, UNArray() As Byte
        Dim GName As String, i As Integer, UNPtr As Long
        Dim TempPtr As MungeLong, TempStr As MungeInt

        Dim DCName As String, UName As String

        'get the name of a domain controller & the name of the user running us
        DCName = GetPrimaryDCName()
        UName = Bruger7
         
       

                SNArray = DCName & vbNullChar
                UNArray = UName & vbNullChar

                Result = NetUserGetGroups0(SNArray(0), UNArray(0), 0, BufPtr, -1, EntriesRead, TotalEntries)
       

        If Result <> 0 And Result <> 234 Then ' 234 = more data; should never happen seeing as though we ask for all of it at once
                MsgBox "Error " & Result & " enumerating group " & EntriesRead & " of " & TotalEntries
                Exit Function
        End If


                For i = 1 To EntriesRead
                        Result = PtrToInt(TempStr.XLo, BufPtr + (i - 1) * 4, 2)
                        Result = PtrToInt(TempStr.XHi, BufPtr + (i - 1) * 4 + 2, 2)
                        LSet TempPtr = TempStr ' munge 2 Integers To a Long

                        'Copy string to array and convert to a string
                        Result = PtrToStr(GNArray(0), TempPtr.X)
                        GName = Left(GNArray, StrLen(TempPtr.X))
                        If GName = Groupname Then listUserGroups = True
                Next i



                Result = NetApiBufferFree(BufPtr) ' Don't leak memory
End Function

Function GetPrimaryDCName() As String

        Dim Result As Long, DCName As String, DCNPtr As Long
        Dim DCNArray(100) As Byte


                Result = NetGetDCName(0&, 0&, DCNPtr)

        If Result <> 0 Then
                MsgBox "Unable to determine Domain Controller Name"
                Exit Function
        End If


                Result = PtrToStr(DCNArray(0), DCNPtr)
                Result = NetApiBufferFree(DCNPtr)
                DCName = DCNArray()

        GetPrimaryDCName = DCName
'MsgBox (DCName)
End Function
Avatar billede bbkdk Seniormester
03. november 2004 - 14:56 #4
Whaw ........... det var en ordentlig smøre madschristensen.
Jeg skal lige tilføjes, at der både er et brugernavn og et kendeord ved indgang. Brugernavnet ændrer sig ikke (f.eks. har jeg kdk) Kendeordet skal ændres en gang i mellem.
Det må jo så være brugernavnet, der skal anvendes.
Vil det sige, at jeg skal oprette et felt med brugernavnet i min tabel over ansatte, og at koden ved åbning af databasen så skal sætte et filter på hændelsen VedÅbning, der anvender filteret, således at Brugernavnet i tabellen sættes lig med den aktuelle bruger iflg. Windows.
Ligeledes at feltet med brugernavnet i selve komme-og-gå tabellen, automatisk sættes til det brugernavn, der svarer til brugernavnet, der er anvendt ved indgang på PCen.
Håber jeg har forstået det korrekt. Kan standardværdien på selve tabellen i øvrigt sættes til den aktuelle bruger?
Der vil lige gå lidt tid(eller meget alt efter arbejdspres), inden jeg kan teste jeres løsninger.
Hvis overchord også lige vil smide et svar, og eventuelt uddybe lidt vedrørende, hvordan systemet finder brugeren, deler jeg points efter bedste overbevisning.
Avatar billede overchord Nybegynder
03. november 2004 - 15:15 #5
ok - hvad jeg normalt goer er en lidt simplificeret sikkerhedsversion som mere er beregnet til at goere det nemt for brugeren.
Jeg bruger Environ("username") til at finde folk med visse rettigheder uden at du skal looge paa databasen (goer det nemmere for folk). De personer der skal genkendes ligger i en tabel sammen med info om deres brugerniveau (som giver adgang til bestemte formularer osv).
Jeg kan forestille mig at du skal bruge en tabel over alle folk som, og at du derefter bare kan bruger en filter-funktion. Hvis du f.eks har den formular hvor folk indskriver flex-tid med brugernavn kan du ved opstart blot saette et filter paa formularen saaledes at den kun aabner paa posten = Environ("username"):
me.filter "Bruger = " & Environ("username")
me.Filteron = True
'Smides i formularens laod haendelse
Avatar billede overchord Nybegynder
03. november 2004 - 15:17 #6
Lige en ekstra fodnote - Mit foreslag er ikke en sikkerheds-loesning men bruges til at identificere folk. Ved brugen af Environ("usernmae") vil en bruger altid finde sine egne data naar han/hun er logget paa maskinnen uafhaengigt af hvilken maskine det er.
Avatar billede madschristensen Nybegynder
03. november 2004 - 15:18 #7
Min løsning behøver ingen tabeller i access. Du har jo allerede et brugernavn i windows - du har også medlemskab af visse grupper - så hvis kun admin skal have adgang til en formular:

if admin()=true then
'åbn formular
else
'Nej - vedkommende bruger er IKKE admin
  msgbox("Gå væk")
  exit sub
end if

Samtidig kan du bruge den globale variabel bruger i dine oprettelser, forespørgsler m.v.
Avatar billede madschristensen Nybegynder
03. november 2004 - 15:21 #8
D.v.s., at når du laver din forespørgsel der ligger til grund for formulareren - sætter du bare bruger() som parameter..... (Kan både bruges i SQL og QBE)
Avatar billede madschristensen Nybegynder
03. november 2004 - 15:25 #9
Jeg ved godt, at det er en stor mundfuld. Hvis du vil, kan jeg da godt lave en lille eksempel DB
Avatar billede overchord Nybegynder
03. november 2004 - 15:43 #10
bbkdk - Har du allerede en tabel over ansattes navne og flex i databasen?

Hvis det er tilfaeldet kan du noejes med at tilfeoje en kolonne til den tabel med deres brugernavn.
Avatar billede bbkdk Seniormester
03. november 2004 - 17:31 #11
Til madschristensen og overchord !!
Som overchord er inde på, er der ikke tale om et egentligt sikkerhedssystem - den store gruppe af brugere skal udelukkende kunne finde og eventuelt rette sine egne data, medens kun administrator skal kunne lave udtræk m.v. Dermed er sikkerheden vel egentlig taget også i orden?
Til madschristensen vil jeg gerne sige, at jeg vil blive utroligt glad, hvis der er mulighed for at få mailet et lille eksempel, så jeg kan se, hvad der sker. Jeg har indtryk af, at jeg ikke er den eneste, der har besvær med sikkerhedssystemer og identifikation af brugere ved indgang.
Min mailadresse er kdk@skatte-huset.dk.
Og så har i begge fortjent en masse points, er 100 til hver ok - hvordan er det lige jeg forhøjer - og så til madschristensen - du er nødt til at lægge et svar for at få del i pointene.
Avatar billede madschristensen Nybegynder
03. november 2004 - 19:34 #12
30 er godt nok til mig... ;O))

Jeg prøver lige at lave en eksempel DB i morgen i løbet af dagen - er det ok ??
Avatar billede bbkdk Seniormester
04. november 2004 - 07:45 #13
Det er naturligvis bare helt i orden madschristensen - overchrod hvis det også er ok for dig med 30 points, deler jeg dem mellem jer.

Og så rigtigt mange tak for hjælpen begge to - det har bare været aller tiders.
Avatar billede overchord Nybegynder
04. november 2004 - 13:56 #14
Ja 30 point er skam helt fint!

Det ser ud til at jeg har faaet 2x30 point ved en fejl - saa jeg overfoerer 30 til mads.
Avatar billede overchord Nybegynder
04. november 2004 - 14:03 #15
lige en lille opdatering - Min navigationsbjaelke her paa E er forsvundet (!) - saa jeg kan ikke oprette spoergsmaal, men jeg vil faa det ordnet saa snart som muligt.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester