-
Notifications
You must be signed in to change notification settings - Fork 0
/
_Smart Data Validation.gs
237 lines (184 loc) · 7.57 KB
/
_Smart Data Validation.gs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
function makeSmartDataValidation(ObjDv, ObjValues, sheet)
{
// Loop connections
var connections = ObjDv.connections;
var connection = {};
var dataSet = {};
for (var i = 0, l = connections.length; i < l; i++)
{
connection = connections[i];
dataSet = ObjDv.dataSets[connection.name];
makeSmartDVConnection(ObjValues, connection, dataSet);
}
// take action at last
makeTasks(sheet);
}
function makeSmartDVConnection(ObjValues, connection, dataSet)
{
/*
connection = {"r":5,"c":[1,2,3,5],"columnsChanged":[2,3,5],"name":"0Data Sample"}
ObjValues = {"rowNums":[6],"R6C2":{"value":"s","range":{}}}
dataSet = {"n":"Data Sample","d":{"Earth":{"Europe":{"Britain":...}},"h":["Planet","Mainland","Country","City"],"l":4,"s":">","f":0}}
*/
var columnsChanged = connection.columnsChanged;
var numCol = columnsChanged[columnsChanged.length - 1]; // check only last changed column
var numRows = ObjValues.rowNums;
var objDvChange = {};
var objCellInfo = {};
var numRow = 0;
// loop changed rows
for (var i = 0, l = numRows.length; i < l; i++)
{
numRow = numRows[i];
if (numRow > connection.r) // check if row is in range of data
{
objDvChange = getObjDvChange(numCol, numRows[i], connection.c, columnsChanged, ObjValues);
makeSmartDVRow(objDvChange, dataSet, ObjValues);
}
}
}
function getObjDvChange(numCol, numRow, columns, columnsChanged, ObjValues)
{
var objDvChange = {};
// fill with coords
objDvChange.numRow = numRow;
objDvChange.numCol = numCol;
objDvChange.addR1C1 = 'R' + numRow + 'C' + numCol;
objDvChange.columns = columns;
objDvChange.columnsChanged = columnsChanged;
// fill with values
var objCellInfo = ObjValues[objDvChange.addR1C1];
objDvChange.value = objCellInfo.value;
objDvChange.range = objCellInfo.range;
return objDvChange;
}
function makeSmartDVRow(objDvChange, dataSet, ObjValues)
{
/*
objDvChange = {"numRow":7,"addR1C1":"R7C1","value":"Tatooine","range":{},"numCol":3, "columns": [1,2,3,5],"columnsChanged":[2,3,5]}
ObjValues = {"rowNums":[6],"R6C2":{"value":"s","range":{}}}
dataSet = {"n":"Data Sample","d":{"Earth":{"Europe":{"Britain":...}},"h":["Planet","Mainland","Country","City"],"l":4,"s":">","f":0}}
*/
// Check if column is last level
var boolLastLevel = false;
var level = objDvChange.columns.indexOf(objDvChange.numCol);
boolLastLevel = (level === dataSet.l - 1);
// Check. If empty ctring
var boolBadValue = false;
if (objDvChange.value === '') { boolBadValue = true; } // value = ''
// get a helpText
var ObjValue = ObjValues[objDvChange.addR1C1]
var range = ObjValue.range;
var validation = range.getDataValidation();
// Check. if no data validation
if (!validation) { boolBadValue = true; } // no data validation
else
{
// get next help text: "Earht>Europe", "Earth"
var helpText = validation.getHelpText();
var keyData = helpText + dataSet.s + objDvChange.value;
}
if (!helpText) { keyData = ObjValue.value; }
// get next list for DVR
var keyTask = 'makeDv';
var data = getDvRuleList(dataSet, keyData);
// Check. if no data found
if (!data) { boolBadValue = true; } // no data dound
// deal with bad value
if (boolBadValue)
{
dealWithBadValue(objDvChange, ObjValues, dataSet);
return 0; // do not add tasks
}
if (boolLastLevel) { return 0; } // last level & value = OK
// Add task
var columns = objDvChange.columns;
var numIndx = columns.indexOf(objDvChange.numCol) + 1;
if (numIndx === dataSet.l) { return 0; } // no need to make new rule, this is last level
var numColTo = columns[numIndx];
addTask(keyTask, keyData, objDvChange.numRow, [numColTo], data);
// fill the only value
if (data.length === 1) { dealWithOnlyValue(data[0], keyData, dataSet.s, objDvChange.numRow, numColTo, columns, dataSet) }
}
function dealWithOnlyValue(value, keyData, splitter, numRow, numColTo, columns, dataSet)
{
// if last level
var boolLastLevel = false;
var level = columns.indexOf(numColTo);
boolLastLevel = (level === dataSet.l - 1);
// set the only value
var keyTask = 'setVal'
addTask(keyTask, value, numRow, [numColTo]);
// make next validation if it is not the last value
if (!boolLastLevel)
{
// add task on next DV
keyTask = 'makeDv';
keyData = keyData + splitter + value; // A>B + > + C = A>B>C
var data = getDvRuleList(dataSet, keyData);
numColTo = columns[level + 1]; // column of the next level
addTask(keyTask, keyData, numRow, [numColTo], data);
// launch itself
if (data.length === 1) {
value = data[0]
dealWithOnlyValue(value, keyData, splitter, numRow, numColTo, columns, dataSet);
}
}
}
function dealWithBadValue(objDvChange, ObjValues, dataSet)
{
/*
objDvChange = {"numRow":7,"addR1C1":"R7C1","value":"Tatooine","range":{},"numCol":3, "columns": [1,2,3,5],"columnsChanged":[2,3,5]}
ObjValues = {"rowNums":[6],"R6C2":{"value":"s","range":{}}}
dataSet = {"n":"Data Sample","d":{"Earth":{"Europe":{"Britain":...}},"h":["Planet","Mainland","Country","City"],"l":4,"s":">","f":0}}
*/
/*
Plan:
a. add to tasks: kill validation and values on next levels, on head level if it is
b. run makeSmartDVRow with level - 1 (check if it is ok) or If level = 1 => exit
*/
/*
OBJ_TASKS_DV
"clearContents" ~ keyTask
"" ~ keyData
numRows = [1,2,3,4]
numColumnss = [[2,3], [2,3], [2,3], [2,3]]
"makeDv"
"Paris>Lion"
numRows = [1,2,3,4]
numColumnss = [[2,3], [2,3], [2,3], [2,3]]
data = ["Paris", "Lion"]
addTask(keyTask, keyData, numRow, numCols, data)
*/
// a. add to tasks: kill validation and values on next levels, on head level if it is
var nextColumns = objDvChange.columns.filter(function(elt) { return elt > objDvChange.numCol; } );
if (nextColumns && nextColumns.length) { addTask('clearDv', '', objDvChange.numRow, nextColumns); } // clear DV on next levels
var nextColumnsIn = objDvChange.columns.filter(function(elt) { return elt >= objDvChange.numCol; } );
if (nextColumnsIn && nextColumnsIn.length) { addTask('clearContents', '', objDvChange.numRow, nextColumnsIn); } // clear values on next + current level
var indxLevel = objDvChange.columns.indexOf(objDvChange.numCol);
var indxChanged = objDvChange.columnsChanged.indexOf(objDvChange.numCol);
if (indxLevel === 0)
{
// have a bad value on first level
// set data validation
var keyTask = 'makeDv';
var keyData = "";
var data = getDvRuleList(dataSet, "");
addTask(keyTask, keyData, objDvChange.numRow, [objDvChange.numCol], data);
return 0; // do nothing more here
}
else if (indxChanged === 0) // nothing before was changed
{
return 0; // do nothing more here
}
else
{
// b. run makeSmartDVRow with level - 1 (check if it is ok) or If level = 1 => exit
// change objDvChange =
// {"numRow":7,"addR1C1":"R7C1","value":"Tatooine","range":{},"numCol":3, "columns": [1,2,3,5],"columnsChanged":[2,3,5]}
// + change change change change +
var numColumnPre = objDvChange.columnsChanged[indxChanged - 1];
var newObjDvChange = getObjDvChange(numColumnPre, objDvChange.numRow, objDvChange.columns, objDvChange.columnsChanged, ObjValues);
makeSmartDVRow(newObjDvChange, dataSet, ObjValues);
}
}