emihir0
emihir0

Reputation: 1260

VB, excel macro pause and resume working if possible

I cannot figure out the best way to do the following problem. Basically my macro (excel, VB) is checking several (100+) worksheets for correct values, if wrong value is found, I want it to stop, give me a warning, then I could have a look into the reason why the value is wrong, correct it manually and then I want to resume the macro, or remember the last value checked so if I return, it remembers where to continue (resume).

My current problem is that it finds the wrong value, then I can either make it stop so I check the problem, or it goes through all the sheets and then I have to remember which sheets had the wrong value.

What I thought of is make a list where the name of sheet is added every time a wrong value is found. The problem is that usually there is more than 1 wrong value in the same sheet if there is a wrong value at all and this added the same sheet name several times to the list. Another problem with that is that I cannot correct the values straight away.

I'm very inexperienced with programming and so would appreciate your idea on how to best approach this problem (I don't want to spend a long time on coding something which wouldn't be efficient for such a "simple" problem).

Upvotes: 1

Views: 1682

Answers (5)

genespos
genespos

Reputation: 3311

What about inserting a button (on the sheet or in a menubar) for stopping?

Insert the code below:

'This at the top of the module
Public mStop As Boolean

'This in the module
Sub MyBreak()
mStop = True
End Sub

'This is your macro
Sub YourMacro()
'This at the top of your code
mStop = False
'Your code
'...
    'This code where you want to break
    DoEvents '<<<< This makes possible the stop
    If mStop Then
        mCont = MsgBox("Do you want to continue?", vbYesNo)
        If mCont = vbNo Then
            Exit Sub
        Else
            mStop = False
        End If
    End If
'Your code
'...
End Sub

Now you need to create a button and link it to the macro called "MyBreak".

Upvotes: 0

jbay
jbay

Reputation: 126

The best way to do this is to create a userform and as mentioned by prior users create a public variable. When the program finds an error store the cell and initiate the userform. Your code will stop on the userform. When you're done checking the problem have a button on the userform that you can click to continue checking. Your loop can be something like the below.

public y as integer

sub temp1 ()       
  rw1= range("a500000").end(xlup).row  'any method to create a range will do
  if y = null then y=1

  for x = y to rw1
      cells(x,1).select 
      'check for the problem your looking for
      if errorX=true then
         userform1.show
         y = activecell.row
         exit sub
      end if
  next x
end sub

Upvotes: 0

David Zemens
David Zemens

Reputation: 53663

When the error is found (I'm assuming you've already been able to identify this), you can use the Application.InputBox function to prompt you for a new value.

For example, if rng is a Range variable that represents the cell being checked, and you have some logic to determine where the error happens, then you can just do:

rng.Value = Application.InputBox("Please update the value in " & rng.Address, "Error!", rng.Value)

The inputbox function effectively halts execution of the procedure, while waiting for input from the user.

If InputBox isn't robust enough, then you can create a custom UserForm to do the same sort of thing. But for modifying single range values, one at a time, the InputBox is probably the easiest to implement.

Upvotes: 4

SierraOscar
SierraOscar

Reputation: 17647

Create a public variable that stores the cell address of the last checked cell and use a conditional statement to see if it's "mid-macro" for want of a better phrase. here is a very crude example...

Public lastCellChecked As String

Sub Check_Someting()

Dim cell As     Excel.Range
Dim WS As       Excel.Worksheet

If Not lastCellChecked = vbNullString Then Set cell = Evaluate(lastCellChecked)

'// Rest of code...

'// Some loop here I'm assuming...
lastCellChecked = "'" & WS.Name & "'!" & cell.Address
If cell.Value > 10 Then Exit Sub '// Lets assume this is classed as an error
'// Rest of loop here...

lastCellChecked = vbNullString
End Sub

Upvotes: 0

Mike
Mike

Reputation: 1324

I believe you can handle this task by using one or two static local variables in your macro. A variable declared with "static" rather than "dim" will remember its value from the last time that procedure was run. This can hold where you left off so you can resume from there.

One thing that could be a problem with this solution would be if the macro gets recompiled. That would probably cause VBA to clear the value that the static variable was holding. Just doing a data edit in Excel should not cause a recompile, but you will want to watch for this case, just to make sure it doesn't come up. It almost certainly will if you edit any code between executions.

Upvotes: 0

Related Questions