Basic debugging and error tracing
Introduction
When you are building your app, putting in some code and see the “red squiggly lines” appearing under it, you immediately start thinking “what have I done wrong”. There are many forum posts with these types of questions that can be easily solved with a bit of investigation and knowledge of where to look for the issue.
Contents
- Intellisense
- Format Text
- Labels with values
- Looking directly at the data
- Using Variables and Collections
- Look at the error message
- Hover over your code
- Pull your code apart and reconstruct it
- And/Or confusion
IntelliSense
Firstly, IntelliSense is your best friend. It is a bit like a predictive Google or Bing search and displays valid values for the “next step” in your code directly underneath where you are typing. In the simple example below, the combo box displays one field out of a list and the label to the right of it needs to display the selected item, so when the combo name (cbDevices) is typed with .Selected. after it, the one valid value appears for selection.
In a little more complex example, the same combo box is based on the entire list and is displaying the Device Name in it. In this case, you can actually refer to any field in the list belonging to the record selected, but you want the Device Name, so have typed in cbDevices.Selected.dev and can now see the valid choices in the list.
This function works with all code, but be aware that it does not know what you are thinking forward and can provide valid values that are not what you are intending to do.
Format Text
Another highly useful function that serves two purposes that both: –
- Formats your text into proper indents and lines and makes it much more manageable and readable.
- Will only activate (the button is disabled by default) when your code is valid, so it is a really good check (without leaving the code panel) that you have done it correctly.
The examples below show unformatted and formatted code
Labels with values
This is one of the more useful, but simple tools you can use to “track” what is happening immediately as you execute the code. For a Variable called varWidget, if you put this in a Label on the screen with
"varWidget: " & varWidget
You can see the value of this change in the various functions you are using.
Another common one used would be on a Collection colWidget or a Gallery galWidget to see how many records currently exist.
"colWidget contains " & CountRows(colWidget) & " records"
"galWidget contains " CountRows(galWidget.AllItems) & " records"
You can take this a lot further to for instance include a filter that you may be using on a list
"My filter has " & CountRows(Filter(Widgets,WidgetName="Fred")) & " records"
The possibilities are endless and it probably the first tool you should use when you are not receiving the required outcome from your code.
Looking directly at the data
Two main functions exist here – View > Collections and View > Variables. The Collections will only show the first five records, but is highly valuable to see the actual data fields and their structures.
The Variables (you need to look under the screen name for Context Variables or under Global for Set() Variables) function also shows: –
- The current value of the Variable.
- Every place it is set under Definitions.
- Every place it is used under Uses.
Using Variables and Collections
Another use of these is to set a test variable to the value you are trying to use in a Filter or a LookUp. A Variable can contain a Value or a Record (so is good for a LookUp).
Set(
varMyVar,
Lookup(
Widgets,
WidgetName="Fred"
)
)
After setting, look at the value as above (View > Variables) and the case of a Record, you will see the data structure and data type of all the fields in the record. This is extremely useful when you are trying to Patch a list and have field type mismatches.
Along the same line, simply Collect the list
ClearCollect(colMyCol,Widgets)
You will only be able to see the first five records, however what you are really after is the data structure, so you can see the type of field
In the example below, the third field ChoiceTest is a Choice field, so you can “look inside” and see that it contains one field Value.
so the reference to this field would be
colTest.ChoiceTest.Value
Look at the error message
Hover your mouse over the error icon (“red x circle” for errors or “orange triangle” for delegation warnings) and see what the error or warning is about.
Hover over your code
The source of the error will be shown – in the case below, there is a comma missing after the With() statement.
Pull your code apart and reconstruct it
Code works from the “inside out”. If you use Format Text, the first bits executed or the “base” of the code will be the pieces indented the furthest to the right. The other functions (LookUp/Filter/Sort etc) “wrap around” this and execute in order of right-left indents. Start with valid “right-side” code and keep adding (particularly filters) one at a time until it stops working, then you will know what is the issue. Be sure to use “Format Text” each time you have valid code.
The main exception to the “right-left” rule is a With() statement which is generally at the head of the code and executes first as it is used in the remainder below, however for the most part, the “rules” above can be followed. In practical terms for debugging:
- If you have a Sort/SortByColumns on the “outside”, get rid of it for now.
- If you have multiple LookUp or Filter criteria, get rid of them all then add one back in.
- Use Format Text each time you have valid code.
- Once valid, add the next item and so on until you find the one you need to fix.
- Watch your opening and closing brackets – each “set” should close on the same indent that the command belonging to it opened.
- When this is valid, put your Sort back.
To avoid happening, construct your code this way from the start.
And/Or confusion
Always bracket any changes in and/or logic into groups reflecting their separate logic. For instance – using && for And() , || for Or() below: –
A=B && C=D || E=F && G=H
could mean
(A=B && C=D) || (E=F && G=H)
or also could be
A=B && (C=D || E=F) && G=H
which are two completely different results
Conclusion
This summary only covers the basics of code investigations, but I hope that it will allow you to understand your efforts more clearly.
One Comment
Isaac Pisors
Warren’s articles are so easy to understand and read – the hardest thing about this experience was the Captcha to enter this comment! LOL. Thanks Mr. Belz.