Использование VBA / Macro для выделения изменений в Excel
У меня есть электронная таблица, которую я отправляю в разные места, чтобы информация о ней была обновлена, а затем отправлена обратно мне. Однако мне пришлось поставить проверку и заблокировать ячейки, чтобы заставить пользователей вводить точную информацию. Затем я могу использовать VBA, чтобы отключить обходные функции копирования и вставки. И дополнительно я вставил функцию VBA, чтобы заставить пользователей открывать файл Excel в макросах. Сейчас я пытаюсь отслеживать изменения, чтобы знать, что было обновлено, когда я получаю лист обратно. Однако каждый раз, когда я делаю это, я получаю сообщение об ошибке, когда кто-то сохраняет документ, и случайным образом он полностью блокирует меня из документа.
Мой код вставлен ниже, может ли кто-нибудь помочь мне создать код на форуме VBA, чтобы выделить изменения, а не с помощью опции поделиться / отслеживать изменения в Excel?
ThisWorkbook (Код):
Option Explicit
Const WelcomePage = "Macros"
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call ToggleCutCopyAndPaste(True)
'Turn off events to prevent unwanted loops
Application.EnableEvents = False
'Evaluate if workbook is saved and emulate default propmts
With ThisWorkbook
If Not .Saved Then
Select Case MsgBox("Do you want to save the changes you made to '" & .Name & "'?", _
vbYesNoCancel + vbExclamation)
Case Is = vbYes
'Call customized save routine
Call CustomSave
Case Is = vbNo
'Do not save
Case Is = vbCancel
'Set up procedure to cancel close
Cancel = True
End Select
End If
'If Cancel was clicked, turn events back on and cancel close,
'otherwise close the workbook without saving further changes
If Not Cancel = True Then
.Saved = True
Application.EnableEvents = True
.Close savechanges:=False
Else
Application.EnableEvents = True
End If
End With
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
'Turn off events to prevent unwanted loops
Application.EnableEvents = False
'Call customized save routine and set workbook's saved property to true
'(To cancel regular saving)
Call CustomSave(SaveAsUI)
Cancel = True
'Turn events back on an set saved property to true
Application.EnableEvents = True
ThisWorkbook.Saved = True
End Sub
Private Sub Workbook_Open()
Call ToggleCutCopyAndPaste(False)
'Unhide all worksheets
Application.ScreenUpdating = False
Call ShowAllSheets
Application.ScreenUpdating = True
End Sub
Private Sub CustomSave(Optional SaveAs As Boolean)
Dim ws As Worksheet, aWs As Worksheet, newFname As String
'Turn off screen flashing
Application.ScreenUpdating = False
'Record active worksheet
Set aWs = ActiveSheet
'Hide all sheets
Call HideAllSheets
'Save workbook directly or prompt for saveas filename
If SaveAs = True Then
newFname = Application.GetSaveAsFilename( _
fileFilter:="Excel Files (*.xls), *.xls")
If Not newFname = "False" Then ThisWorkbook.SaveAs newFname
Else
ThisWorkbook.Save
End If
'Restore file to where user was
Call ShowAllSheets
aWs.Activate
'Restore screen updates
Application.ScreenUpdating = True
End Sub
Private Sub HideAllSheets()
'Hide all worksheets except the macro welcome page
Dim ws As Worksheet
Worksheets(WelcomePage).Visible = xlSheetVisible
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name = WelcomePage Then ws.Visible = xlSheetVeryHidden
Next ws
Worksheets(WelcomePage).Activate
End Sub
Private Sub ShowAllSheets()
'Show all worksheets except the macro welcome page
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name = WelcomePage Then ws.Visible = xlSheetVisible
Next ws
Worksheets(WelcomePage).Visible = xlSheetVeryHidden
End Sub
Private Sub Workbook_Activate()
Call ToggleCutCopyAndPaste(False)
End Sub
Private Sub Workbook_Deactivate()
Call ToggleCutCopyAndPaste(True)
End Sub
This is in my ModuleCode:
Option Explicit
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 "+{DEL}", "CutCopyPasteDisabled"
.OnKey "^{INSERT}", "CutCopyPasteDisabled"
Case Is = True
.OnKey "^c"
.OnKey "^v"
.OnKey "^x"
.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 " Cutting, copying and pasting have been disabled in this workbook. Please hard key in data. "
End Sub
3 ответа
Я немного изменил ваш модуль, как показано ниже, и вызвал функцию в разделах "Workbook_Open" и "Workbook_Beforeclose" в "This Workbook". В первом случае аргумент функции был False, а во втором аргумент был True. Это работает хорошо. Вам также следует обратиться к коду Йогеша, который является более полным. URL для этого: http://ygblogs.blogspot.com/2009/04/macros-in-excel-disable-cut-copy-paste.html
Вставьте следующее в модуль:
Option Explicit
Dim Allow As Boolean, ctlId As Integer, Enabled As Boolean
Function ToggleCutCopyAndPaste(Allow As Boolean)
'Activate/deactivate cut, copy, paste and pastespecial shortcut keys
With Application
Select Case Allow
Case False
.OnKey "^c", "CutCopyPasteDisabled"
.OnKey "^v", "CutCopyPasteDisabled"
.OnKey "^x", "CutCopyPasteDisabled"
.OnKey "+{DEL}", "CutCopyPasteDisabled"
.OnKey "^{INSERT}", "CutCopyPasteDisabled"
Case True
.OnKey "^c"
.OnKey "^v"
.OnKey "^x"
.OnKey "+{DEL}"
.OnKey "^{INSERT}"
End Select
.CutCopyMode = Allow
.CellDragAndDrop = Allow
End With
'Activate/Deactivate specific menu item
Dim cBar As CommandBar
Dim cBarCtrl As CommandBarControl, i As Integer
For i = 1 To 4
If i = 1 Then ctlId = 21
If i = 2 Then ctlId = 19
If i = 3 Then ctlId = 22
If i = 4 Then ctlId = 755
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 = Allow
End If
Next
Next i
End Function
Вставьте следующее в раздел ThisWorkbook редактора VBA:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ToggleCutCopyAndPaste (True)
End Sub
Private Sub Workbook_Open()
ToggleCutCopyAndPaste (False)
End Sub
Если вам нужно отслеживать и сравнивать изменения, есть простой способ вообще не использовать макросы: попробуйте надстройку контроля версий для Excel.
Вы можете сравнить свою оригинальную электронную таблицу с версиями, полученными от других пользователей. В идеале на них также должна быть установлена надстройка, но не обязательно.
Если вы хотите отслеживать изменения в ваших макромодулях, то этот макрос контроля версий для VBA - это спасение жизни.
Почему бы вам не проверить Ozgrid.com:
http://www.ozgrid.com/VBA/track-changes.htm
Вы можете напрямую реализовать код, а также добавить несколько функций, таких как выделение измененных ячеек и т. Д. Цветом.