Jeszcze kilka lat temu, użytkownicy Excela ochoczo wykorzystywali mechanizm sprawdzania poprawności do tworzenia list rozwijanych. Okazało się, że w praktyce to rozwiązanie ma wiele wad – przede wszystkim łatwo te reguły walidacji nadpisać. Aby temu zapobiec, programiści tworzyli różne protezy. Jedną z najbardziej popularnych była blokada kopiowania i wklejania danych.
Dziurawa walidacja
Mechanizm sprawdzania poprawności zmienił swoją nazwę na Poprawność danych w wersji 2007 MS Excel. Osobiście wolę oryginalną nazwę tj. Walidację danych (z ang. Validation).
Narzędzie na pozór bardzo praktyczne – posiada niestety sporo niedoskonałości, Zdecydowanie lepszą opcją jest lista rozwijana na formularzu.
Komórki z walidacją można w bardzo prosty sposób nadpisać poprzez wklejenie danych lub przeciągnięcie komórek. W takiej sytuacji nasze wysiłki z tworzeniem nawet najbardziej złożonych reguł wezmą w łeb.
Aby uniknąć nadpisywania danych blokuje się kopiowanie i wklejanie danych, a także przeciąganie komórek.
Jest to rozwiązanie, które w dużej mierze zdaje egzamin.
Kod VBA
Poniżej wklejam kod, który znalazłem w sieci, a z którego często korzystam.
W momencie otwarcia lub aktywacji pliku następuje blokada kopiowania i wklejania. Wyłączane jest również przeciąganie komórek. Przy próbie zamknięcia lub deaktywacji pliku – opcje te zostają przywrócone.
Poniższe makra zostały domyślnie zaprojektowane dla starszych wersji Excela. Mogą nie działać w 100% poprawnie w nowszych wersjach. Stanowią jednak solidny punkt wyjścia do pracy nad zablokowaniem wklejania i kopiowania w pliku.
Moduł zwykły
Sub ToggleCutCopyAndPaste(Allow As Boolean)
'Activate/deactivate cut, copy, paste and pastespecial menu items
Call EnableMenuItem(21, Allow) ' cut
Call EnableMenuItem(19, Allow) ' copy
Call EnableMenuItem(22, Allow) ' paste
Call EnableMenuItem(755, Allow) ' pastespecial
'Activate/deactivate drag and drop ability
Application.CellDragAndDrop = Allow
'Activate/deactivate cut, copy, paste and pastespecial shortcut keys
With Application
Select Case Allow
Case Is = False
.OnKey "^c", "CutCopyPasteDisabled"
.OnKey "^v", "CutCopyPasteDisabled"
.OnKey "^x", "CutCopyPasteDisabled"
.OnKey "^r", "CutCopyPasteDisabled"
.OnKey "+{DEL}", "CutCopyPasteDisabled"
.OnKey "^{INSERT}", "CutCopyPasteDisabled"
Case Is = True
.OnKey "^c"
.OnKey "^v"
.OnKey "^x"
.OnKey "^r"
.OnKey "+{DEL}"
.OnKey "^{INSERT}"
End Select
End With
End Sub
Sub EnableMenuItem(ctlId As Integer, Enabled As Boolean)
'Activate/Deactivate specific menu item
Dim cBar As CommandBar
Dim cBarCtrl As CommandBarControl
For Each cBar In Application.CommandBars
If cBar.Name <> "Clipboard" Then
Set cBarCtrl = cBar.FindControl(ID:=ctlId, recursive:=True)
If Not cBarCtrl Is Nothing Then cBarCtrl.Enabled = Enabled
End If
Next
End Sub
Sub CutCopyPasteDisabled()
'Inform user that the functions have been disabled
MsgBox "Kopiowanie i wklejanie zostało wyłączone w tym pliku.", vbCritical, "UWAGA"
End Sub
Moduł skoroszytu
Private Sub Workbook_Open()
ToggleCutCopyAndPaste False
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ToggleCutCopyAndPaste True
End Sub
Private Sub Workbook_Activate()
ToggleCutCopyAndPaste False
End Sub
Private Sub Workbook_Deactivate()
ToggleCutCopyAndPaste True
End Sub