我有一个处理一系列输入工作簿的工作簿,其中一些工具簿设置了VBA密码,但未锁定查看 - 即导航vb代码不需要密码,但查看项目属性需要密码(例如工具/参考资料)。在这种情况下,即使设置了密码,VBProject.Protection也会设置为vbext_pp_none。我可以检查什么来检测“查看项目属性的密码”?
答案 0 :(得分:0)
当您保护项目时,您必须勾选方框并提供密码。
换句话说,你的一个但另一个的逻辑是有道理但不会发生(我知道(我在Excel 2010上测试过)),它是vbext_pp_none
(0)或{ {1}} ...(1)。
编辑/补充: -
在阅读你的评论后,我无法重现这种情况,但在所有版本/平台中,我无法想象它是不可能的。下面是一个示例,在错误捕获过程中尝试更改属性,如果成功,则它根本不被锁定。
vbext_pp_locked
答案 1 :(得分:0)
以下代码依赖于问题中不存在的信息,但如果使用Excel 2010(已测试)或2007(未经测试)专门在PC上工作,则应检测是否存在密码以及您已有的代码和在上一个答案的代码中,它应该回答检测密码存在的方法的问题。
最新的办公文件格式是一个zip包,为此您可以将其从.xlsm
重命名为.zip
并查看其内容。在zip包中,bin
文件夹中可能存在xl
文件(如果文件中没有VBA,则不存在)。在bin
文件中有一个名为'DPB'的字符串值,该值已加密,但如果有密码,则值为long,因此可以通过'DPB'的长度检测到密码的存在值。
以下代码将受益于重要的错误处理,因为发生了大量文件操作,并且如上所述,这与前一个答案中的代码的更改版本一起使用,应该提供问题的答案
下面的代码需要添加“Windows Scripting Runtime”参考(工具>参考>勾选'Windows Scripting Runtime'),我没有后期绑定,以便更快地编写它并且可能更清晰。我还在整个代码中评论了描述正在发生的事情
Public Sub Sample()
Dim FSO As New FileSystemObject
Dim Shl As Object
Dim Fl As Scripting.File
Dim Fldr As Scripting.Folder
Dim LngCounter As Long
Dim Ts As Scripting.TextStream
Dim StrTmpFldr As String
Dim StrWkBk As String
Dim StrWkBkName As String
Dim StrContainer As String
Dim WkBk As Excel.Workbook
'A place to work with temp files, for my own ease I done it on the desktop
'but this is not good practice
StrTmpFldr = Environ("UserProfile") & "\Desktop\"
'A path to a workbook (may be passed in)
StrWkBk = Environ("UserProfile") & "\Desktop\Book4.xlsm"
'We need the file name seperate from the path
StrWkBkName = Right(StrWkBk, Len(StrWkBk) - InStrRev(StrWkBk, "\"))
'Copy the workbook and change it to a .zip (xlsx, and other new forms are zip packages)
FSO.CopyFile StrWkBk, StrTmpFldr & Left(StrWkBkName, InStrRev(StrWkBkName, ".")) & "zip", True
'Create a folder to extract the zip to
FSO.CreateFolder StrTmpFldr & Left(StrWkBkName, InStrRev(StrWkBkName, ".") - 1)
'Unzip it into the folder we created
Set Shl = CreateObject("Shell.Application")
Shl.Namespace(StrTmpFldr & Left(StrWkBkName, InStrRev(StrWkBkName, ".") - 1) & "\").CopyHere Shl.Namespace(StrTmpFldr & Left(StrWkBkName, InStrRev(StrWkBkName, ".")) & "zip").Items
Set Shl = Nothing
'Delete the zip
FSO.DeleteFile StrTmpFldr & Left(StrWkBkName, InStrRev(StrWkBkName, ".")) & "zip", True
Set Fldr = FSO.GetFolder(StrTmpFldr & Left(StrWkBkName, InStrRev(StrWkBkName, ".") - 1) & "\xl\")
'Is there a project file? (there won't be if there is no code in it)
For Each Fl In Fldr.Files
If Right(Fl.Name, 4) = ".bin" Then Exit For
Next
If Fl Is Nothing Then
MsgBox "It is not protected"
Else
'Parse the file looking for the line starting "DPB="" if the value in here is over 25 long,
'then it is storing a password
Set Ts = Fl.OpenAsTextStream(ForReading)
Do Until Ts.AtEndOfStream
StrContainer = Ts.ReadLine
If Left(StrContainer, 5) = "DPB=" & """" Then
StrContainer = Replace(Replace(StrContainer, "DPB=", ""), """", "")
If Len(StrContainer) > 25 Then
MsgBox "It is protected"
Else
MsgBox "It is not protected"
End If
Exit Do
End If
Loop
Ts.Close
Set Ts = Nothing
Set Fl = Nothing
End If
Set Fldr = Nothing
'Delete the folder
FSO.DeleteFolder StrTmpFldr & Left(StrWkBkName, InStrRev(StrWkBkName, ".") - 1), True
End Sub