Multiexcerpt include macro | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
...
Lookup Table Tips & Tricks
Example: In-Form Lookup Table Querying
...
Excel Tricks for Lookup Tables
Below is a list of tips and tricks for managing your Lookup Tables in Excel.
Expand | ||||
---|---|---|---|---|
|
Code Block |
---|
Form Builder clip version 1
id type labelItext:en-default appearance calculateAttr instances relevantAttr
/fruit_counter Group Fruit Counter null null null null
/fruit_counter/what_kinds_of_fruit_do_you_want_to_count Select What kinds of fruit do you want to count? null null null null
/fruit_counter/what_kinds_of_fruit_do_you_want_to_count/citrus Choice Citrus null null null null
/fruit_counter/what_kinds_of_fruit_do_you_want_to_count/berry Choice Berry null null null null
/fruit_counter/there_are Trigger "There are <output value=""#form/fruit_counter/count"" /> matching fruits in the lookup table" minimal null null not(#form/fruit_counter/what_kinds_of_fruit_do_you_want_to_count = '')
/fruit_counter/count DataBindOnly null null count(instance('item-list:fruit')/fruit_list/fruit[type = #form/fruit_counter/what_kinds_of_fruit_do_you_want_to_count]) {} null |
Afterwards, you should see these questions added into your form:
Test It Out
You will need to be logged in as a mobile user to test the form, either on a mobile phone or by using the Login As feature in live preview to choose a mobile user.
Once you've loaded the form, you should be able to choose a filter, and see an up-to-date count of how many items from the lookup table match the filter.
Understand
The lookup table querying is done inside of the #form/count Hidden Value calculation:
count(instance('item-list:fruit')/fruit_list/fruit[type = #form/fruit_counter/what_kinds_of_fruit_do_you_want_to_count])
This shows how the lookup table can be queried with xpath syntax by starting expressions with the following root, with filters applied for additional logic
instance('item-list:fruit')/fruit_list/fruit
For example, to print a list of the names of all citrus fruits instead, you could use the expression
join(" ", instance('item-list:fruit')/fruit_list/fruit[type = 'citrus']/name)
Experiment
Once you've loaded the form, you can use the Data Preview XPath Evaluator to experiment with different expressions, and see the data live.
This tool is especially helpful for experimenting with lookup table queries because it can display for you the intermediate outputs of the filters, which can be a big help when debugging more complex expressions.
NOTE - In order for you to be able to reference a lookup table from this tool, your form needs to already contain at least one reference to the lookup table in another expression (calculation, display condition, selection choices, etc) for the form to be connected to the table. You can see the lookup tables connected to your current form by typing "instance" into the tool and seeing what autocompletes.
Advanced: Indexing Lookup Tables (Larger Lookup Tables)
Indexes are designed to solve a specific problem: references to a large lookup table are slowing down your application.
Expand | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||
For example, suppose you are using a lookup table to set up a question with filtered choices. Your lookup table, health_centers_by_region, has the following fields:
and you have a hidden value that contains the calculation:
If this table is large enough that this filter is slowing down performance in your form, you may be able to alleviate this by adding an index to district_id and moving the indexed field to the front of your filter, so that:
becomes:
Definitions
What is an Index?An index is a data structure that helps make certain XPath expressions that reference a lookup table more efficient. When you index a field in a lookup table, you can improve the speed of expressions on that particular field. The following scenarios highlight the difference between querying a field that is indexed, compared to querying an unindexed field:
When Should I Create an Index on my Lookup Table?Most lookup tables will not need to be indexed. If you think you might need to index one or more fields of a lookup table, ask yourself:
If you answered "yes" to all of the above questions, it might be worth adding an index for one or more fields in your lookup table. If you're not sure whether a particular query is slowing down your app, try the following exercise:
Indexing Tables Used in Multiple Choice Lookup Table Questions If you are populating a multiple choice or checkbox question from a lookup table, and are still experiencing performance issues after indexing any appropriate columns from the filter, try adding indexes for the Value Field and the Display Text Field. How Do I Add an Index?Suppose you have a lookup table health_centers_by_region with the following fields (this is the same table from the Overview above):
As part of your workflow, a mobile worker often needs to select a health center in a certain region that has MNCH services available. There are thousands of health centers spread over hundreds of districts, and you've noticed that a query that appears throughout the app is taking a long time:
Since district_id has hundreds of values represented, it has a high enough cardinality to warrant an index. mnch_services_available will only ever be set to "yes" or "no." Since the cardinality for this field is low, the benefits of indexing the field would be minimal compared to the extra space it would take up on the phone, so it should not be indexed. Before adding an index to the lookup table, please refamiliarize yourself with the process of creating and updating lookup tables, specifically downloading or uploading tables for editing. When you're ready to add an index, follow these steps:
Once the index has been added, you will need to rewrite your query so that the indexed field or fields appear at the beginning of the string of filters. Since region_id is indexed and mnch_services_available is not, our example becomes:
See the next section for details. Query OptimizationWhen writing XPath queries on an indexed lookup table (or on any indexed fixture, such as casedb), it is important to write your query such that all filters on indexed properties are evaluated BEFORE other filters. For example, say you have a lookup table health_centers_by_region with the following fields:
If we want a query to return all health centers in region 123 where MNCH services are available, we would write:
With this query, the XPath query evaluator will first use an efficient key lookup to filter on the indexed field (region_id), before performing single lookups on each of the results to check whether mnch_services_available = "yes" for each one. The following documents go into much further technical detail on XPath evaluation and optimization:
LimitationsComplex Queries Currently, only the most basic XPath queries will leverage lookup table indexing. For example: value = 1 will use the indexing, but value < 2 will not. In addition, composite queries using and or or will not leverage the indexes. Lookup Tables with Multiple Languages When indexing a lookup table with multiple languages, you can only index fields that do not have translations. Indexing columns with attributes is unsupported.Managing large lookup tables efficiently Sometimes when creating Lookup Tables, you can receive large source files with values in different fonts, all caps etc. This page describes a few tricks on how to make values easily all lower case, how to replace spaces by underscores etc. Below are a set of Excel formulas, with a description of what it does and how to use it. Note: this tutorial assumes that you are using Excel in English. The names of the formulae are different in French. How to turn all your text entries to first-letter capital for each word (ex: First_name Last_name) =properUse: Converts words written in any format to words where the first letter is upper case and the rest is lower case. Example: CAPE TOWN > Cape Town How: Add a column next to the column where all the values are, then in the first cell of the new column add =proper(cell number) and click enter (for 'cell number' click on the cell with the all caps value). Drag the corner right little box from the cell down so that all values from the all caps column will be converted. When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (i.e., the text in the desired format). Note: For words that are already properly formatted (ex: Johannesburg in the example above), no change is applied. Note as well that "cape town" turns to Cape Town. How to quickly format all your text entries to all caps: =upper Use: Converts words written in any format to all caps. Example: Cape Town > CAPE TOWN How: Add a column next to the original words/text. Use the formula =UPPER(cell number) in the new column and click enter. Drag down the formula to replicate this for all your text. When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (i.e., the text in the desired format). How to quickly format all your text entries to lower case: =lower Use: Converts words written in any format to all lower case. Example: Cindy Jones > cindy jones How: Add a column next to the original words/text. Use the formula =LOWER(cell number) in the new column and click enter. Drag down the formula to replicate this for all your text. When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (i.e., the text in the desired format). How to quickly delete unwanted spaces: =trim Use: For when you receive a list of names/places where there is a space before the first word or after the final word. Example " cindy jones " (notice the space before 'cindy' and after 'jones'. The TRIM function will yield "cindy jones" How: Add a column next to the original words/text. Use the formula =TRIM(cell number) in the new column and click enter. Drag down the formula to replicate this for all your text. When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (ie, the text in the desired format). Note: TRIM only deletes spaces before or at the end a full string of text. It will not eliminate common/accurate spaces such as the space between a first and last name. Combining the above formulas: (ex: to eliminate unnecessary spaces AND to format upper/lower case) =UPPER(TRIM(cell number)) or =LOWER(TRIM(cell number)) or =PROPER(TRIM(cell number)) Use: Do the steps above more quickly! How: Add a column next to the original words/text. Use the formula =UPPER(TRIM(cell number)) in the new column and click enter. Drag down the formula to replicate this for all your text. *the bolded UPPER can be modified to reflect what you actually want. When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (ie, the text in the desired format). How to turn spaces into underscore (necessary for uploading your lookup tables into CommCare HQ) Use: It is recommended that before you upload your lookup table into CommCare HQ that you eliminate the spacing between the words. Example: marie france > marie_france How: (numbered steps correspond to the images below)
How to quickly append text/numbers to the end a text: =CONCATENATE Use: Imagine that you have a list of districts and another list of villages. Some of the districts have the exact same name as the villages (Ex: District: Bambara, which contains a village also called Bambara). CommCare will require you to distinguish which of the "Bambara" is a village and which is a district. For this example, we will append "_vil" to the end of each village name. How: Create a column next to the one containing the words you want to append. Use =CONCATENATE(cell number, "what you want to append"). In this case, we appended _vil. When clicking on the new value in the column "Appended Village", you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (ie, the text in the desired format). How to quickly eliminate duplicate entries from your Lookup list: Use: To link villages to districts, you need one row per village. But because multiple villages can belong to a single district, this means as a result that you will have several rows where your district is repeated. CommCare will require a separate list for districts and a separate one for villages. For that reason, you will want to eliminate all the duplicate districts from your Excel spreadsheet. How: (numbered steps correspond to the images below) 1.. Select the columns containing duplicate data. Click "Data" on the toolbar, then click "Remove Duplicates" 2.. Make sure that you select that your data has headers (if it does), and that you have selected the entire column. Click OK. 3.. You will see a message box with the number of duplicate values that have been removed and the number remaining. If you want to be able to see which duplicate values were removed
How to (very) quickly fill in a column with a value or a formula: If you want to quickly pull down a single value, you can double click (don’t drag) on the bottom right corner and the value will fill in bellow for all rows where there is information next to it. The RED X shows you were to double click. AND the same thing can be done with Functions! But don't forget to copy and paste value once you've created a column of functions. |
In-Form Lookup Table Querying
Lookup table data can be referenced in forms in ways other than as potential selection choices. This provides a quick example to show you how.
Expand | ||
---|---|---|
| ||
Add the sample table Download the attached Excel File and upload the file into your project space. Afterwards you should have the following lookup table available: Copy the example form Copy the following text with your web browser and paste it into the tree pane of a CommCare HQ form builder form:
Afterwards, you should see these questions added into your form: Test It Out You will need to be logged in as a mobile user to test the form, either on a mobile phone or by using the Login As feature in live preview to choose a mobile user. Once you've loaded the form, you should be able to choose a filter, and see an up-to-date count of how many items from the lookup table match the filter. Understand The lookup table querying is done inside of the #form/count Hidden Value calculation: count(instance('item-list:fruit')/fruit_list/fruit[type = #form/fruit_counter/what_kinds_of_fruit_do_you_want_to_count]) This shows how the lookup table can be queried with xpath syntax by starting expressions with the following root, with filters applied for additional logic instance('item-list:fruit')/fruit_list/fruit For example, to print a list of the names of all citrus fruits instead, you could use the expression join(" ", instance('item-list:fruit')/fruit_list/fruit[type = 'citrus']/name) Experiment Once you've loaded the form, you can use the Data Preview XPath Evaluator to experiment with different expressions, and see the data live. This tool is especially helpful for experimenting with lookup table queries because it can display for you the intermediate outputs of the filters, which can be a big help when debugging more complex expressions. NOTE - In order for you to be able to reference a lookup table from this tool, your form needs to already contain at least one reference to the lookup table in another expression (calculation, display condition, selection choices, etc) for the form to be connected to the table. You can see the lookup tables connected to your current form by typing "instance" into the tool and seeing what autocompletes. |
Setup a Form to Display a Random Question from Lookup Table
...
Expand | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
First setup the following two tables using the Creating and Updating Lookup Tables section. You can use whichever mobile workers or groups that you have in your project. state:
district:
Our sample creates two tables (state and district). The district table has three fields (id, name and state_id). The state_id will be used to filter the list of districts based on the selected state. The following image shows our final setup. Create a Multiple Choice/Checkbox Question Based on a Lookup Table NOTE: Lookup tables referenced in Multiple Choice or Checkbox questions should not have values with spaces in them. This can cause data issues in your app. Please define the values in the lookup tables without spaces. To create a multiple choice or checkbox question based on a lookup table, first add the question to your form. In our example, we'll add two multiple choice lookup table questions, "state" and "district". Now go to "Lookup Table Data" and select the correct lookup table and value and label fields. When inputting the value and labels an autocomplete widget will show you valid options for these fields. If you were to test this application, you'd see the first question displays a list of all states and the second question displays a list of all districts (irrespective of the selected state). To filter the district list, we need to add a filter condition to the choices. Filtering the Choices To filter the set of choices, you can use the 'Filter Option' under 'Lookup Table Data' (similar to the expressions used when defining Display Logic or Calculations in your form). In our example, we'll filter the District item list based on the selected state. Our district table contains a field called "state_id". The values in this match the value specified for the state question. The left option will show an autocomplete widget to help you pick a lookup table attribute and the right option will allow you to drag a question from the question tree. Loading a lookup table value into a hidden value instead of a multiple choice/checkbox question Sometimes you'll want to pull information from a lookup table into a hidden value. For example, from the example above, you want to save another case property called "project_name" and after the user selects a district, you already know which project it falls under. You create a hidden value question under the district question and name it "project_name". Then you create the following lookup table: project:
In the hidden value you'll enter the following calculation: instance('item-list:project')/project_list/project[id = /data/district ]/project_name. Depending on what the user chooses for district, the value for "project_name" will be either 'nutrition' or 'agriculture'. From the formula, the first 3 'project' refers to the lookup table name. 'id' is the value from the column in the lookup table that is matched with the question 'district', which has '/data/district' path in the form. The last part of the formula is 'project_name' and will be the value taken from the same named lookup table column and loaded into the hidden value. How to enter your own value using an 'other' option There might be times where you want to give the option to enter a location or value that might not be in the lookup table. You can do so by adding an 'other' option to your district table and a text question to your form that will only be displayed when the 'other' option is selected. The following steps will show you how to do so. Using the example above, we want to allow the user to enter a district that is not in the lookup table. To do so, you can add an ‘other’ field to the district lookup table:
You then proceed to create the form like you did above: Once the locations are set up, you need to add another filter to the lookup table question in the form. This filter will be based on the district ID, so the first field should be set to ‘id’. The second field should be set to ‘is equal’. And the third field should be set to ‘other’. We also want this option to occur only when ‘other’ is selected, so we also need to change the ‘Result is’ field to be ‘True when ANY of the expressions are true.” Be sure to save the expression once you are done! After saving the new expression and returning to the question properties page, you should see the full expression: Now you just need to add another text question to the form that will be displayed only when ‘other’ is selected: Now when your users select ‘other' for the district, they will be able to proceed to another question that will allow them to enter the district name. Testing an application with lookup tables In order to test the filtered choices and other logic works in the application, you must sign on as a mobile user and submit 'real' data to the server. If you see an error when opening the form that states "Could not find an appropriate fixture for src: jr://fixture/item-list:table_name" you have not properly setup your lookup tables.
If you run into issues testing your app with lookup tables, try to Clear user data. After you sync your phone if the lookup table still is not working, you may need to clear user data and log-in again. To do this, go to the login screen and click on Settings. After the Settings screen shows up, click the menu button, and select the first option, "Clear User Data." This will clear the username and force you to re-enter login credentials. Once you log in again, the new or edited table should be accessible to your user. Training an application with lookup tables
Factors contributing to form's performance using LookUp Table : In many cases, your Lookup table may scale up to a point where it starts to make your form inefficient for user to use. Lookup tables tend to deteriorate the user experience in such scenarios.
|
...
Expand | ||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Defining a Lookup Table that Support Multiple Languages Please review the Creating and Updating Lookup Tables section to understand the basics of defining lookup tables. Unfortunately, the current interface cannot be used to completely define a table that supports multiple languages. Instead, we can upload an Excel document that sets up the table for us.
Note: I've set this table up so that its visible to all users (for simplicity).
types sheet to identify which columns will have multiple languages. This is done by adding an extra property on the field that will indicate the language. This is highlighted in Red below.
state sheet to add the list of states with each language. We'll also need to modify this sheet's columns to include the additional language information. You will need to add columns for each language supported. The example below includes two languages, but you can add additional columns titled name: lang X and field: name X for more languages. In the lang column, specify the language code used in CommCareHQ for the language. You can find this by reviewing https://dimagi.atlassian.net/wiki/x/njTKfw. In this example, I've used English and Hindi. (Note: For new rows, you can ignore the UID and Delete(Y/N) columns).
Using Multiple Languages with Multiple Choice/Checkbox Questions
lang-code and label text that matches the language code for each language. We'll also set a Display Condition of 1=2 on this to ensure that it doesn't appear in the form. This label will be used to determine which language to display, based on what language is chosen.
a. Set the lookup table to the lookup table you uploaded (ex. state) b. Set the value field to the column in your table you want to store (ex. id) c. Set the display text field to the following: name[@lang = jr:itext('lang-code-label')] . You can replace name with the column that contains multiple languages.
Testing an application with lookup tables In order to test the filtered choices and other logic works in the application, you must sign on as a mobile user and submit 'real' data to the server. If you see an error when opening the form that states "Could not find an appropriate fixture for src: jr://fixture/item-list:table_name" you have not properly setup your lookup tables (make sure you did tap the blue button in the app menu "sync with server" before going into the form as this can give the same error message. When you sync, the updated lookup table(s) will be downloaded to your device).
If you run into issues testing your app with lookup tables, try to clear user data. After you sync your phone if the lookup table still is not working, you may need to clear user data and log-in again. To do this, go to the login screen and click on Settings. After the Settings screen shows up, click the menu button, and select the first option, "Clear User Data." This will clear the username and force you to re-enter login credentials. Once you log in again, the new or edited table should be accessible to your user. Training an application with lookup tables
|
Excel Tricks for Lookup Tables
Below is a list of tips and tricks for managing your Lookup Tables in Excel.
...
title | Click to expand. |
---|
Managing large lookup tables efficiently
Sometimes when creating Lookup Tables, you can receive large source files with values in different fonts, all caps etc. This page describes a few tricks on how to make values easily all lower case, how to replace spaces by underscores etc. Below are a set of Excel formulas, with a description of what it does and how to use it.
Note: this tutorial assumes that you are using Excel in English. The names of the formulae are different in French.
How to turn all your text entries to first-letter capital for each word (ex: First_name Last_name)
=proper
Use: Converts words written in any format to words where the first letter is upper case and the rest is lower case. Example: CAPE TOWN > Cape Town
How: Add a column next to the column where all the values are, then in the first cell of the new column add =proper(cell number) and click enter (for 'cell number' click on the cell with the all caps value). Drag the corner right little box from the cell down so that all values from the all caps column will be converted.
When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (i.e., the text in the desired format).
...
Note: For words that are already properly formatted (ex: Johannesburg in the example above), no change is applied. Note as well that "cape town" turns to Cape Town.
How to quickly format all your text entries to all caps:
=upper
Use: Converts words written in any format to all caps. Example: Cape Town > CAPE TOWN
How: Add a column next to the original words/text. Use the formula =UPPER(cell number) in the new column and click enter. Drag down the formula to replicate this for all your text.
When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (i.e., the text in the desired format).
...
=lower
Use: Converts words written in any format to all lower case. Example: Cindy Jones > cindy jones
How: Add a column next to the original words/text. Use the formula =LOWER(cell number) in the new column and click enter. Drag down the formula to replicate this for all your text.
When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (i.e., the text in the desired format).
...
How to quickly delete unwanted spaces:
=trim
Use: For when you receive a list of names/places where there is a space before the first word or after the final word. Example " cindy jones " (notice the space before 'cindy' and after 'jones'. The TRIM function will yield "cindy jones"
How: Add a column next to the original words/text. Use the formula =TRIM(cell number) in the new column and click enter. Drag down the formula to replicate this for all your text.
When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (ie, the text in the desired format).
Note: TRIM only deletes spaces before or at the end a full string of text. It will not eliminate common/accurate spaces such as the space between a first and last name.
...
Combining the above formulas: (ex: to eliminate unnecessary spaces AND to format upper/lower case)
=UPPER(TRIM(cell number)) or =LOWER(TRIM(cell number)) or =PROPER(TRIM(cell number))
Use: Do the steps above more quickly!
How: Add a column next to the original words/text. Use the formula =UPPER(TRIM(cell number)) in the new column and click enter. Drag down the formula to replicate this for all your text.
*the bolded UPPER can be modified to reflect what you actually want.
When clicking on the new value, you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (ie, the text in the desired format).
...
Use: It is recommended that before you upload your lookup table into CommCare HQ that you eliminate the spacing between the words. Example: marie france > marie_france
How: (numbered steps correspond to the images below)
Select the column(s) where the data are located. Then click "Ctrl + F" to show the "Find" box. Go to the tab "Replace" and in the "Find what:" entry box, type a space.
In the "Replace with:" entry box, type an underscore "_"
Click "Replace all."
...
How to quickly append text/numbers to the end a text:
=CONCATENATE
Use: Imagine that you have a list of districts and another list of villages. Some of the districts have the exact same name as the villages (Ex: District: Bambara, which contains a village also called Bambara). CommCare will require you to distinguish which of the "Bambara" is a village and which is a district. For this example, we will append "_vil" to the end of each village name.
How: Create a column next to the one containing the words you want to append. Use =CONCATENATE(cell number, "what you want to append"). In this case, we appended _vil.
When clicking on the new value in the column "Appended Village", you'll notice that the value of the cell is still the formula. Select the first cell and then click ctrl+shift+down arrow (this will select all values in this column) and click ctrl+c to copy the selection. Then right click and choose 'paste values' under paste options. This eliminates the formula so that you are only left with the values you want (ie, the text in the desired format).
...
How to quickly eliminate duplicate entries from your Lookup list:
Use: To link villages to districts, you need one row per village. But because multiple villages can belong to a single district, this means as a result that you will have several rows where your district is repeated. CommCare will require a separate list for districts and a separate one for villages. For that reason, you will want to eliminate all the duplicate districts from your Excel spreadsheet.
How: (numbered steps correspond to the images below)
1.. Select the columns containing duplicate data. Click "Data" on the toolbar, then click "Remove Duplicates"
2.. Make sure that you select that your data has headers (if it does), and that you have selected the entire column. Click OK.
3.. You will see a message box with the number of duplicate values that have been removed and the number remaining.
...
If you want to be able to see which duplicate values were removed
In a new tab, copy - paste your original column with duplicates into column A
Copy - paste your new cleaned up column into column B
In column C, enter the following countif equation: "=COUNTIF(B1:B800, A1)"
In any row that has the value "2" in column C, the column A value is a duplicate
How to (very) quickly fill in a column with a value or a formula:
If you want to quickly pull down a single value, you can double click (don’t drag) on the bottom right corner and the value will fill in bellow for all rows where there is information next to it.
The RED X shows you were to double click.
...
AND the same thing can be done with Functions! But don't forget to copy and paste value once you've created a column of functions.
...
Calculate a Z-Score in a Form
This section will walk through an example of setting up a form to calculate a z-score based on age in months, gender, and weight.
Expand | ||
---|---|---|
| ||
First, upload the following z-score table using the information in this section. This table covers children between 0 and 60 months of age, but you can modify the table as needed for your project. Including Lookup Table Information in the Form Once we've defined a zscore lookup table, we need to reference it in our form. Edit the form XML and add an "instance" line that references the name of the table. You can place this above any existing instance tags in your form.
Calculating the Z-Score In your form, first add three questions, one for the gender, age in months and measured weight. (You can also load these from a case if you've previously captured them elsewhere). Note-- your answer options for the gender question MUST be "female" and "male" (not "m", "f" or "1", "2") to align with what is written in the z score look up table. Then add a hidden value (zscore) to calculate the approximate z-score from the table. Assuming the name of your lookup table is "zscore" the calculation for this hidden value should be:
Note: This calculation uses case properties named "gender", "weight", and "age." If you have named your case properties something else, you will need to change the reference above to the same name as your case properties. This hidden value will be -3, -2, -1, or 0 which corresponds to the child being more than -3, -2, and -1 standard deviations from the mean. You can then use this hidden value for further calculations or display it back to the user. testing your app with lookup tables, try to clear user data. After you sync your phone if the lookup table still is not working, you may need to clear user data and log-in again. To do this, go to the login screen and click on Settings. After the Settings screen shows up, click the menu button, and select the first option, "Clear User Data." This will clear the username and force you to re-enter login credentials. Once you log in again, the new or edited table should be accessible to your user. Training an application with lookup tables
|
Calculate a Z-Score in a Form
This section will walk through an example of setting up a form to calculate a z-score based on age in months, gender, and weight.
Expand | ||
---|---|---|
| ||
First, upload the following z-score table using the information in this section. This table covers children between 0 and 60 months of age, but you can modify the table as needed for your project. Including Lookup Table Information in the Form Once we've defined a zscore lookup table, we need to reference it in our form. Edit the form XML and add an "instance" line that references the name of the table. You can place this above any existing instance tags in your form.
Calculating the Z-Score In your form, first add three questions, one for the gender, age in months and measured weight. (You can also load these from a case if you've previously captured them elsewhere). Note-- your answer options for the gender question MUST be "female" and "male" (not "m", "f" or "1", "2") to align with what is written in the z score look up table. Then add a hidden value (zscore) to calculate the approximate z-score from the table. Assuming the name of your lookup table is "zscore" the calculation for this hidden value should be:
Note: This calculation uses case properties named "gender", "weight", and "age." If you have named your case properties something else, you will need to change the reference above to the same name as your case properties. This hidden value will be -3, -2, -1, or 0 which corresponds to the child being more than -3, -2, and -1 standard deviations from the mean. You can then use this hidden value for further calculations or display it back to the user. |
Advanced: Indexing Lookup Tables (Larger Lookup Tables)
Indexes are designed to solve a specific problem: references to a large lookup table are slowing down your application.
Expand | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||
For example, suppose you are using a lookup table to set up a question with filtered choices. Your lookup table, health_centers_by_region, has the following fields:
and you have a hidden value that contains the calculation:
If this table is large enough that this filter is slowing down performance in your form, you may be able to alleviate this by adding an index to district_id and moving the indexed field to the front of your filter, so that:
becomes:
Definitions
What is an Index?An index is a data structure that helps make certain XPath expressions that reference a lookup table more efficient. When you index a field in a lookup table, you can improve the speed of expressions on that particular field. The following scenarios highlight the difference between querying a field that is indexed, compared to querying an unindexed field:
When Should I Create an Index on my Lookup Table?Most lookup tables will not need to be indexed. If you think you might need to index one or more fields of a lookup table, ask yourself:
If you answered "yes" to all of the above questions, it might be worth adding an index for one or more fields in your lookup table. If you're not sure whether a particular query is slowing down your app, try the following exercise:
Indexing Tables Used in Multiple Choice Lookup Table Questions If you are populating a multiple choice or checkbox question from a lookup table, and are still experiencing performance issues after indexing any appropriate columns from the filter, try adding indexes for the Value Field and the Display Text Field. How Do I Add an Index?Suppose you have a lookup table health_centers_by_region with the following fields (this is the same table from the Overview above):
As part of your workflow, a mobile worker often needs to select a health center in a certain region that has MNCH services available. There are thousands of health centers spread over hundreds of districts, and you've noticed that a query that appears throughout the app is taking a long time:
Since district_id has hundreds of values represented, it has a high enough cardinality to warrant an index. mnch_services_available will only ever be set to "yes" or "no." Since the cardinality for this field is low, the benefits of indexing the field would be minimal compared to the extra space it would take up on the phone, so it should not be indexed. Before adding an index to the lookup table, please refamiliarize yourself with the process of creating and updating lookup tables, specifically downloading or uploading tables for editing. When you're ready to add an index, follow these steps:
Once the index has been added, you will need to rewrite your query so that the indexed field or fields appear at the beginning of the string of filters. Since region_id is indexed and mnch_services_available is not, our example becomes:
See the next section for details. Query OptimizationWhen writing XPath queries on an indexed lookup table (or on any indexed fixture, such as casedb), it is important to write your query such that all filters on indexed properties are evaluated BEFORE other filters. For example, say you have a lookup table health_centers_by_region with the following fields:
If we want a query to return all health centers in region 123 where MNCH services are available, we would write:
With this query, the XPath query evaluator will first use an efficient key lookup to filter on the indexed field (region_id), before performing single lookups on each of the results to check whether mnch_services_available = "yes" for each one. The following documents go into much further technical detail on XPath evaluation and optimization:
LimitationsComplex Queries Currently, only the most basic XPath queries will leverage lookup table indexing. For example: value = 1 will use the indexing, but value < 2 will not. In addition, composite queries using and or or will not leverage the indexes. Lookup Tables with Multiple Languages When indexing a lookup table with multiple languages, you can only index fields that do not have translations. Indexing columns with attributes is unsupported. |