Hirdetés

Új hozzászólás Aktív témák

  • Mutt

    senior tag

    válasz lappy #39091 üzenetére

    Szia,

    Ha a felhasználó hozzáfér egy munkalaphoz, akkor már nehezen lehet leszabályozni hogy melyik sorhoz férjen hozzá. Talán az lehetne egy megoldás, hogy mindig az első 2 sorba írnád bele a felhasználóra tartozó adatokat egy másik helyről és a Worksheet_SelectionChange eseménnyel próbálnád meg leblokkolni hogy ne mászkáljon el.

    Én inkább egy másik megoldást javaslok, ami kicsit bolondbiztosabb és bonyolultabb is.

    Userform-ot, amin keresztül a beléptetjük a felhasználót és megjelenítjük az adott sor adatait, amit ott tud módosítani és visszamenteni az eredeti lapra.

    Az előnye ennek, hogy mindegyik lapot el tudod rejteni (akár VeryHidden-ként), így középszintű Excel felhasználóktól is megtudod védeni az adatokat.

    Egy csontvázat mutatok be, ami alapján el tudsz indulni.

    1. A fájlodban van két munkalap, az egyiken vannak az adatok, a másikon pedig a felhasználói azonosítók és jelszavak. Ezen lapokat nyugodtan elrejtheted.

    2. VBA-ban szúrj be egy formot és kezd el rá dobálni az alábbi vezérlőket:
    - egy combobox a felhasználói neveknek (ezzel egy legördülő listát lehet csinálni)
    - egy textbox kell a jelszóhoz,
    - 2 gomb a belépéshez és kilépéshez a programból.

    Lehet még felrakni labeleket, hogy tudjuk mi mire való, illetve én tettem fel egy pluszat is ahova ki lehet írni a sikeres belépés vagy a hibás felhasználó üzeneteket.

    3. Legyen pár globális változónk, hogy tudjuk rájuk minden helyen gyorsan hivatkozni.

    Option Explicit
    Dim wsUsers As Worksheet, wsData As Worksheet, lastrowUsers As Long, lastrowData As Long
    Dim activeRow As Long 'control which row should be displayed

    A wsUsers és WsData egy változó lesz azon munkalapokhoz ahol vannak az adatok és a felhasználók, illetve megjegyezzük hogy ezen lapokon hol vannak az utolsó sorok.
    Az activeRow pedig mindig mutatni fog arra a sorra, ami a belépett felhasználóhoz van rendelve.

    4. A Userform indulásával feltöltjük a username comboboxot, aminek én a cbUserName azonosítót adtam.
    Beállítjuk a többi változót.

    Private Sub UserForm_Initialize()
    Dim i As Long
    Const UserSheet = "Users" 'worksheet name with user ids, passwords etc
    Const DataSheet = "Data" 'worksheet name with actual data

    Set wsData = Worksheets(DataSheet) 'assign data sheet to a variable
    Set wsUsers = Worksheets(UserSheet) 'assign user id sheet to a variable
    lastrowData = wsData.Range("A" & Rows.Count).End(xlUp).Row 'find the last row on data sheet
    lastrowUsers = wsUsers.Range("A" & Rows.Count).End(xlUp).Row 'find the last row on user sheet

    'load valid users to username controlbox
    For i = 2 To lastrowUsers
    Me.cbUserName.AddItem wsUsers.Range("A" & i)
    Next i

    End Sub

    5. Ha van felhasználói név és jelszó megadva, akkor lehet csak belépni. Ehhez én figyelem ennek a két doboznak (cbUserName -ről már írtam, a jelszó pedig a txPassword textbox-ban van) a change eseményét nézem, de lehetne az AfterUpdate-t is. A lényeg, hogy a form indulásakor a Login nevű gomb inaktív (ez az alapértelemezett értéke) és csak akkor lesz kattintható ha van név és jelszó megadva.

    Private Sub cbUserName_Change()

    'if both username and password is filled then enable login button
    If cbUserName <> "" And txPassword <> "*" Then
    btLogin.Enabled = True
    lbComment.Visible = False
    End If

    End Sub

    Private Sub txPassword_Change()

    'if both username and password is filled then enable login button
    If cbUserName <> "" And txPassword <> "*" Then
    btLogin.Enabled = True
    lbComment.Visible = False
    End If

    End Sub

    6. Ha kattintanak a Login gombra, akkor megnézzük hogy a megadott felhasználó és jelszópáros egyezik-e a menttettel. Ha igen, akkor
    - van egy hely (LoginComment) ahova kiírjuk hogy sikeres a belépés
    - megkeressük hogy a felhasználóhoz melyik sorban van adat rendelve és az activeRow változóba ezt beállítjuk,
    - láthatóvá tesszük azokat a vezérlőket, amelyekben megjelenítjük a felhasználóhoz tartozó adatokat .

    Ehhez a formra felvittem még pár mezőt, így néz ki a teljes form:

    Hibás belépésnél lényegében csak kiírjuk a hibát és töröljük a megadott jelszót.

    Private Sub btLogin_Click()
    Dim cell As Range
    Dim i As Long

    For Each cell In wsUsers.Range("A2:A" & lastrowUsers)
    'find the selected username on user id sheet
    If UCase(cell) = UCase(cbUserName) Then
    'if password matches then print out a notification and display the data
    If cell.Offset(, 1) = txPassword Then
    lbComment = "Successful login"
    lbComment.Visible = True
    txPassword = "*" 'password is visible on the form, so after a valid login hide it
    btSave.Visible = True 'make visible the save button

    'find the correct line for the selected user on data sheet
    If UCase(cbUserName) = "ADMIN" Then
    activeRow = 2
    spinRecord.Visible = True
    spinRecord.Min = activeRow
    spinRecord.Max = lastrowData
    Else
    For i = 2 To lastrowData
    If UCase(wsData.Range("A" & i)) = UCase(cbUserName) Then
    activeRow = i
    End If
    Next i
    End If

    Call DisplayData
    Else
    'wrong password was given
    lbComment = "Invalid username or password"
    lbComment.Visible = True
    txPassword = "*"
    End If
    End If
    Next cell
    End Sub

    7. A cancel (kilépés) gombnak egyszerű az eseménye, bezárja a formot.

    Private Sub btCancel_Click()

    Unload Me

    End Sub

    8. A felhasználóhoz rendelt adatok megjelenítésére csináltam egy külön szubrutint, DisplayData névvel, Ez most nagyon minimalista.

    Sub DisplayData()

    With wsData
    If Len(.Cells(activeRow, 2)) > 0 Then
    txRecord1 = .Cells(activeRow, 2)
    Else
    txRecord1 = ""
    End If

    If Len(.Cells(activeRow, 3)) > 0 Then
    txRecord2 = .Cells(activeRow, 3)
    Else
    txRecord2 = ""
    End If

    If Len(.Cells(activeRow, 4)) > 0 Then
    txRecord3 = .Cells(activeRow, 4)
    Else
    txRecord3 = ""
    End If
    End With

    End Sub

    9. Ha a felhasználó átírja a formon az adatot, akkor a Save gombbal visszaírjuk a munkalapra.

    Private Sub btSave_Click()

    With wsData
    .Cells(activeRow, 2) = txRecord1
    .Cells(activeRow, 3) = txRecord2
    .Cells(activeRow, 4) = txRecord3
    End With

    End Sub

    10. Végül az ADMIN-ra kell egy kicsit rágyúrni, mivel ő látja az összes adatot.
    Neki az a megoldás, hogy van egy görgető sáv (én most a spinbutton vezérlőt használom, a spinRecord nevet adtam neki), amin tud lépkedni az egyes mezők között. Ezt a görgető sávot a belépéskor teszem láthatóvá neki és beállítom hogy a 2-es sortól (1-esben a fejléc van), csak az utolsóig mehet. A léptetést a vezérlő change eseménye oldja meg, mert módosítja az activeRow értéket és egyből meghívja a DisplayData-t.

    Private Sub spinRecord_Change()

    activeRow = spinRecord.Value
    Call DisplayData

    End Sub

    A végeredmény így néz ki Admin-al belépve:

    A UserForm-nak nagy előnye, hogy áttekinthető formában tálalni a felhasználó felé azokat az adatokat amiket te választasz ki, illetve ha sok adatot kell bekérni akkor ott is tud segíteni, mert mentés előtt tudsz validálást csinálni.

    Ha akarod akkor automatikusan indíthatóvá teheted.
    Private Sub Workbook_Open()

    MainForm.Show

    End Sub

    üdv

Új hozzászólás Aktív témák