我有一张受保护的工作表,并且锁定了所有单元格,但没有选中水果单元格B2
。我编写了如下代码:如果我在单元格中输入“Mango”,B2
则工作表将不受保护,并解锁单元格J2
并再次保护工作表。然后,当我在单元格中输入数值J2
(如“15”)时,它将在第 15 行插入一行。然后合并A15:C15
。它运行良好。但问题是,当它插入一行时,该行下方的所有其他内容都会消失。此外,此代码中缺少我的工作表。我该怎么办。请帮忙。代码供您参考:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim inputCell As Integer
Dim copyRange As String
Dim ws As Worksheet
Dim validateCell As String
Dim fruitType As String
inputCell = Range("J2").Value
copyRange = "A" & inputCell
Set ws = Worksheets("Sheet1")
validateCell = Range("B2").Value
fruitType = "Mango"
If validateCell = fruitType Then
ws.Unprotect Password:="mehedi"
Range("J2").Locked = False
ws.Protect Password:="mehedi"
End If
If Range("J2").Value >= 5 Then
ws.Unprotect Password:="mehedi"
Range(copyRange).EntireRow.Insert
Range(copyRange & ":C" & inputCell).Merge
Range(copyRange & ":C" & inputCell).BorderAround LineStyle:=xlContinuous, Weight:=xlThin
Range("D" & inputCell & ":F" & inputCell).Merge
Range("D" & inputCell & ":F" & inputCell).BorderAround LineStyle:=xlContinuous, Weight:=xlThin
End If
End Sub
@FlexYourData 的更新
答案1
Worksheet_Change
使用时参考范围很重要Target
。
我设置了一些虚拟数据。J2
是空白的。我输入了 MangoB2
并进入 Sub 例程。请注意,当我们启动时,inputCell 为零(因为J2
是空白的)。
因此,copyRange
将为“A0”,这不是有效地址。这不是您此处问题的原因,但它可能导致其他地方出现问题。
我们可以使用Target
来检查哪个单元格已被编辑。因此,对于您的情况,您可以使用如下方法:
If Target.AddressLocal = "$J$2" Then
'do something when J2 was changed
ElseIf Target.AddressLocal = "$B$2" Then
'do something when B2 was changed
Else
'do something else, or nothing
End If
每次当前代码调用 时.EntireRow.Insert
,都会导致Worksheet_Change
再次调用事件,从而导致插入另一行,这又会导致再次调用事件,从而导致插入另一行,依此类推。事实上,我怀疑你的代码会继续插入这样的行,导致下面的数据看起来好像消失了。这也可能会导致速度变慢。
因此,您应该始终参考Target
,以便宏仅在您更改特定单元格时(而不是在插入行时)才采取行动。
您可能需要考虑的另一件事是将密码作为常量放在此工作表中或将全局常量放在另一个模块中。如果您不希望用户看到该密码,则需要锁定 VBA 项目,如下所述这里。我认为这会对您有一点帮助,因为您只需要在 VBA 项目中输入一次,因此出现拼写错误的机会更少。
通过将其粘贴到工作表后面的代码中,看看这是否适合您。Option Explicit
通常是一个好主意,因为它强制系统不接受变量,除非它们Dim
是
Option Explicit
Const pwd As String = "mehedi"
Private Sub Worksheet_Change(ByVal Target As Range)
Dim inputCell As Integer
Dim copyRange As String
Dim ws As Worksheet
Dim validateCell As String
Dim fruitType As String
'this is just giving a short name for the current sheet
Set ws = ActiveSheet
'set this at the top
fruitType = "Mango"
If Target.AddressLocal = "$J$2" Then
'do something when J2 was changed
inputCell = Target
'only take action if the condition is met
If inputCell >= 5 Then
copyRange = "A" & inputCell
ws.Unprotect Password:=pwd
ws.Range(copyRange).EntireRow.Insert 'causes this event to fire again, so be careful~
ws.Range(copyRange & ":C" & inputCell).Merge
ws.Range(copyRange & ":C" & inputCell).BorderAround LineStyle:=xlContinuous, Weight:=xlThin
ws.Range("D" & inputCell & ":F" & inputCell).Merge
ws.Range("D" & inputCell & ":F" & inputCell).BorderAround LineStyle:=xlContinuous, Weight:=xlThin
'perhaps you need this here as well?
ws.Protect Password:=pwd
End If
ElseIf Target.AddressLocal = "$B$2" And Target.Value = fruitType Then
'only take action if the right fruit was entered into the right cell
ws.Unprotect Password:=pwd
ws.Range("J2").Locked = False
ws.Protect Password:=pwd
End If
End Sub
编辑:
上面列出的代码在以下一系列步骤中运行良好:
- 除 B2 外所有单元格均已锁定
- 在B2中输入“Mango”
- 工作表不受保护,J2 已解锁,工作表受保护
- 在 J2 中输入 15
- 行插入到当前行 15 上方,A15:C15 合并并赋予边框,D15:F15 合并并赋予边框
目前我唯一能想到的是您的问题中有一些您没有说明的细节。在这种情况下,您需要调试此问题。