通过WorkbookOpen事件打开受密码保护的工作簿

时间:2017-10-31 17:05:49

标签: excel excel-vba vba

我有很多工作簿提示输入密码,所以我想跳过这个步骤,使用VBA为我输入密码。这可能吗?我猜不是因为WorkbookOpen事件在本书打开之前不会触发是吗?

我的personal.xlsb中有一个类模块,代码如下:

Private WithEvents appEvent As Application

Private Sub Class_Initialize()
    Set appEvent = Application
End Sub

Private Sub AppEvent_WorkbookOpen(ByVal wb As Excel.Workbook)

If wb.name = "PERSONAL.XLSB" Then Exit Sub

Dim prefix As String
Dim bookName As String
Dim path As String
Dim password As String
Dim dd As String
Dim book As Workbook

prefix = Left(wb.name, 3)

If prefix = "DD0" Then
    dd = Mid(wb.name, 4, 5)
    path = wb.path & "\"
    bookName = wb.name

    skipPass path, bookName, dd
End If

End Sub

然后我在personal.xlsb中有一个模块,其中包含以下内容:

Sub skipPass(p As String, n As String, center As String)

Dim book As Workbook
Set book = Workbooks.Open(filename:=p & n, UpdateLinks:=0, password:=pass(p, center))

End Sub

Function pass(path As String, ddN As String)

Select Case path
...
end function

第一次打开工作簿时,它会提示我输入密码。然后代码运行正常,除了它只是永远循环。我想我可以通过设置全局标志来解决循环问题但是如何解决第一个问题呢?

2 个答案:

答案 0 :(得分:0)

这种方法不起作用,因为正如您所猜测的那样,AppEvent_WorkbookOpen事件在您手动提供密码之前不会触发。

您必须从头开始处理文件打开,即通过编程使用Application.GetOpenFileName获取一个或多个要打开的文件名的子文件,然后根据您的逻辑提供密码。您的子组件可以通过组合键调用;搜索Application.OnKey示例。

请注意,VBA中的字符串比较区分大小写;每当需要进行不区分大小写的比较时,请使用StrComp函数。

答案 1 :(得分:0)

创建了一个名为coa的类,其中包含以下内容:

Private Type ddData
    path As String
    passw As String
End Type

Private this As ddData

Public Property Get path() As String
    path = this.path
End Property

Public Property Let path(ByVal value As String)
    this.path = value
End Property

Public Property Get passw() As String
    passw = this.passw
End Property

Public Property Let passw(ByVal value As String)
    this.passw = value
End Property

然后在模块中进行以下操作:

Private Sub noPass()

Dim ddN As String
Dim wb As Workbook
Dim dd As coa

ddN = InputBox("File?")
If ddN = "" Then Exit Sub

dd = grabddData(ddN)
Set wb = Workbooks.Open(filename:=dd.path & ddN & ".xlsm", UpdateLinks:=0, password:=dd.passw)

End Sub

Private Function grabddData(ByVal ddNumber) As coa 'returns our class

Dim result As New coa 'create an object of our class

Select Case ddNumber
...
Set grabddData = result 'return our class object

End Function

不太理想,但很好。