Большинство наверняка знает как установить/снять пароль с VBA проекта вручную:

  1. Tools-VBAProject Properties-вкладка Protection;
  2. для защиты устанавливается галочка "Lock project for viewing"; для разблокировки - снимается;
  3. вписывается/удаляется сам пароль в полях Password и Confirm password.

Предположу, что не очень многим может понадобиться снимать пароль с проекта VBA средствами самого VBA. Но все же данная тема имеет спрос, как я смог убедиться, общаясь на форумах. Прежде всего это может пригодиться тем, кто создает свои приложения на VBA и периодически нужно вносить изменения в уже созданные проекты(например копирование модулей и кодов из одного проекта в другой). Сразу оговорюсь: я не рассматриваю ситуации, когда вам неизвестен пароль к проекту. Предполагается, что вы знаете пароль и можете снять его вручную.

Я лично знаю два способа снять пароль программно: через метод SendKeys и использовании функций API. Т.к. второй способ довольно громоздкий и сложный для понимания - я в данной статье опишу лишь первый способ. Он не содежит каких-либо изысков и довольно прост.

Sub Unprotect_VBA()
    Dim objVBProject As Object, objVBComponent As Object, objWindow As Object
 
    Workbooks.Open "C:\1.xls"
    Set objVBProject = ActiveWorkbook.VBProject
    'просматриваем все окна проекта в поисках окна снятия защиты
    For Each objWindow In objVBProject.VBE.Windows
        ' Type = 6 - это нужное нам окно
        If objWindow.Type = 6 Then
            objWindow.Visible = True
            objWindow.SetFocus: Exit For
        End If
    Next
    'вводим пароль и подтверждаем ввод
    SendKeys "~1234~", True: SendKeys "{ENTER}", True
    'здесь Ваш код по внесению изменений в проект
    Set objVBProject = Nothing: Set objVBComponent = Nothing: Set objWindow = Nothing
    ActiveWorkbook.Close True
End Sub

Код сначала открывает необходимую книгу, а затем снимает пароль с проекта.

"C:\1.xls" - полный путь к книге, включая расширение файла.

"~1234~" - пароль к проекту. Тильды нужны, но они не являются частью кода. Т.е. сам код это - 1234.

Способ, как видите, действительно очень прост, но это порождает и недостатки. Главный недостаток: снятие пароля данным методом весьма нестабильно и иногда может не срабатывать. Так же во время работы данного кода крайне нежелательно пользоваться мышью и клавиатурой. Точнее даже не нежелательно, а просто нельзя, если вам необходим положительный результат.

Также см.:
[[Копирование модулей и форм из одной книги в другую]]
[[Как удалить макросы в книге?]]
[[Как добавить код процедуры программно, скопировать модуль]]
[[Защита листов/снятие защиты]]

22 комментария

    1. А Вы не могли бы конкретизировать?
      Я вот выписываю:

      Dim VBPPr As Boolean
      VBPPr = Application.ThisWorkbook.VBProject.Protection

      И мне стабильно выдает False, независимо от того, флаг выставлен или нет.

  1. vikvas, может я чего не понимаю? Вы чего хотите сделать? Если проект защищен - то пароль будет запрашиваться сразу же, как только Вы захотите хоть к какому-то свойству обратиться. Вводите пароль и потом уже меняйте свойства проекта. Или Вы рассчитывали, что можно просто взять и не зная пароля снять галку и просмотреть код? А нифиг тогда такой пароль?

  2. Добрый день. А как сделать защиту от этого макроса с парой десятков циклов перебора? Например если пароль набран неправильно, то книга-жертва закрывается.

  3. Добрый день!
    Хочу сделать чтобы проект обновлял сам себя.
    Например смотрел на сайте по ссылке новую версию, качал сначала модуль "содержание", затем импортировал все модули.
    Проблемы две:
    Первая - нужно снять (потом поставить обратно) пароль с VBA на время импорта (таки нужен упомянутый способ через API)
    Вторая - Как получить список всех модулей из файла "донора".
    Буду рад если подскажете решение

    1. Вторую проблему победил.
      Вот решение, кому интересно.

      Public Enum MyComponents

      MyAll = -1
      MyWorkSheets = 100
      MyModules = 1
      MyClasses = 2
      MyForms = 3

      End Enum

      Public MyModeCopy

      Private Function GetListComponents(wbFromFrom As Workbook)

      Dim Arr() As String
      ReDim Arr(1 To 1)
      Dim objVBProjFrom As Object

      Set objVBProjFrom = wbFromFrom.VBProject

      For Each Comp In objVBProjFrom.VBComponents
      tN = Comp.Name
      tType = Comp.Type
      If tType = MyModeCopy Or MyModeCopy = MyAll Then
      If Arr(UBound(Arr)) Empty Then ReDim Preserve Arr(LBound(Arr) To UBound(Arr) + 1)
      Arr(UBound(Arr)) = tN
      End If
      Next

      GetListComponents = Arr()

      End Function

      Осталось с паролями разобраться.

  4. Может что поменялось со временем?
    В Excel 2016, цикл по данному методу работает только с текущим проектом из которого был вызван описываемый макрос, т.к. в свойствах objVBProject.VBE.Windows других проектов просто нет.

    Как ни изгалялся, но так и не смог обратиться к нужному проекту для открытия его окна ввода пароля.
    Разве что через ****
    Application.GoTo WBook & "!" & sModName & "." & SubName
    Но это криво. (((

    Есть еще какие-то способы?

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.