Hi everyone ![]()
Recently @Sagar_Thosre requested an app to create a “Book of Laws” with
section >> subsections >> articles
@securebugs suggested using Google Sheets/Airtable.
Since Google Sheets is much more widely used and can be easily accessed in CSV format via the Web component, I thought it would be useful to find a way to proceed with it.
Here’s what I managed to do.
Data on Google Sheets
This is the structure, where each element is repeated if it belongs to the same category.
Blocks
I want to preface by saying I’m sure it can be further optimized, so if anyone has a smarter/more efficient method, I’d be happy to update it and give credit.
I won’t explain every single block of the aia project because my main goal is to share the procedure.
The procedure receives two parameters:
csvText: the CSV textstopNestingAtIndex: this is the index at which the procedure will stop nesting the columns and will create a dictionary{"columnName":"cellValue"}for each subsequent value.
In our example it will stop at the “Text” column, which is number 4
(the column following the last nesting)
We create 3 variables that we’ll use later:
nestedDictionary: which will contain our dictionarylistOfList: which will be our CSV formatted as a list of listsheaders: which will be the first row oflistOfListcontaining the list of column names
(Section SubSection Article Text Unique ID)
After populating the headers variable with the first row of listOfList, we remove it from listOfList so that only the data remains.
At this point, to explain how it works, instead of commenting on each part as I usually do, I think it’s more effective to give a practical example.
stopNestingAtIndex = 4Where I marked with a red dot, we are at
colNumber = 3.For each row in list, have
row = (2 2.1 Art. 10 Article text 10 Law_uid10)For each
wkNumber it will loop from 1 to 3 and will add to keypath the element in row at that index, in this case (2 2.1 Art. 10)Then, if the
key(Art. 10) is not present in the keypath butLast(2 2.1), it will create the key inside nestedDictionary with the value of tempDictionary, which in this case is empty.
stopNestingAtIndex = 4Here we are at
colNumber = 5.For each row in list, have
row = (2 2.3 Art. 17 Article text 17 Law_uid17)For each
wkNumber it will loop from 1 to 3 and will add to keypath the element in row at that index, in this case (2 2.1 Art. 10)From 4 to 5 it will add to
tempDictionary some dictionaries which in this case will be,at cycle 4
{"Text":"Article text 17"}at cycle 5
{"Unique ID":"Law_uid17"}.
Then, if the key(Art. 10) is not present in the keypath butLast(2 2.3 Art. 17), it will create the key inside nestedDictionary with the value of tempDictionary.
{
{"Text": "Article text 17"},
{"Unique ID": "Law_uid17"}
}
I hope these examples can make it clearer,
so by passing a CSV like this:
CSV
Section,SubSection,Article,Text,Unique ID
1,1.1,Art. 1,Article text 1,Law_uid1
1,1.1,Art. 2,Article text 2,Law_uid2
1,1.1,Art. 3,Article text 3,Law_uid3
1,1.2,Art. 4,Article text 4,Law_uid4
1,1.2,Art. 5,Article text 5,Law_uid5
1,1.2,Art. 6,Article text 6,Law_uid6
1,1.3,Art. 7,Article text 7,Law_uid7
1,1.3,Art. 8,Article text 8,Law_uid8
1,1.3,Art. 9,Article text 9,Law_uid9
2,2.1,Art. 10,Article text 10,Law_uid10
2,2.1,Art. 11,Article text 11,Law_uid11
2,2.2,Art. 12,Article text 12,Law_uid12
2,2.2,Art. 13,Article text 13,Law_uid13
2,2.2,Art. 14,Article text 14,Law_uid14
2,2.3,Art. 15,Article text 15,Law_uid15
2,2.3,Art. 16,Article text 16,Law_uid16
2,2.3,Art. 17,Article text 17,Law_uid17
3,3.1,Art. 18,Article text 18,Law_uid18
3,3.1,Art. 19,Article text 19,Law_uid19
3,3.2,Art. 20,Article text 20,Law_uid20
3,3.2,Art. 21,Article text 21,Law_uid21
3,3.2,Art. 22,Article text 22,Law_uid22
3,3.3,Art. 23,Article text 23,Law_uid23
3,3.3,Art. 24,Article text 24,Law_uid24
3,3.3,Art. 25,Article text 25,Law_uid25
4,4.1,Art. 26,Article text 26,Law_uid26
4,4.1,Art. 27,Article text 27,Law_uid27
4,4.2,Art. 28,Article text 28,Law_uid28
4,4.2,Art. 29,Article text 29,Law_uid29
4,4.2,Art. 30,Article text 30,Law_uid30
4,4.3,Art. 31,Article text 31,Law_uid31
4,4.3,Art. 32,Article text 32,Law_uid32
4,4.3,Art. 33,Article text 33,Law_uid33
5,5.1,Art. 34,Article text 34,Law_uid34
5,5.1,Art. 35,Article text 35,Law_uid35
5,5.2,Art. 36,Article text 36,Law_uid36
5,5.2,Art. 37,Article text 37,Law_uid37
5,5.2,Art. 38,Article text 38,Law_uid38
5,5.3,Art. 39,Article text 39,Law_uid39
5,5.3,Art. 40,Article text 40,Law_uid40
5,5.3,Art. 41,Article text 41,Law_uid41
6,6.1,Art. 42,Article text 42,Law_uid42
6,6.1,Art. 43,Article text 43,Law_uid43
6,6.2,Art. 44,Article text 44,Law_uid44
6,6.2,Art. 45,Article text 45,Law_uid45
6,6.2,Art. 46,Article text 46,Law_uid46
6,6.3,Art. 47,Article text 47,Law_uid47
6,6.3,Art. 48,Article text 48,Law_uid48
6,6.3,Art. 49,Article text 49,Law_uid49
7,7.1,Art. 50,Article text 50,Law_uid50
We will get a JSON like this:
JSON
{
"1":{
"1.1":{
"Art. 1":{
"Text":"Article text 1",
"Unique ID":"Law_uid1"
},
"Art. 2":{
"Text":"Article text 2",
"Unique ID":"Law_uid2"
},
"Art. 3":{
"Text":"Article text 3",
"Unique ID":"Law_uid3"
}
},
"1.2":{
"Art. 4":{
"Text":"Article text 4",
"Unique ID":"Law_uid4"
},
"Art. 5":{
"Text":"Article text 5",
"Unique ID":"Law_uid5"
},
"Art. 6":{
"Text":"Article text 6",
"Unique ID":"Law_uid6"
}
},
"1.3":{
"Art. 7":{
"Text":"Article text 7",
"Unique ID":"Law_uid7"
},
"Art. 8":{
"Text":"Article text 8",
"Unique ID":"Law_uid8"
},
"Art. 9":{
"Text":"Article text 9",
"Unique ID":"Law_uid9"
}
}
},
"2":{
"2.1":{
"Art. 10":{
"Text":"Article text 10",
"Unique ID":"Law_uid10"
},
"Art. 11":{
"Text":"Article text 11",
"Unique ID":"Law_uid11"
}
},
"2.2":{
"Art. 12":{
"Text":"Article text 12",
"Unique ID":"Law_uid12"
},
"Art. 13":{
"Text":"Article text 13",
"Unique ID":"Law_uid13"
},
"Art. 14":{
"Text":"Article text 14",
"Unique ID":"Law_uid14"
}
},
"2.3":{
"Art. 15":{
"Text":"Article text 15",
"Unique ID":"Law_uid15"
},
"Art. 16":{
"Text":"Article text 16",
"Unique ID":"Law_uid16"
},
"Art. 17":{
"Text":"Article text 17",
"Unique ID":"Law_uid17"
}
}
},
"3":{
"3.1":{
"Art. 18":{
"Text":"Article text 18",
"Unique ID":"Law_uid18"
},
"Art. 19":{
"Text":"Article text 19",
"Unique ID":"Law_uid19"
}
},
"3.2":{
"Art. 20":{
"Text":"Article text 20",
"Unique ID":"Law_uid20"
},
"Art. 21":{
"Text":"Article text 21",
"Unique ID":"Law_uid21"
},
"Art. 22":{
"Text":"Article text 22",
"Unique ID":"Law_uid22"
}
},
"3.3":{
"Art. 23":{
"Text":"Article text 23",
"Unique ID":"Law_uid23"
},
"Art. 24":{
"Text":"Article text 24",
"Unique ID":"Law_uid24"
},
"Art. 25":{
"Text":"Article text 25",
"Unique ID":"Law_uid25"
}
}
},
"4":{
"4.1":{
"Art. 26":{
"Text":"Article text 26",
"Unique ID":"Law_uid26"
},
"Art. 27":{
"Text":"Article text 27",
"Unique ID":"Law_uid27"
}
},
"4.2":{
"Art. 28":{
"Text":"Article text 28",
"Unique ID":"Law_uid28"
},
"Art. 29":{
"Text":"Article text 29",
"Unique ID":"Law_uid29"
},
"Art. 30":{
"Text":"Article text 30",
"Unique ID":"Law_uid30"
}
},
"4.3":{
"Art. 31":{
"Text":"Article text 31",
"Unique ID":"Law_uid31"
},
"Art. 32":{
"Text":"Article text 32",
"Unique ID":"Law_uid32"
},
"Art. 33":{
"Text":"Article text 33",
"Unique ID":"Law_uid33"
}
}
},
"5":{
"5.1":{
"Art. 34":{
"Text":"Article text 34",
"Unique ID":"Law_uid34"
},
"Art. 35":{
"Text":"Article text 35",
"Unique ID":"Law_uid35"
}
},
"5.2":{
"Art. 36":{
"Text":"Article text 36",
"Unique ID":"Law_uid36"
},
"Art. 37":{
"Text":"Article text 37",
"Unique ID":"Law_uid37"
},
"Art. 38":{
"Text":"Article text 38",
"Unique ID":"Law_uid38"
}
},
"5.3":{
"Art. 39":{
"Text":"Article text 39",
"Unique ID":"Law_uid39"
},
"Art. 40":{
"Text":"Article text 40",
"Unique ID":"Law_uid40"
},
"Art. 41":{
"Text":"Article text 41",
"Unique ID":"Law_uid41"
}
}
},
"6":{
"6.1":{
"Art. 42":{
"Text":"Article text 42",
"Unique ID":"Law_uid42"
},
"Art. 43":{
"Text":"Article text 43",
"Unique ID":"Law_uid43"
}
},
"6.2":{
"Art. 44":{
"Text":"Article text 44",
"Unique ID":"Law_uid44"
},
"Art. 45":{
"Text":"Article text 45",
"Unique ID":"Law_uid45"
},
"Art. 46":{
"Text":"Article text 46",
"Unique ID":"Law_uid46"
}
},
"6.3":{
"Art. 47":{
"Text":"Article text 47",
"Unique ID":"Law_uid47"
},
"Art. 48":{
"Text":"Article text 48",
"Unique ID":"Law_uid48"
},
"Art. 49":{
"Text":"Article text 49",
"Unique ID":"Law_uid49"
}
}
},
"7":{
"7.1":{
"Art. 50":{
"Text":"Article text 50",
"Unique ID":"Law_uid50"
}
}
}
}
CSV file
LawsBook - Sheet1.csv (2.0 KB)
AIA

NestedJsonFromCSV.aia (134.1 KB)
Remember to set the spreadsheet ID.

With different table
stopNestingAtIndex = 6
{
"MasterBook1": {
"Book1": {
"1": {
"1.1": {
"Art. 1": {
"Text": "Article text 1",
"Unique ID": "Law_uid1",
"Date": "1 January 1997",
"Status": "repealed"
}
}
}
}
}
}
As always, I’m available for any clarification.
Happy
oding!





