我有一个带有Worksheet_Change事件的电子表格,该事件调用模块中的sub。worksheet_change代码为:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim itemType As String, material As String, size As Variant, rating As Variant, weldType As String
Dim rowNum, i, iMax, j As Double
If Target.Count > 1 Then Exit Sub
Disable_Slowdowns
'....code for other columns which is not triggered....
If Target.Column = 4 And Target.row > 4 Then
If Len(Target.Value2) > 0 Then AutoFill_By_PN Target
End If
Enable_Slowdowns
End Sub
Enable_Slowdowns和Disable_Slowdowns subs的代码,存储在一个模块中:
Sub Disable_Slowdowns()
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
End Sub
Sub Enable_Slowdowns()
If Application.EnableEvents = False Then Application.EnableEvents = True
If Application.ScreenUpdating = False Then Application.ScreenUpdating = True
If Application.Calculation = xlCalculationManual Then Application.Calculation = xlCalculationAutomatic
End Sub
然后,执行这项工作的子模块名为AutoFill_by_PN (一个变量在子模块外部声明,名为selectedPartIndex):
Public selectedPartIndex As Integer
Public Sub AutoFill_By_PN(ByVal rngPN As Range)
Dim vCell As Variant
Dim wb, costingWB As Workbook
Dim strTemp, PN, sName, sPrice, sSize, sType As String
Dim quotePosR, spacePosL, counter, i, k As Integer
Dim priceL, priceR As Variant
Dim dict As Object
Disable_Slowdowns
Set dict = CreateObject("Scripting.Dictionary")
PN = rngPN.Value2
Set costingWB = ActiveWorkbook
Set wb = Workbooks.Open(Filename:="Z:\Shared\Materials\Parts Book\New Parts Book - Official.xlsx", UpdateLinks:=1, ReadOnly:=1)
counter = 0
selectedPartIndex = -1
For Each vCell In wb.Sheets("PARTS BOOK").Range("$F$260:$F$3872")
With vCell
If InStr(1, .Value2, PN, vbTextCompare) > 0 Then
sName = "name" & counter
sType = "type" & counter
sPrice = "price" & counter
sSize = "size" & counter
dict.Add sName, .Value2
dict.Add sType, .Offset(, -2).Value2
quotePosR = InStr(1, .Value2, """", vbTextCompare)
If quotePosR > 0 Then
spacePosL = InStrRev(.Value2, " ", quotePosR, vbBinaryCompare)
strTemp = Evaluate(Replace(Mid(.Value2, spacePosL + 1, quotePosR - spacePosL - 1), "-", "+", compare:=vbTextCompare))
dict.Add sSize, strTemp
Else
dict.Add sSize, ""
End If
priceR = .Offset(, 3).Value2
priceL = .Offset(, 2).Value2
If IsNumeric(priceL) And IsNumeric(priceR) Then
If priceL - priceR <= 0 Then
dict.Add sPrice, priceR
Else
dict.Add sPrice, priceL
End If
ElseIf IsNumeric(priceL) Then
dict.Add sPrice, priceL
ElseIf IsNumeric(priceR) Then
dict.Add sPrice, priceR
Else
dict.Add sPrice, ""
End If
counter = counter + 1
End If
End With
Next vCell
If counter - 1 <= 0 Then
With rngPN
.Offset(, 3).Value2 = dict(sName)
.Offset(, 4).Value2 = dict(sType)
.Offset(, 6).Value2 = dict(sSize)
.Offset(, 13).Value2 = dict(sPrice)
End With
Else
For i = 0 To counter - 1
UF_PartSelection.LB_PartList.AddItem dict("name" & i), i
Next i
UF_PartSelection.Show
End If
If selectedPartIndex >= 0 Then
With rngPN
.Offset(, 3).Value2 = dict("name" & selectedPartIndex)
.Offset(, 4).Value2 = dict("type" & selectedPartIndex)
.Offset(, 6).Value2 = dict("size" & selectedPartIndex)
.Offset(, 13).Value2 = dict("price" & selectedPartIndex)
End With
End If
Enable_Slowdowns
End Sub
其思想是在单元格中输入零件编号,然后搜索零件手册,并在其他列中填充一些值。重要的是,有时会在多个部件的文本中找到部件号,此时会显示一个用户表单,让用户选择正确的部件。表单正在显示,所有涉及到的代码运行都没有错误,直到最后一行(字面上),当worksheet_change代码到达"End Sub“时-然后我收到一条消息”此操作将重置项目“。
为什么会发生这种情况?下面用户表单的代码(字段已正确填充,所选项目已正确捕获)
Private Sub cmd_ok_Click()
Dim i, indexNo As Integer, vItem As Variant
indexNo = -1
For i = 0 To Me.LB_PartList.ListCount
If Me.LB_PartList.Selected(i) = True Then indexNo = i
Next i
If indexNo >= 0 Then capture_ListBox_Index indexNo Else capture_ListBox_Index -1
Unload Me
End Sub
以及捕获列表框选择的代码,位于与AutoFill_by_PN子模块相同的模块中:
Public Sub capture_ListBox_Index(indexNo As Integer)
selectedPartIndex = indexNo
End Sub
任何帮助都是非常感谢的。我似乎无法确定是什么操作特别触发了项目重置-每次在调试模式下单步执行代码时,它都会发生在worksheet_change代码的"End Sub“行上。
编辑:我发现当只有一个匹配的部件号时,代码运行得很好。这让我相信它一定与用户表单代码有关,因为只有当有多个匹配时才会显示用户表单。此外,单元格值都会根据用户在用户表单中选择的部分正确更新,即使我收到“项目必须重置”消息也是如此。非常奇怪。
编辑2:我试着在AutoFill_By_PN子模块中运行这段代码,仍然有同样的问题:
If counter - 1 <= 0 Then
With rngPN
.Offset(, 3).Value2 = dict(sName)
.Offset(, 4).Value2 = dict(sType)
.Offset(, 6).Value2 = dict(sSize)
.Offset(, 13).Value2 = dict(sPrice)
End With
Else
Dim ui As New UF_PartSelection
For i = 0 To counter - 1
ui.LB_PartList.AddItem dict("name" & i), i
ui.LB_PartList.List(i, 1) = FormatCurrency(dict("price" & i), 2)
Next i
ui.Show
End If
编辑3:感谢您的评论。在重写上面所示的"else“块中的代码之后,问题就解决了!代码如下:
Else
Dim ui As UF_PartSelection
Set ui = New UF_PartSelection
For i = 0 To counter - 1
ui.LB_PartList.AddItem dict("name" & i), i
ui.LB_PartList.List(i, 1) = FormatCurrency(dict("price" & i), 2)
Next i
ui.Show
End If
发布于 2018-12-13 03:43:58
我已经解决了这个问题,尽管我一点也不理解它。由于某些原因,当worksheet_change子进程终止时,打开VBE窗口会导致项目重置。关闭VBE窗口可消除此问题。有人知道为什么吗?我以前从来没有遇到过这样的事情。
https://stackoverflow.com/questions/53748850
复制相似问题