【发布时间】:2014-04-18 15:41:04
【问题描述】:
我正在使用脚本来监视文件夹以添加文件。如果将 3 个文件(满足条件)添加到受监视的文件夹中,则脚本运行良好。它很好地从这些文件中提取数据并添加到打开的 excel 文件中。但是,如果条件不是我,脚本会继续通过Do While Loop,并且我无法使用 excel 上的任何按钮(正在考虑使用另一个命令按钮来退出循环)。请帮忙!!任何建议表示赞赏!谢谢!
Public vItem As Variant
'vItem contains the folder path that the user selects.
'Another function deals with this and only its values is passed to `CommandButton2 Click()`
Private Sub CommandButton2_Click()
Dim i As Integer
i = 0
Dim fcounter, pcounter, vcounter As Integer
fcounter = 0
pcounter = 0
vcounter = 0
Set objShell = CreateObject("Wscript.Shell")
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Dim vItemstr As String
vItemstr = Replace(vItem, "\", "\\\\")
MsgBox vItemstr
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE " _
& "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _
& "TargetInstance.GroupComponent= " _
& "'Win32_Directory.Name=" & Chr(34) & vItemstr & Chr(34) & "'")
Do While True
Set objLatestEvent = colMonitoredEvents.NextEvent
StrNewfile = objLatestEvent.TargetInstance.PartComponent
arrNewFile = Split(StrNewfile, "=")
strFileName = arrNewFile(1)
strFileName = Replace(strFileName, "\\", "\")
strFileName = Replace(strFileName, Chr(34), "")
Dim justfilename, namestr As String
justfilename = Dir(strFileName)
Do While True
novaval = InStr(1, justfilename, "SampleResults")
If novaval > 0 Then
namestr = "f"
Exit Do
End If
novaval = InStr(1, justfilename, "v")
If novaval > 0 Then
namestr = "v"
Exit Do
End If
novaval = InStr(1, justfilename, "p")
If novaval > 0 Then
namestr = "p"
Exit Do
End If
Loop
If namestr = "f" And fcounter = 0 Then
i = i + 1
Dim OpenFileName As String
Dim wb As Workbook
Set wb = Workbooks.Open(strFileName, UpdateLinks:=0)
ThisWorkbook.Sheets(1).Range("K18:P18").Value = wb.Sheets(1).Range("G1:L1").Value
ThisWorkbook.Sheets(1).Range("K19:P19").Value = wb.Sheets(1).Range("G5:L5").Value
ThisWorkbook.Sheets(1).Range("K20:P20").Value = wb.Sheets(1).Range("G4:L4").Value
ThisWorkbook.Sheets(1).Range("K21:P21").Value = wb.Sheets(1).Range("G3:L3").Value
ThisWorkbook.Sheets(1).Range("K22:P22").Value = wb.Sheets(1).Range("G2:L2").Value
ThisWorkbook.Save
wb.Close
fcounter = fcounter + 1
ElseIf namestr = "v" And vcounter = 0 Then
i = i + 1
Set wb = Workbooks.Open(strFileName, UpdateLinks:=0)
ThisWorkbook.Sheets(1).Range("C18:E18").Value = wb.Sheets(1).Range("C1:E1").Value
ThisWorkbook.Sheets(1).Range("C19:E19").Value = wb.Sheets(1).Range("C5:E5").Value
ThisWorkbook.Sheets(1).Range("C20:E20").Value = wb.Sheets(1).Range("C4:E4").Value
ThisWorkbook.Save
wb.Close
vcounter = vcounter + 1
ElseIf namestr = "p" And pcounter = 0 Then
i = i + 1
Set wb = Workbooks.Open(strFileName, UpdateLinks:=0)
ThisWorkbook.Sheets(1).Range("F18:H18").Value = wb.Sheets(1).Range("X1:Z1").Value
ThisWorkbook.Sheets(1).Range("F19:H19").Value = wb.Sheets(1).Range("X5:Z5").Value
ThisWorkbook.Sheets(1).Range("F20:H20").Value = wb.Sheets(1).Range("X4:Z4").Value
ThisWorkbook.Save
wb.Close
pcounter = pcounter + 1
End If
If i = 3 Then
Exit Do
End If
Loop
End Sub
【问题讨论】:
-
首先,您没有显示几个变量的 Dim,所以不知道它们是什么。其次,你确定“退出”真的让你脱离了循环吗?您有两个“Do While True”循环。如果你放了一个断点并且没有所需的三个文件,它应该会显示问题所在。
-
感谢韦恩的评论!我注意到缺少
vItem描述,因此我编辑了帖子以澄清该变量。我再次浏览了代码,找不到任何其他未声明的变量。如果您愿意指出这一点,我将编辑帖子以澄清这些变量。关于另一个Do while循环,您有一个很好的观点。让我看一看。但无论如何,即使在我打开监视器后添加另一个循环之前,excel文件上的任何内容都不是“可点击”的,直到监视完成。 -
在模块顶部添加“Option Explicit”,然后添加“Debug |编译'。将显示丢失的 Dim。您应该能够在代码中的第一个“Do While True”处放置一个断点,然后单击按钮开始该过程。然后在代码窗口中,只需按 F8 即可单步执行代码。应该很容易找到问题。最后,您的“Do While True”似乎有点奇怪,因为您没有任何条件会改变“True”条件 - 因此循环将永远运行,直到您“退出”。如果您说“Do While blnFlag = True”并且您在循环中更改 blnFlag,那么这将停止 Do。
-
代码底部
Loop之前的最后一个If语句是结束Do While True循环的内容。基本上它的作用是,只要将 3 个文件添加到受监视的文件夹(每个文件名中都包含“f”或“p”或“v”),Do While True循环就会中断。我想要的是另一个选项,例如,用户可以使用命令按钮手动打破Do While True循环。但不幸的是,正如我上面提到的,一旦循环开始,我就无法点击 Excel 工作表上的任何控件。 -
(1) 以下内容未定义(您是否使用过 Option Explicit 并编译过??):objShell、strComputer、objWMIService、colMonitoredEvents、objLatestEvent、StrNewfile、arrNewFile、strFileName、novaval; (2) 您是否曾尝试使用断点单步执行代码? (3) 如果您修复代码,则无需提供“破解”能力。可能您可以使用计时器和 DoEvents 来让用户中断。