将vba"查找和替换"限制为活动工作表



我有一个由几个受保护的工作表组成的工作簿。我想使用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

请注意,这在SheetWorkbook模块中不起作用,您需要将其添加到您创建的模块中-插入>模块


创建一个返回布尔值的函数,该函数确定对话框是否打开

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窗口是否打开。它通过调用返回TrueFalse结果的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

最新更新