2013-10-24 7 views
0

Я запускаю макрос, который автоматически защищает рабочий лист при изменении значения ячейки (с паролем). Этот макрос работает все время на всех открытых листах. Это должно быть так. Но когда у меня есть еще один файл excel, он также защищает этот лист с паролем. Как я могу ограничить свой макрос только тем файлом, в котором он находится?Ограничить макрос excel vba до одного файла

Спасибо!

Private Sub Worksheet_Calculate() 
Dim FormulaRange As Range 
Dim FormulaRange2 As Range 
Dim NotSentMsg As String 
Dim MyMsg As String 
Dim SentMsg As String 
Dim MyLimit As Double 

NotSentMsg = "Niet verzonden" 
SentMsg = "Verzonden" 

'Above the MyLimit value it will run the macro 
MyLimit = 0 

'Set the range with the Formula that you want to check 
Set FormulaRange2 = ActiveSheet.Range("D22") 

On Error GoTo EndMacro: 
For Each FormulaCell In FormulaRange2.Cells 
    With FormulaCell 
     If IsNumeric(.Value) = False Then 
      MyMsg = "Not numeric" 
     Else 
      If .Value > MyLimit Then 

       MyMsg = SentMsg 

       If .Offset(2, 10).Value = NotSentMsg Then 
        Call Mail_with_outlook2 
       End If 
      Else 
       MyMsg = NotSentMsg 
      End If 
     End If 
     Application.EnableEvents = False 
ActiveSheet.Unprotect Password:="zou82pam" 
     .Offset(2, 10).Value = MyMsg 
ActiveSheet.Protect Password:="zou82pam", DrawingObjects:=True, Contents:=True,  
Scenarios:=True 
ActiveSheet.EnableSelection = xlUnlockedCells 
     Application.EnableEvents = True 
    End With 
Next FormulaCell 

ExitMacro: 
Exit Sub 

EndMacro: 
Application.EnableEvents = True 

MsgBox "De onderstaande error is ontstaan. Neem contact op met Wouter van Leeuwen" _ 
    & vbLf & vbLf & Err.Number _ 
    & vbLf & Err.Description 

End Sub 
+0

Просто мысль. При быстром просмотре ваш код выглядит нормально и не делает _not_ думаю, что он обновит несколько книг (файлов). Так что я думаю, что так или иначе, но вы проверяете, чтобы изменения вызывали ваш макрос, он может стрелять по всем книгам и многократно называть ваш (хороший) макрос? – asantaballa

+1

Я уверен, что многие люди могут помочь вам с ответом; но, возможно, это поможет вам, если вы примете несколько ответов на вопросы, которые вы получили в прошлом. – Trace

+0

@KimGysen Я всегда нажимал стрелку вверх, думая, что это согласится с ответом. Просто узнал иначе. Спасибо за совет! – Wtr

ответ

1

Это прекрасный пример того, как ActiveSheet открывает возможные ошибки и их следует избегать, насколько это возможно.

Первое, что вам нужно сделать, это всегда соблюдать следующую иерархию объектов:

(application) -> workbook -> sheet -> range 

В переводе на VBA это означает, что это хорошая практика, чтобы всегда записывайте всю иерархию:

Thisworkbook.Sheets('sheetname').range("A1") 

Если вы используете несколько объектов приложения или, чаще всего, книги, вы контролируете объекты, которые хотите манипулировать.

Теперь вместо использования:

ActiveSheet.Unprotect Password:="zou82pam" 
     .Offset(2, 10).Value = MyMsg 
ActiveSheet.Protect Password:="zou82pam", DrawingObjects:=True, Contents:=True,  
Scenarios:=True 
ActiveSheet.EnableSelection = xlUnlockedCells 
     Application.EnableEvents = True 
    End With 

Вы бы:

Thisworkbook.sheets("somesheet").Unprotect Password:="zou82pam" 
     .Offset(2, 10).Value = MyMsg 
Thisworkbook.sheets("somesheet").Protect Password:="zou82pam", DrawingObjects:=True, Contents:=True,  
Scenarios:=True 
Thisworkbook.sheets("somesheet").EnableSelection = xlUnlockedCells 
     Application.EnableEvents = True 
    End With 

Теперь в случае, если вам нужно перебрать несколько листов, вы всегда можете использовать индекс листа вместо имени листа. Например:

Dim iCnt as integer 

for iCnt = 1 to 10 
    Thisworkbook.sheets(iCnt).range("A1").value = "this is an example on how to use the sheet index" 
next iCnt 
+0

благодарит @kimgysen за ответ. Очень ясно, и это имеет смысл. В следующий раз я сохраню иерархию. Просто мысль. Можете ли вы использовать этот workbook.activesheet.protect также? Я использую один лист в качестве шаблона для создания нового. Это копирует макрос. Но тогда мне нужно переименовать имя листа в макрос в новом листе, чтобы он работал на новом листе. – Wtr

+1

Это технически возможно, но я всегда советую против этого. По моему опыту, использование activesheet приводит, чаще всего, к ошибкам. Не сразу, но VBA - это типичный язык, который через некоторое время превратится в беспорядок из-за людей, которые добавляют и удаляют код, не задумываясь. Другое дело, что я сомневаюсь в дизайне вашего приложения. Копирование листа с VBA кажется странной практикой; Я не уверен, почему вы это сделаете. Модули VBA в листах должны использоваться только для событий листа (например, активировать, заменять и т. Д.). – Trace

+1

Ну, мы запускаем статистику на листе. Всякий раз, когда мы делаем новый тест, мы создаем новый лист. Но так как многие сотрудники здесь не знают, что это хорошо, это в основном приводит к тому, что люди меняют листы, что приводит к неправильным вычислениям. Поэтому я сделал это «dumbo-proof», поэтому им нужно только нажать кнопку. Я согласен, что это не идеально, но это немного лучше, чем всегда корректировать листы, когда кому-то хотелось добавить несколько вещей;) Но я запомню ваш совет.Возможно, я найду обходное решение или поручу своим коллегам. – Wtr

Смежные вопросы