banner

For a full list of BASHing data blog posts, see the index page.     RSS


YAD repeat and edit

I use YAD form dialogs to enter data into my "databases", which are just tab-separated, plain-text tables with primary and foreign key fields. (My YAD is version 0.38.2)

I usually do my data entering in batches of new records. If new record 2 had some of the same data values as new record 1, it was annoying to have to enter those values again. For this reason, I rewrote the data-entering scripts to include a Repeat and edit option: fill the (editable) YAD form with values from the previously entered record.

For demonstration purposes I'll use a CSV (called "table") with just 3 fields, like this:

RecNo,Fruit,Kg
1001,banana,10.2
1002,banana,4.6
1003,apple,7.1

A simple YAD command for data entry would be:

yad --form --separator="," --field="RecNo" --field="Fruit" --field="Kg" \
| sed 's/,$//' >> table

form1

The sed command is there to delete the comma added by YAD at the end of the comma-separated string of data items, before they're appended to "table".

Putting the command in a script, we can auto-increment the RecNo for each new record. We put the last record number (from "table") plus 1 into the RecNo field on the form, and make that a read-only entry:

#!/bin/bash
 
number=$(printf "%s" $(($(tail -n 1 table | cut -d"," -f1)+1)))
 
yad --form --separator="," --field="RecNo":RO --field="Fruit" --field="Kg" \
"$number" "" "" | sed 's/,$//' >> table

form2

Because more than one record may be entered at a time, it's handy to put the whole data-entering operation in a while loop, and to ask after each entry whether to quit or to continue entering records:

#!/bin/bash
 
while true; do
 
number=$(printf "%s" $(($(tail -n 1 table | cut -d"," -f1)+1)))
 
yad --form --separator="," --field="RecNo":RO --field="Fruit" --field="Kg" \
"$number" "" "" | sed 's/,$//' \
>> table  2>/dev/null
 
yad --image "dialog-question" --text "Enter another record?" \
--button="gtk-quit":1 --button="New entry":0 2>/dev/null
 
case $? in
1) exit 0 ;;
0) continue ;;
esac
 
done
 
exit 0

After data has been entered in the first YAD dialog for RecNo 1004 and appended to "table", the second YAD dialog pops up.

form3

If the answer is "Quit", the script exits. If the answer is "New entry", the continue command returns us to the start of the "do" section, and this time the RecNo is 1005.

For a Repeat and edit option, we can add another button to that question dialog, and put a second while loop nested inside the first:

#!/bin/bash
 
while true; do
 
number=$(printf "%s" $(($(tail -n 1 table | cut -d"," -f1)+1)))
 
yad --form --separator="," --field="RecNo":RO --field="Fruit" --field="Kg" \
"$number" "" "" | sed 's/,$//' \
>> table 2>/dev/null
 
yad --image "dialog-question" --text "Enter another record?" \
--button="gtk-quit":1 --button="Repeat and edit":3 --button="New entry":0 2>/dev/null
 
case $? in
1) exit 0 ;;
0) continue ;;
3) while true; do
    printf "%s,%s\n" $(( $(tail -n 1 table | cut -d"," -f1) + 1 )) \
    $(tail -n 1 table | cut -d"," -f2-) | tr ',' '\n' \
    | yad --form --separator="," --field="RecNo":RO --field="Fruit" --field="Kg" \
    | sed 's/,$//' >> table 2>/dev/null
 
    yad --image "dialog-question" --text "Enter another record?" \
    --button="gtk-quit":1 --button="Repeat and edit":3 \
    --button="New entry":0   2>/dev/null
 
    case $? in
    1) exit 0 ;;
    3) continue ;;
    0) break ;;
    esac
    done
 
esac
done
 
exit 0

The amended script works like the last one unless "Repeat and edit" is selected. That starts the nested while loop in which a data-entry YAD dialog is loaded with both an incremented RecNo and the Fruit and Kg from the previous record. The loading is done with a newline-separated list; YAD puts each line into a field in the form.

If I'm entering a couple of banana records one after the other, the dialogs will look like this:

form4
 
form8a
 
form5
 

Editing Kg from 13.1 to 9.4 and entering:

form6

RecNo,Fruit,Kg
1001,banana,10.2
1002,banana,4.6
1003,apple,7.1
1004,banana,13.1
1005,banana,9.4

There are two ways to escape the inner while loop. Choosing "Quit" forces an exit from the program, and choosing "New entry" breaks out of the inner loop and returns us to the outer loop, with an incremented RecNo and nothing in the Fruit and Kg fields:

form8b
 
form7

My real-world data entry scripts are more complicated than the one shown here and have more options, but at their core they now have this time-saving "Repeat and edit" feature.


Last update: 2018-05-21