Any idea why inserting break points and stop no longer stops my vba code from running?
The code runs ok all the way to the end (I tested it) but ignores break points and Stop.
Also step into just makes the code run in it's entirety, ignoring break points and stops.
When I close the workbook where the issue seems to originate from the same issue occurs in other macro workbooks.
if I completely close excel and re-open it with a normally working macro workbook the issue doesn't occur until I re-open the problem work book.
I added breakpoints on:
TotP1 = 0
of the following code:
Option Explicit
Private Country As String
Private Measure As String
Private P1 As String
Private P2 As String
Private TotP1 As Double
Private TotP2 As Double
Sub VennDisplayIt()
Dim SI() As String
Dim SICount As Integer
Dim x As Integer
Dim OSh As Worksheet
Dim BrandListBox As Object
Dim VennGroup As Shape
TotP1 = 0
TotP2 = 0
Set OSh = ThisWorkbook.Sheets("Venn")
Set BrandListBox = OSh.OLEObjects("BrandListBox").Object
ReDim SI(2, 0)
For x = 0 To BrandListBox.ListCount - 1
If BrandListBox.Selected(x) = True Then
'If UBound(SI) < 4 Then
ReDim Preserve SI(2, UBound(SI, 2) + 1)
SI(1, UBound(SI, 2)) = BrandListBox.List(x)
SI(2, UBound(SI, 2)) = x + 1
'End If
End If
Next x
If UBound(SI, 2) < 2 Then
BrandListBox.Selected(BrandListBox.ListIndex) = True
Exit Sub
ElseIf UBound(SI, 2) > 4 Then
BrandListBox.Selected(BrandListBox.ListIndex) = False
Exit Sub
End If
For x = 1 To UBound(SI, 2)
OSh.Range("o8").Offset(x, 0).Value = SI(1, x)
OSh.Range("o8").Offset(x + 5, 0).Value = SI(1, x)
Next x
For x = UBound(SI, 2) + 1 To 4
OSh.Range("o8").Offset(x, 0).Value = ""
OSh.Range("o8").Offset(x + 5, 0).Value = ""
Next x
SICount = UBound(SI, 2)
For x = 1 To OSh.Shapes.Count
If Right(OSh.Shapes(x).Name, 5) = "Group" Then
If LCase(OSh.Shapes(x).Name) = SICount & "waygroup" Then
Set VennGroup = OSh.Shapes(x)
OSh.Shapes(x).Visible = True
Else
OSh.Shapes(x).Visible = False
End If
End If
Next x
For x = 1 To SICount
VennGroup.GroupItems.Item(SICount & "WayBrand" & x).DrawingObject.Text = SI(1, x)
Next x
Country = ThisWorkbook.Sheets("Venn").Range("D4").Value
Measure = ThisWorkbook.Sheets("Venn").Range("E32").Value
P2 = ThisWorkbook.Sheets("Venn").Range("E31").Value
P1 = ThisWorkbook.Sheets("Selections").Range("B5").Value
End Sub
I've never heard of Stop not working, but I've heard about and experienced the breakpoint thing many times. When you compile VBA, it creates a p-code, which is used by the interpreter. You have the VBA syntax layer that you can see and the p-code layer that you can't see. When breakpoints stop working, it's because the p-code was corrupted. I don't know how or why it happened, but it did.
The fix is to export, remove, and reimport all of your modules. Exporting them creates a .bas file (plain text, really). When you re-import, the p-code is regenerated from scratch. If you have more than a couple of modules, get CodeCleaner (free add-in) and it will export and reimport automatically.
If one of the settings is unchecked then breakpoints will not work. "File/options/Current database/Application options/use access special keys" should be checked
Just to 'second' Tibo's comment: I had a problem where I had a form with about 5 different subroutines. One of them (attached to a button event) would not stop when I set a breakpoint. in 10 years of VBA writing, I've never seen that happen. Interestingly, breakpoints worked on all of the other subroutines in that form. After much head-scratching and searching, I came upon this post and Tibo's comment. I added a "Stop" command to the affected subroutine, ran the procedure (it stopped as it should have) and then breakpoints began working again! Hope this helps someone in the future.
If the breakpoints are in your code, then the code should stop running as soon as it hits that line. Possible causes of your problem:
a) The code never gets to the Breakpoint.
Seems highly unlikely seeing as you're breaking on the first line of your code. Maybe step through the sub (F8) just to check it's running as it should.
b) Your breakpoints have been wiped. Any line with a breakpoint should display as highlighted in red on your IDE. Your breakpoints can easily be wiped through, e.g. closing and opening the workbook (a screenshot would be really useful).
c) your workbook is broken in some way. It would be unlikely to break something as fundamental as stopping at breakpoints and still function normally. Are you sure your code is actually running?
Just sharing a funny thing which happened to me in case it helps someone. The mistake I did was that I simply took someone's method code meant for workbook open event and pasted it on Sheet1 excel object code area. So there was no possibility of Workbook_Open method getting fired ever.
Private Sub Workbook_Open()
Stop
On Error Resume Next
Call ActiveSheet.Worksheet_Activate
On Error GoTo 0
End Sub
What I was supposed to do is paste this method after double clicking ThisWorkbook node under Microsoft Excel Objects in Project pane as shown below:
Note: Side effect of copy-pasting others code can be freaky at times.
a) Double check that your breakpoints got disabled or not.
b) Double check that you added a conditional breakpoint or not
c) If you run your macro using C# code (using, the _Run2 command), breakpoints and stop doesn't work sometimes.
I have the problems as described above:
Stop and Breakpoints not working
Single step F8 worked, but code was not highlighted in yellow
Closing VBA editor did not help
My remedy: close VBA editor again, save Excel-file, open editor, back to normal
I've never faced this problem for years. Today for the first time I started using watch expressions with stopping when true.
This happens to me once in a while and the following solves the problem for me every time:
Create a Sub with only the command Stop in it. Run it. Then try your routine, the breakpoints and Stop commands should now work correctly.
Make sure that you do not have a named Range that matches the name of the Function or Subroutine you are calling. This will look like the Function or Subroutine is failing, but it is actually failing before the routine is ever called with an 'invalid cell reference'.
I had this problem as well. My solution was put an error in the code and run it. After I cleared the error the breakpoints started working again. That was weird.
I been writing code in VBA for many years but today I came across this problem for the first time. None of the solutions I found on the web worked but here's something simply you can use instead of Stop:
ErrCatch = 1 / 0
Still doesn't solve the breakpoints not working though...
I went int my vba code, added an enter (new blank line), then ran it again.
Voila! It ran the code and stopped at the breakpoint!
Not just me then! On a few occasions the yellow hi-lite stops a few lines beyond the breakpoint! I guess the code is running so fast it can't stop in time. :) As suggested above, I find adding "stops" here and there and also exporting & re-importing helps too.
Related
I couldn't find this asked anywhere. In Visual Basic (excel), I can hit F8 and cycle through each line. But lets say I want to begin the sub procedure, and then after executing the first 2 lines, I'd like to skip to line 200. Until now, I've always just dragged the yellow arrow to the desired line. This is really time consuming and I was wondering if there's any command to simply say "run current line where selected" or something.
Additionally, even if I could begin to run through line by line, and quickly move the yellow selected arrow to the desired line, that would also work.
If you have a 200-liner procedure that does so many things you'd like to skip most of it, it looks like you need to refactor a bit.
Extract "things the procedure is doing" into their own Sub procedures and Function scopes. If you have banner-like comments that say things like '*** do something *** then that's a chunk to extract into its own procedure already.
Stepping through that procedure could then involve stepping over (Shift+F8) the smaller procedures that do one thing, or break and skip the call altogether.
Right click on the line you want to jump to. Hit the Set Next Statement option in the menu. That's equivalent to dragging the arrow to that line. (Ctrl-F9 is the hotkey for this action.)
If you want it to quickly execute every line up to a certain line, set a breakpoint then hit run instead of stepping through the code line by line. Do this by clicking on the gray bar to the left side where the yellow arrow appears. A dark red dot should appear and the line should be highlighted in dark red. This tells visual basic to stop when it hits that line.
You can also comment lines out by starting them with an apostrophy.
Finally, you can break code into subroutines and execute them independently of eachother.
Sub Subroutine1()
'This is a commented out line. It does nothing.
MsgBox "Do stuff here"
End Sub
Sub Subroutine2()
Subroutine1 'This will run all the code in subroutine 1
MsgBox "Do more stuff here"
End Sub
In the above example, if you run Subroutine1 you'll get one message box popping up. If you run Subroutine2 you'll get two message boxes.
Unfortunately it is not possible to do what you ask directly.
However, you may comment out the lines of code above the code you want to be executed for example:
Sub Workbook_Open()
'Application.DisplayFullScreen = True
'Application.DisplayFormulaBar = False
'ActiveWindow.DisplayWorkbookTabs = False
''ActiveWindow.DisplayHeadings = False
Application.EnableEvents = True
Password = "1234"
ActiveWorkbook.Protect
ThisWorkbook.Protect (Password = "1234")
End Sub
You may use GoTos, but however this is not considered good practice and may actively harm your code:
Sub Workbook_Open()
GoTo ExecuteCode
Application.DisplayFullScreen = True
Application.DisplayFormulaBar = False
ActiveWindow.DisplayWorkbookTabs = False
ActiveWindow.DisplayHeadings = False
Application.EnableEvents = True
ExecuteCode:
Password = "1234"
ActiveWorkbook.Protect
ThisWorkbook.Protect (Password = "1234")
End Sub
This is how I do it - basically if I know that my code up to line 200 is working properly but I'm pretty sure there's an error between 200-300 then before compiling - scroll down to line 200 and mark it (to the left of the code). Then compile it - click F5 and it will execute everything up to line 200 - then you can step through each line thereafter individually.
I normally comment out lines of code that I don't want to run with apostrophes. Alternatively, you can break up your code into smaller procedures so that you can easily pick and choose what you want to test/run.
I found adding a module for testing and copy pasting snippets of code in it as a best way for troubleshooting.
I am writing and re-writing Excel VBA code to make some engineering analysis easier for myself and the others at my company. So the goal is to make it easy for others, not to be integrated into other code or purposes outside our own Excel work.
The problem: a few of the macros will add a custom function to a worksheet cell, bring up the function dialog for inputs, but then when completed, come up with a Value error, stating A value used in the formula is of the wrong data type. Based on this, I believe the issue arises when my function uses a Variant or Range type variable. Some of these functions only give this error via certain input types.
HOWEVER, in every single case, using the function dialog Not in the macro works fine, as does typing the formula in manually. Additionally, all you have to do is double-click on the error cell to edit it, change nothing, press enter, and it's fine!
My macros themselves are as simple as:
Sub NewSTC_dialog()
ActiveCell.FormulaR1C1 = "=sheetname.xlsm!NewSTC()"
Application.Dialogs(xlDialogFunctionWizard).Show
End Sub
My functions have more to them, but the situation is different for different functions, and the functions themselves work fine, so it is preferable to have a solution that applies to the macros rather than within the functions. If I must, I can go through each situation individually or come up with a simplified function that has the same issue to give as an example.
My best workaround so far (I cannot re-find the website were I found this particular solution):
Sub Recalculate()
ActiveCell.Replace What:="=", Replacement:="="
End Sub
Set to a convenient shortcut, and it works great. However, as mentioned above, the goal is to make this easy for everyone else, which would mean not requiring anything additional to have the formula work. Unfortunately, calling this from within the initial macro will not work. In fact, nothing located after the dialog call will run. I tried using On Error Resume Next and it still won't run anything after the dialog call.
Some options searched and tried:
How to refresh cells in Excel 2010 using VBA? and links within that - as mentioned, nothing located after the dialog call will run, thus won't reach these adjustments. Putting before the dialog call also doesn't help. Putting the dialog call in between the false and true statements makes the false apply, then never runs the true statement.
http://www.excelforum.com/excel-general/471632-formula-do-not-work-until-edited.html - Excel is not set to manual
http://blog.contextures.com/archives/2012/02/16/excel-formulas-not-calculating/ - SUMIF is not involved
This is all on Excel 2010, Windows 7 Professional.
EDIT:
Here is an example that creates this behavior. This is similar to the behavior of two of my functions, but not to all of them, so again, I would much prefer the solution be in the macro, not the function. This is just for anybody else's testing purposes.
Function LetNum(input1 As Variant, input2 As Variant) As Integer
If input1 = "A" Or input1 = "a" Then
input1 = 100
ElseIf input1 = 10 Then
input1 = -10
End If
If input2 = "B" Or input2 = "b" Then
input2 = 200
ElseIf input2 = 10 Then
input2 = -1000
End If
LetNum = input1 + input2
End Function
Sub LetNum_dialog()
ActiveCell.FormulaR1C1 = "=LetNum()"
Application.Dialogs(xlDialogFunctionWizard).Show
End Sub
In this situation, typing A and 2 into the dialog box in that order works, but 2 into the second then A into the first doesn't. Additionally, typing B in the second box never works. In all situations, clicking to edit, changing nothing, and hitting enter, fixes it. Additionally, any situation in the dialog box if you bring it up without the macro works fine.
Also, I'm aware this case works better if you input it with quotes, but excel automatically changes it correctly, and not all my functions are string issues.
EDIT 2:
Tim's answer is a great step in the right direction! However, if anybody can come up with a solution that doesn't involve ignoring all errors, that would be more ideal due to some desired error-throwing being ignored. I will look into handling errors differently in the meantime.
The issue seems to be that any error triggered in your UDF effectively "disables" the Function Wizard: note that in cases where you get #VALUE! error, the Show() method never returns any value, and any lines following the call to Show() are not executed.
The only thing which resolved this in my testing was to add a line to the function which skips any errors when the Function Wizard is open:
Dim bSettingUp As Boolean
Function LetNum(input1 As Variant, input2 As Variant) As Integer
If bSettingUp Then On Error Resume Next
If input1 = "A" Or input1 = "a" Then
input1 = 100
ElseIf input1 = 10 Then
input1 = -10
End If
If input2 = "B" Or input2 = "b" Then
input2 = 200
ElseIf input2 = 10 Then
input2 = -1000
End If
LetNum = input1 + input2
End Function
Sub LetNum_dialog()
ActiveCell.Formula = "=LetNum()"
bSettingUp = True
Debug.Print Application.Dialogs(xlDialogFunctionWizard).Show()
bSettingUp = False
End Sub
I'm aware that you'd rather not alter your functions ,but this was the only work-around I could find.
I'm trying to code to be able to do simple math inside a text box (user types in 5/8, .625 comes out). If I hit an error, the debugger comes up telling me the error, and if I hit the End Button, another Excel window pops up saying "Microsoft Excel Has Stopped Working" and excel closes then reopens. This also happens when I put breakpoints in the code and stop the program at the break points, excel just crashes, no warning or explanation.
Here is the few lines of code I was debugging, maybe that will help tell you why, but I have several different modules for this project and I've never had this issue before and I have been able to debug without a problem.
Sub TextboxMath(textbox As MSForms.textbox)
Dim value As String
value = textbox
For i = 1 To Len(value)
If Mid(value, i, 1) = "+" Then
ElseIf Mid(value, i, 1) = "-" Then
ElseIf Mid(value, i, 1) = "*" Then
ElseIf Mid(value, i, 1) = "/" Then
End If
Next i
End Sub
And Also the Code that runs the subprocedure
Private Sub tbANTShankDiameter_AfterUpdate()
If obSDIN.value = True Then
Call TextboxMath(tbANTShankDiameter)
End If
End Sub
This only ever happens when I'm stopping or resetting the debugger and program after an error. I'd appreciate any suggestions, let me know if I need to provide any more information that could help you give me a better suggestion. Thanks a lot for reading and helping!
Edit:
I tried transferring all the userforms, code, and data to a new workbook, but I still had no luck, and it crashed. I did notice, however, that it only crashes on the AfterUpdate events I have in the code, not in anything else. It crashes when you stop or reset the debugger on an error, or when I stop the code at breakpoints to test. This is the first time I've ever used those events, and I don't have them anywhere else in my workbook, which is why I never had this problem before. Any new ideas anyone? Thanks again!!
Evan
at the moment I have a small application and need to take information from an object and display it into an excel file, using the Microsoft.office.interop class I've been able to write to the file, and it shows one by one the records being added, however about once every 3 times I try it, the spreadsheet stops filling somewhere between the 300th and 600th record, I have 6,000 in total and it's not breaking every time, I put a check after it finishes to see whether the last record is filled in but the code never reaches that point and I'm unsure of what's happening
I also don't know how to debug the problem as it'd mean going through 6,000 loops to check for it stopping... which might not even happen?
a little section of the code is here
loadExcel(incidents, WorkSheetName)
If WorkSheetName.Cells(DBObject.HighestInci + 1, 6) Is Nothing Then
MessageBox.Show("Failed to fill spreadsheet, Retrying now.")
loadExcel(incidents, WorkSheetName)
End If
above is the code calling and checking the method below
Private Sub loadExcel(ByVal incidents As List(Of Incident), ByRef WorkSheetName As Excel.Worksheet)
Dim i = 2
For Each inc As Incident In incidents
WorkSheetName.Cells(i, 1) = inc.DateLogged
WorkSheetName.Cells(i, 2) = inc.DateClosed
WorkSheetName.Cells(i, 3) = Convert.ToString(inc.DateLogged).Substring(3, 2)
i += 1
Next
End Sub
Thanks in advance
EDIT
I'm thinking loading it to a buffer of some sort then writing once they have all been updated would be the way to go instead of it currently loading and writing each separately? however I have no idea where to start for that?
I've fixed my problem, with what I had above Excel was opened and it started printing into the spreadsheet line by line, the problem is that any interactions with excel would cause the process to freeze
By adding an
ExcelApp.visible = false
before carrying out the process and an
ExcelApp.visible = true
afterwards, it all works and then opens the file afterwards
I want to make a special list of figures with use of VBA and here I am using the function
myFigures = ActiveDocument.GetCrossReferenceItems(Referencetype:="Figure")
In my word document there are 20 figures, but myFigures only contains the first 10 figures (see my code below.).
I search the internet and found that others had the same problem, but I have not found any solutions.
My word is 2003 version
Please help me ....
Sub List()
Dim i As Long
Dim LowerValFig, UpperValFig As Integer
Dim myTables, myFigures as Variant
If ActiveDocument.Bookmarks.Count >= 1 Then
myFigures = ActiveDocument.GetCrossReferenceItems(Referencetype:="Figure")
' Test size...
LowerValFig = LBound(myFigures) 'Get the lower boundry number.
UpperValFig = UBound(myFigures) 'Get the upper boundry number
' Do something ....
For i = LBound(myFigures) To UBound(myFigures) ‘ should be 1…20, but is onlu 1…10
'Do something ....
Next i
End If
MsgBox ("Done ....")
End Sub*
Definitely something flaky with that. If I run the following code on a document that contains 32 Figure captions, the message boxes both display 32. However, if I uncomment the For Next loop, they only display 12 and the iteration ceases after the 12th item.
Dim i As Long
Dim myFigures As Variant
myFigures = ActiveDocument.GetCrossReferenceItems("Figure")
MsgBox myFigures(UBound(myFigures))
MsgBox UBound(myFigures)
'For i = 1 To UBound(myFigures)
' MsgBox myFigures(i)
'Next i
I had the same problem with my custom cross-refference dialog and solved it by invoking the dialog after each command ActiveDocument.GetCrossReferenceItems(YourCaptionName).
So you type:
varRefItemsFigure1 = ActiveDocument.GetCrossReferenceItems(g_strCaptionLabelFigure1)
For k = 1 To UBound(varRefItemsFigure1)
frmBwtRefDialog.ListBoxFigures.AddItem varRefItemsFigure1(k)
Next
and then:
frmBwtRefDialog.Show vbModeless
Thus the dialog invoked several times instead of one, but it works fast and don't do any trouble. I used this for one year and didn't see any errors.
Enjoy!
Frankly I feel bad about calling this an "answer", but here's what I did in the same situation. It would appear that entering the debugger and stepping through the GetCrossReferenceItems always returns the correct value. Inspired by this I tried various ways of giving control back to Word (DoEvents; running next segment using Application.OnTime) but to no avail. Eventually the only thing I found that worked was to invoke the debugger between assignments, so I have:
availRefs =
ActiveDocument.GetCrossReferenceItems(wdRefTypeNumberedItem):Stop
availTables =
ActiveDocument.GetCrossReferenceItems(wdCaptionTable):Stop
availFigures = ActiveDocument.GetCrossReferenceItems(wdCaptionFigure)
It's not pretty but, as I'm the only person who'll be running this, it kind of works for my purposes.