我有一个由几个受保护的工作表组成的工作簿。我想使用Excel查找&替换对话框,但需要在打开工作表之前取消保护,并在关闭工作表时重新保护;"替换"对话框。我最初试图将命令按钮编码如下:
Private Sub cbFindReplace_Click()
ActiveSheet.Unprotect Password:="*password*"
Application.Dialogs(xlDialogFormulaReplace).Show
ActiveSheet.Protect Password:="*password*", DrawingObjects:=True, Contents:=True, _
Scenarios:=True, AllowFiltering:=True
End Sub
问题是,这打开了对话框,没有选项按钮,因此可以限制查找&替换为活动图纸。因此,我将上面的Show命令替换为以下命令:
ActiveSheet.Cells.Find what:="", LookAt:=xlWhole
Application.CommandBars("Worksheet Menu Bar").FindControl( _
ID:=1849, recursive:=True).Execute
Find&打开的"替换"对话框包含"选项"按钮和限制为活动图纸的功能,但它不是模态的,因此保护图纸命令在打开对话框后直接执行,并阻止进行替换。有人有一个解决方案,允许使用现有的Excel查找&替换对话框,不要创建用户表单来复制该逻辑。
经过一点尝试和错误之后,我得到了以下代码,可以按照您的意愿工作。
请注意,在等待find and replace
对话框关闭时,很可能有更好的方法来处理代码——我一开始没有确切的解决方案,但认为这可能有效——事实确实如此。
根据wordribbon.tips.net中的"检测打开的对话框",我借用了代码来查找Find and replace
对话框的打开窗口。根据文章;
对话框不过是一个打开的窗口,每个对话框都有一个名称。
在确认了这一点后,我做了一些修改,我将在下面的代码中解释。
在VBE中创建一个新模块(或将以下内容添加到现有模块中(
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal wClassName As Any, ByVal wWindowName As String) As Long
请注意,这在Sheet
或Workbook
模块中不起作用,您需要将其添加到您创建的模块中-插入>模块
创建一个返回布尔值的函数,该函数确定对话框是否打开
Function testDialogOpen() As Boolean
Dim wHandle As Long
Dim wName As String
wName = "Find and Replace"
wHandle = FindWindow(0&, wName)
If wHandle = 0 Then
testDialogOpen = False
Else
testDialogOpen = True
End If
End Function
在保护图纸之前,对代码进行轻微修改,以检查对话框是否打开
Sub unprotect_findandreplace_protect()
Sheet1.Unprotect "abc123"
Application.CommandBars("Edit").Controls("Find...").Execute
While testDialogOpen()
DoEvents
Wend
Sheet1.Protect "abc123"
End Sub
While...Wend
循环在每次迭代中评估Find and Replace
窗口是否打开。它通过调用返回True
或False
结果的testDialogOpen()
函数来完成此操作。循环将继续运行,直到Find and Replace
对话框关闭,然后退出循环并转到下一行,重新保护图纸。
有趣的问题。不幸的是,Samuel的解决方案在我的电脑上不起作用:/(Excel显示我的替换对话框,但我无法使用替换功能-Excel显示错误(
这对我有效:
#If VBA7 Then
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#Else
Private Declare Function FindWindow Lib "User32.dll" Alias "FindWindowA" (ByVal lpszClass As String, ByVal lpszWindow As String) As Long
#End If
Sub DialogOpen()
ActiveSheet.Unprotect
Application.CommandBars.ExecuteMso ("ReplaceDialog")
DoEvents
Application.OnTime Now + TimeValue("00:00:01"), "OnTime"
End Sub
Sub OnTime()
Dim wHandle As Long
Dim wName As String
wName = "Find and Replace"
wHandle = FindWindow(vbNullString, wName)
DoEvents
If wHandle = 0 Then
ActiveSheet.Protect
Else
Application.OnTime Now + TimeValue("00:00:01"), "OnTime"
End If
End Sub