使用SendKeys无法正常工作的VBA项目密码保护

时间:2013-07-21 22:54:30

标签: vba excel-vba password-protection sendkeys excel

过去两天我一直在研究这个问题。我在这个主题上找到的大部分内容都没有解决我遇到的问题,所以我希望有人可以帮助我。

我一直致力于从“主记分卡”工作簿中执行以下操作的代码:

  1. 获取工作簿中的每个“学生”工作表,并将工作表复制到新工作簿中,
  2. 对新工作簿进行一些小的操作,
  3. 将代码模块导入新工作簿
  4. 向新工作簿添加Workbook_Open个事件和Workbook_BeforeClose个事件(根据访问级别制作某些工作表xlVeryHidden),
  5. 从新导入的模块中运行子过程
  6. 保存并关闭工作簿。
  7. 每个记分卡使用代码确保只有名字在记分卡上的人才能访问它。我在工作簿事件中使用Environ("username")来确保安全性,但是众所周知,如果一个人了解如何运行宏,他/她只能打开VBEditor并取消隐藏{{1工作簿中的工作表非常容易。

    所以,我的想法是以编程方式密码保护新工作簿xlVeryHidden(见上文:第五步)。我在网上找到了一些关于如何使用VBAProject来实现这一目标的消息来源(见下文),但SendKeys不可靠(充其量)并且不与我的代码合作。如果我自己运行它,代码就像一个魅力,但如果我使用SendKeys从另一个项目调用它,它就不会设置保护。代码运行并且已创建所有工作簿后,早期代码中的Run Macro:="filename!macroname"属性窗口全部打开,并尝试在崩溃Excel的同时执行。

    VBAProject

    我不确定为什么会这样;就像我说的,代码在单独运行时工作正常。我发现this post其中this link指的是非Sub LockVBAProject() Const VBAProjectPassword As String = "123" Dim VBP As VBProject, openWin As VBIDE.Window Dim wbActive As Workbook Dim i As Integer Set wbActive = ActiveWorkbook Set VBP = wbActive.VBProject Application.ScreenUpdating = False ' close any code windows to ensure we hit the right project For Each openWin In VBP.VBE.Windows If InStr(openWin.Caption, "(") > 0 Then openWin.Close Next openWin wbActive.Activate With Application '//execute the controls to lock the project\\ .VBE.CommandBars("Menu Bar").Controls("Tools") _ .Controls("VBAProject Properties...").Execute '//activate 'protection'\\ .SendKeys "^{TAB}" '//CAUTION: this either checks OR UNchecks the\\ '//"Lock Project for Viewing" checkbox, if it's already\\ '//been locked for viewing, then this will UNlock it\\ .SendKeys "{ }" '//enter password\\ .SendKeys "{TAB}" & VBAProjectPassword '//confirm password\\ .SendKeys "{TAB}" & VBAProjectPassword '//scroll down to OK key\\ .SendKeys "{TAB}" '//click OK key\\ .SendKeys "{ENTER}" 'the project is now locked - this takes effect 'the very next time the book's opened... End With ThisWorkbook.SaveAs Filename:=Sheets(Sheets.Count).Name, FileFormat:=xlOpenXMLWorkbookMacroEnabled Debug.Print "It Worked " & Now() End Sub 方法,但几年前就写了,我不知道为了我的目的我需要修改它因为我从来没有用VB6编码......

    是否有任何想法为什么SendKeys方法在代码已经运行之后聚集而不是在代码期间应该执行?我应该放弃SendKeys支持这种其他方法吗?我很茫然,所以任何帮助都会非常感激!

    编辑:我认为代码无效的原因是因为在SendKeys代码执行时没有激活正确的项目。我曾希望激活正确的工作簿可以解决问题,但似乎没有帮助。

2 个答案:

答案 0 :(得分:1)

好的,所以经过几个小时的搜索网络寻找替代方法来实现我的目标之后,我偶然发现了this post

我创建了一个模板工作簿(事件代码已在ThisWorkbook中),密码保护项目,并修改了我的代码以使用每个新工作表的模板工作簿。现在,在创建工作表时,项目已锁定以供查看并需要密码。虽然我意识到这种方法下的安全性不是很安全,但正如他们所说,它将有助于“保持诚实的人诚实”。

对于那些偶然发现此帖并仍希望以编程方式锁定/解锁其VBA项目的人,请参阅以下资源:

This SO post
This blog

两者都是很好的资源,可以在VBA中实现这一目标。

答案 1 :(得分:0)

为最初在此处发布的其他代码添加细微差别:如果在VBE中更改工作簿的项目名称,则需要将一行代码更改为:

   .VBE.CommandBars("Menu Bar").Controls("Tools") _
        .Controls(VBP.Name & " Properties...").Execute

(叹气)