And*_*eea 3 excel vba excel-vba
我会尽量在描述中尽可能清楚,所以这里什么都没有:
我创建了一个代码,用户在其中选择他的excel文件,然后宏Sheet将该文件复制到我的宏中Workbook.
MyFile = Application.GetOpenFilename()
Workbooks.Open (MyFile)
ActiveSheet.Copy After:=wbook.Sheets(1)
ActiveSheet.Name = "Selected file"
Workbooks.Open (MyFile)
ActiveWorkbook.Close SaveChanges:=False
Run Code Online (Sandbox Code Playgroud)
这是有效的,但我意识到,可能存在所选文件有多个的情况Sheets.
有没有办法写宏,如果我选择的文件有1张它运行上面的代码,如果它有多张表让我选择我想要的表,然后运行其余的代码?
这只是偶尔使用的基本暂停例程的扩展.
这是我的"常规" Pause例程(使用该Timer函数):
Sub Pause(seconds As Single)
Dim startTime As Single
startTime = Timer 'get current timer count
Do
DoEvents 'let Windows "catch up"
Loop Until Timer > startTime + seconds 'repeat until time's up
End Sub
Run Code Online (Sandbox Code Playgroud)
......所以,它给了我一个主意.
老实说,我有点惊讶地发现这是有效的,因为它基本上同时运行两段代码.
WaitForUserActivity:这是我在上面的演示中使用的代码:
Option Explicit
Public isPaused As Boolean
Sub WaitForUserActivity() 'THE 'RUN DEMO' BUTTON runs this sub.
Dim origSheet As String
isPaused = True 'flag "pause mode" as "on"
origSheet = ActiveSheet.Name 'remember current worksheet name
MsgBox "This will 'pause' code execution until you" & vbLf & _
"click the 'Continue' button, or select a different a worksheet."
Application.StatusBar = "PAUSED: Click ""Continue"", or select a worksheet."
Do 'wait for button click or ws change
DoEvents 'yield execution so that the OS can process other events
Loop Until (Not isPaused) Or (ActiveSheet.Name <> origSheet)
If isPaused Then 'the active worksheet was changed
MsgBox "Worksheet '" & ActiveSheet.Name & "' was selected." _
& vbLf & vbLf & "Now the program can continue..."
Else 'the button was clicked
MsgBox "The 'Continue' button was clicked." _
& vbLf & vbLf & "Now the program can continue..."
End If
Application.StatusBar = "Ready"
End Sub
Sub btnContinue() 'THE 'CONTINUE' BUTTON runs this sub.
isPaused = False 'flag "pause mode" as "off"
End Sub
Run Code Online (Sandbox Code Playgroud)
要运行演示:
WaitForUserActivity btnContinue 代码中的关键命令是DoEventsFunction,它"执行执行以便操作系统可以处理其他事件".
DoEvents将控制权传递给操作系统.在操作系统处理完队列中的事件并且已发送SendKeys队列中的所有密钥后,将返回控制权.
DoEvents对于简单的事情(如允许用户在启动后取消进程,例如搜索文件)最有用.对于长时间运行的进程,通过使用Timer或将任务委派给ActiveXEXE组件可以更好地完成处理器的生成- 操作系统负责多任务处理和时间分片.只要您在事件过程中临时生成处理器,请确保在第一次调用返回之前不再从代码的其他部分执行该过程 ; 这可能会导致不可预测的结果.
进一步的细节(和警告)的源.
一些建议的解决方
您可以提示用户指定哪个工作表,而不是"停止"代码.
您可以"暂停"执行以给用户一定的时间来选择工作表,使用简单的计时器循环,您甚至可以检查工作表名称以查看用户是否选择了新的工作表,如下所示:
Dim startTime As Single, shtName As String
If ThisWorkbook.Worksheets.Count = 1 Then
MsgBox "There is only one worksheet in this workbook."
Else
shtName = ActiveSheet.Name 'get name of active sheet
MsgBox "You have 5 seconds to select a worksheet after clicking OK.", _
vbOKOnly + vbInformation, "Select a worksheet... fast!"
startTime = Timer
Do
DoEvents
Loop Until Timer > startTime + 5
'check if user picked a new worksheet
If ActiveSheet.Name = shtName Then
MsgBox "You didn't select a new worksheet!"
Else
MsgBox "Thanks for selecting a new worksheet!"
End If
End If
Run Code Online (Sandbox Code Playgroud)
它有点可笑,但可以工作,特别是如果进行适当的检查,以确保你现在有正确的工作表.
我想您可以创建一个工作表事件过程,该过程将在激活工作表时运行,并检查全局变量以查看您的"导入过程" 是否正在运行,如果是,则恢复您的代码...但这将是混乱的令人困惑,并要求代码存在于您"导入"的工作簿中.
或者,比其中任何一个更好的是根据工作表的内容以编程方式/ 逻辑方式确定您需要哪个工作表.有标题吗?某个约会?也许是最新的工作表?某个细胞中有什么东西?必须有一些东西可以区别于其他东西.
希望这能为您提供一些非线性解决方案的想法.