0

How do you disable ctrl+c for certain users? (This should be done for the whole database and not just a single form or report)

This is what I got so far:

enter image description here

Public Function ctrlC()
    'prevent unauthorised users from copying data using the ctrl + c shortcut
    If ActiveUserLevel < 2 Then
        'disalbe ctrl + c
        MsgBox "crtl c disabled"
    Else
        'allow user to use ctrl + c
        DoCmd.RunCommand acCmdCopy  'Error: "The cmd or action copy isn't available right now"
    End If
End Function

PS: I realize you could use the KEY DOWN event in a form, but I'm looking for a more efficient solution (I don't want to call the key down method on 100 different forms and possibly missing some of them...)

UPDATE

As inspired by Sion.D.P's comment another idea was to build 2 macros. One that disable ctrl+c and another that is blank, then rename them depending on the userAccessLevel with this function:

Public Sub enableUserShortcuts(val As Boolean)
    On Error Resume Next:
    'swap macro names to enable/disable user shortcut keys

    If val = False Then
        'disable user shorcuts
        DoCmd.RunMacro "AutoKeys_DisableUserShortcuts"  'test if macro needs to be loaded
        If err.number = 0 Then
            DoCmd.Rename "AutoKeys_Blank", acMacro, "AutoKeys"  'save old macro
            DoCmd.Rename "AutoKeys", acMacro, "AutoKeys_DisableUserShortcuts"   'load macro
        End If

    Else
        'enable user shorcuts
        DoCmd.RunMacro "AutoKeys_Blank"  'test if macro needs to be loaded
        If err.number = 0 Then
            DoCmd.Rename "AutoKeys_DisableUserShortcuts", acMacro, "AutoKeys"   'save old macro
            DoCmd.Rename "AutoKeys", acMacro, "AutoKeys_Blank"  'load macro
        End If

    End If

    err.number = 0
    DoCmd.RunMacro "AutoKeys"
End Sub

Or to import xml macro files with a function(https://stackoverflow.com/a/13104045/5148062):

Public Sub enableUserShortcuts(val As Boolean)
    'swap macro names to enable/disable user shortcut keys
    If val = False Then
        'disable user shorcuts
        LoadFromText acMacro, "AutoKeys", "C:\New folder\AutoKeys_DisableUserShortcuts.xml"
    Else
        'enable user shorcuts
        LoadFromText acMacro, "AutoKeys", "C:\New folder\AutoKeys_Blank.xml"
    End If
End Sub

The problem with both of the last 2 'solutions' are that the database doesn't seem to update once the above rename/import is done. You got to close the whole db and open it up again for it to work. If I don't close & reopen I get the following error: "YourDbName cant find the macro ^c in the macro group autokeys"

Rhdr
  • 387
  • 4
  • 22
  • 1
    You want to display data to the user but if he wants to use it, he has to type it manually? If I where a user, I would curse the programmer and try to use a solution as described at https://stackoverflow.com/a/21909259/7599798 - just my 2 cents – FunThomas Jul 24 '18 at 09:34
  • ^^ just what I was about to write - this would be super annoying to your users. And the old-timers will just use Ctrl+Insert and Shift+Insert instead ([link](https://superuser.com/a/428406/544673)) or find another way. – Andre Jul 24 '18 at 09:37
  • There is a way to do it In Excel. It is frequently used in Excel for 'closed' workbooks. – Siyon DP Jul 24 '18 at 09:48
  • Did you see [this](https://stackoverflow.com/questions/44945148/disable-shortcuts-in-access-2013) – Siyon DP Jul 24 '18 at 09:56
  • @FunThomas Captain's orders,,, The user/s to be blocked are raw or temporary employees, once they sign contract they will have a higher access level. We aim to protect the data even if it cause discomfort to a minority of the users – Rhdr Jul 24 '18 at 10:12
  • @Sion.D.P yes thanks. The image of the macro I pasted, capture the ctrl+c event. But I'm struggling to 'release' it (the copy should proceed if the user got a high enough accessLevel) – Rhdr Jul 24 '18 at 10:21
  • @andre I have updated the code thx. Will have to block ctrl+insert as well... – Rhdr Jul 24 '18 at 10:40
  • @Rhdr you shuld be able to enable / disable macros after login to the app acording to user priviladges – Siyon DP Jul 24 '18 at 12:05
  • Well, one could and should likely be distributing a compiled version of the application. That way ctrl-c, or in fact ANY un-handled error will NEVER re-set any of your VBA variables. This results in a FAR more reliable application since your VBA vars (local and global) will NEVER be re-set. Users also can't view your code, and ctrl-c does not work. For the "vast" majority of those developing applications, they do choose to distribute a compiled version of their software - and that includes access developers. – Albert D. Kallal Jul 26 '18 at 21:36

1 Answers1

0

Using the macro switching procedure as described in the updated part of the question resulted in the db having to be restarted. Here is a batch script that wait a while for the db to close then reopens it after login:

Private Sub createDBBatchScript()
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")

    Dim Fileout As Object
    Set Fileout = fso.CreateTextFile(Environ("temp") & "\vba.cmd", True, False)
    Fileout.Write "@echo off " & vbNewLine & _
                    "Rem used within vba to reopen db, once vba execute this script, " & vbNewLine & _
                    "Rem the script waits for a short while then if the db is closed it reopens it " & vbNewLine & _
                    "Rem if reopend create temp txt file else delete any temp txt files " & vbNewLine & _
                    vbNewLine & _
                    "set /a counter=0 " & vbNewLine & _
                    vbNewLine & _
                    ": runAgain " & vbNewLine & _
                    "set /a counter+=1 " & vbNewLine & _
                    "Rem echo %counter% " & vbNewLine & _
                    vbNewLine & _
                    "if %counter% leq 5000 ( " & vbNewLine & _
                    "    if not exist " & Application.CurrentProject.path & "\DB_FE.laccdb ( " & vbNewLine & _
                    "        Rem echo does not exists " & vbNewLine & _
                    "        echo 1 > %temp%\psReopened.txt " & vbNewLine & _
                    "        Start " & Application.CurrentProject.path & "\DB_FE.accde " & vbNewLine & _
                    "    ) else ( " & vbNewLine & _
                    "        Rem echo still exist " & vbNewLine & _
                    "        goto runAgain) " & vbNewLine & _
                    ") else ( " & vbNewLine & _
                    "    del %temp%\dbReopened.txt " & vbNewLine & _
                    ") " & vbNewLine & _
                    vbNewLine & _
                    "Rem pause "

    Fileout.Close
    Set Fileout = Nothing
    Set fso = Nothing

End Sub

Also I added an AutoExec macro & funciton to cleanup any temp leftover files created by the bacth script & help smooth over the login proccess

enter image description here

Public Function startup()
'if db is reopend by bacth script go straight to switchboard else login screen
    If Not Dir(Environ("temp") & "\vba.cmd") = "" Then
        Kill Environ("temp") & "\vba.cmd"

        If Dir(Environ("temp") & "\psReopened.txt") = "" Then
            DoCmd.OpenForm "Login Form"
        Else
            Kill Environ("temp") & "\psReopened.txt"
            DoCmd.OpenForm "SwitchMain"
        End If
    Else
        DoCmd.OpenForm "Login Form"
    End If
End Function

A benefit of generating everything in vba is that there is no left over files floating around, before or after running the scripts

Rhdr
  • 387
  • 4
  • 22