[英]VBA Project Password-Protect with SendKeys not Working Correctly
I've spent the last two days working on this problem. 我花了最后两天的时间来解决这个问题。 Most of the content I've found on this topic doesn't address the issue I'm having, so I'm hopeful that someone here can help me.
我在该主题上找到的大多数内容都无法解决我遇到的问题,因此我希望这里有人可以帮助我。
I've been working on some code that does the following from a "master scorecard" workbook: 我一直在研究一些代码,这些代码可以从“主记分卡”工作簿中执行以下操作:
Workbook_Open
event and a Workbook_BeforeClose
event to the new workbook (to make certain sheets xlVeryHidden
depending on level of access), Workbook_Open
事件和Workbook_BeforeClose
事件添加到新工作簿中(根据访问级别将某些工作表设为xlVeryHidden
), Each scorecard uses code to ensure that only the person whose name is on the scorecard can access it. 每个计分卡都使用代码来确保只有名称在计分卡上的人才能访问它。 I've used
Environ("username")
in the workbook events to ensure security, but as you well know, if one and understands how to run macros, he/she could merely open the VBEditor
and unhide the xlVeryHidden
sheets in the workbook very easily. 我已经在工作簿事件中使用
Environ("username")
来确保安全性,但是众所周知,如果一个人知道如何运行宏,他/她只能打开VBEditor
并取消隐藏工作簿中的xlVeryHidden
工作表。容易。
So, my thought was to password protect the new workbook's VBAProject
programmatically (see above: step number five). 因此,我的想法是以编程方式用密码保护新工作簿的
VBAProject
(请参见上文:第五步)。 I found a few sources online of how to use SendKeys
to achieve this goal (see below), but SendKeys
is unreliable (at best) and isn't cooperating with my code. 我在线上找到了一些有关如何使用
SendKeys
实现此目标的资源(请参阅下文),但是SendKeys
不够可靠(充其量),并且与我的代码不配合。 The code works like a charm if I run it by itself, but if I call it from another project using Run Macro:="filename!macroname"
it doesn't set the protection. 如果我自己运行该代码,则它的工作方式就像一个
Run Macro:="filename!macroname"
,但是如果我使用Run Macro:="filename!macroname"
从另一个项目中调用它,则不会设置保护。 After the code has run and all the workbooks have been created, the VBAProject
properties window(s) from the earlier code are all open and try to execute at the same time which crashes Excel. 运行代码并创建所有工作簿后,先前代码中的
VBAProject
属性窗口将全部打开,并尝试同时执行,这会使Excel崩溃。
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
I'm not sure why this is happening; 我不确定为什么会这样。 like I said, the code works fine when run on its own.
就像我说的那样,代码单独运行时效果很好。 I found this post where this link to a non-
SendKeys
approach was outlined, but it was written several years ago and I'm not sure how I'd need to modify it for my purposes since I've never coded in VB6... 我找到了这篇文章 ,其中概述了与非
SendKeys
方法的链接 ,但是它是几年前编写的,由于我从未在VB6中编写过代码,因此我不确定出于我的目的需要对其进行修改。 。
Are there any thoughts as to why the SendKeys
method is bunching up after the code has already run instead of executing when it's supposed to during the code? 关于为什么在代码已经运行之后而不是在代码执行期间应该执行的情况下,为什么
SendKeys
方法会堆积起来,是否有任何想法? Should I abandon SendKeys
in favor of this other method? 我应该放弃
SendKeys
来支持其他方法吗? I'm at a loss, so any help will be much appreciated! 我很茫然,所以任何帮助将不胜感激!
EDIT: I think the reason the code isn't working is because the correct project isn't activated at the time the SendKeys
code is executed. 编辑:我认为代码不起作用的原因是因为执行
SendKeys
代码时未激活正确的项目。 I had hoped that activating the proper workbook would solve the issue, but it doesn't appear to have helped. 我曾希望激活适当的工作簿能够解决此问题,但似乎没有帮助。
Ok, so after another couple of hours of searching the web for alternative methods to achieve my goal, I stumbled across this post . 好的,因此在经过两个小时的网络搜索以实现我的目标的替代方法之后,我偶然发现了这篇文章 。
I created a template workbook (with the event code already in ThisWorkbook
), password protected the project, and modified my code to use the template workbook for each new sheet. 我创建了一个模板工作簿(事件代码已经在
ThisWorkbook
),用密码保护了该项目,并修改了我的代码以将模板工作簿用于每个新工作表。 Now when the sheets are created, the project is already locked for viewing and requires a password. 现在,在创建图纸后,该项目已被锁定以供查看,并且需要密码。 While I realize the security under this approach isn't very secure, it will help "keep honest people honest" as they say.
尽管我意识到这种方法下的安全性不是很安全,但可以帮助他们“诚实地诚实”。
For those who stumble across this post and still wish to programmatically lock/unlock their VBA Project, see these resources: 对于那些偶然发现这篇文章但仍希望以编程方式锁定/解锁其VBA项目的人,请参阅以下资源:
This SO post 这样的帖子
This blog 这个博客
Both are great resources that walk through a way to do it in VBA. 两者都是很好的资源,它们都介绍了在VBA中进行操作的方法。
To add a nuance to the otherwise fine piece of code originally posted here: If you change the Project Name for the workbook within the VBE, you'll need to change one line of code to: 要为原本发布在此处的精美代码增加一些细微差别:如果您在VBE中更改工作簿的项目名称,则需要将一行代码更改为:
.VBE.CommandBars("Menu Bar").Controls("Tools") _
.Controls(VBP.Name & " Properties...").Execute
(sigh) (叹)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.