cloud-web-corejs 1.0.175 → 1.0.177
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/App.vue +1 -1
- package/src/components/obsUpload/index.js +1 -0
- package/src/components/obsUpload/index.vue +231 -0
- package/src/components/obsUpload/mixins.js +8 -0
- package/src/components/xform/utils/formula-util copy 2.js +0 -945
- package/src/components/xform/utils/formula-util copy.js +0 -860
|
@@ -1,945 +0,0 @@
|
|
|
1
|
-
// 计算公式相关工具方法
|
|
2
|
-
import {evalFn, getFieldWidgetById, traverseFieldWidgetsOfContainer} from "@base/components/xform/utils/util";
|
|
3
|
-
import * as formulajs from '@formulajs/formulajs'
|
|
4
|
-
import {EditorView} from "codemirror"
|
|
5
|
-
import {MatchDecorator, Decoration, ViewPlugin, WidgetType} from "@codemirror/view"
|
|
6
|
-
import {translate} from "@base/components/xform/utils/i18n";
|
|
7
|
-
|
|
8
|
-
class PlaceholderWidget extends WidgetType {
|
|
9
|
-
field;
|
|
10
|
-
text;
|
|
11
|
-
type;
|
|
12
|
-
|
|
13
|
-
constructor(text) {
|
|
14
|
-
super();
|
|
15
|
-
if (text) {
|
|
16
|
-
//type 仅用于区分颜色
|
|
17
|
-
const [field, mText, type] = text.split(".");
|
|
18
|
-
this.text = mText;
|
|
19
|
-
this.type = type;
|
|
20
|
-
this.field = field;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
eq(other) {
|
|
25
|
-
return this.text === other.text;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// 此处是我们的渲染方法
|
|
29
|
-
toDOM() {
|
|
30
|
-
let elt = document.createElement('span');
|
|
31
|
-
if (!this.text) return elt;
|
|
32
|
-
elt.className = this.type === "func" ? "cm-function" : "cm-field";
|
|
33
|
-
elt.textContent = this.text;
|
|
34
|
-
return elt;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
ignoreEvent() {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export const FORMULA_REG_EXP = /\{\{(\w+\.[^.]+\.\w+)}}/g
|
|
43
|
-
|
|
44
|
-
const placeholderMatcher = new MatchDecorator({
|
|
45
|
-
regexp: /\{\{(.+?)}}/g,
|
|
46
|
-
decoration: (match) =>
|
|
47
|
-
Decoration.replace({
|
|
48
|
-
widget: new PlaceholderWidget(match[1])
|
|
49
|
-
})
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
export const placeholders = ViewPlugin.fromClass(class {
|
|
54
|
-
placeholders
|
|
55
|
-
|
|
56
|
-
constructor(view) {
|
|
57
|
-
this.placeholders = placeholderMatcher.createDeco(view)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
update(update) {
|
|
61
|
-
this.placeholders = placeholderMatcher.updateDeco(update, this.placeholders)
|
|
62
|
-
}
|
|
63
|
-
}, {
|
|
64
|
-
decorations: instance => instance.placeholders,
|
|
65
|
-
provide: plugin => EditorView.atomicRanges.of(view => {
|
|
66
|
-
return view.plugin(plugin)?.placeholders || Decoration.none
|
|
67
|
-
})
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
// 背景样式
|
|
71
|
-
export const baseTheme = EditorView.baseTheme({
|
|
72
|
-
".cm-function": {
|
|
73
|
-
paddingLeft: "6px",
|
|
74
|
-
paddingRight: "6px",
|
|
75
|
-
paddingTop: "3px",
|
|
76
|
-
paddingBottom: "3px",
|
|
77
|
-
marginLeft: "3px",
|
|
78
|
-
marginRight: "3px",
|
|
79
|
-
backgroundColor: "#ffcdcc",
|
|
80
|
-
borderRadius: "4px",
|
|
81
|
-
},
|
|
82
|
-
".cm-field": {
|
|
83
|
-
paddingLeft: "6px",
|
|
84
|
-
paddingRight: "6px",
|
|
85
|
-
paddingTop: "3px",
|
|
86
|
-
paddingBottom: "3px",
|
|
87
|
-
marginLeft: "3px",
|
|
88
|
-
marginRight: "3px",
|
|
89
|
-
backgroundColor: "#f8e7a0",
|
|
90
|
-
borderRadius: "4px",
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
export function calculateFormula(VFR, DSV, formulaJs, formulaFieldRef, changedFieldRef) {
|
|
96
|
-
if (formulaFieldRef.tableParam) {
|
|
97
|
-
} else if (!!formulaFieldRef.subFormItemFlag && !!changedFieldRef.subFormItemFlag) {
|
|
98
|
-
/* 子表单字段变化,只能触发子表单同一行字段的计算公式重新计算!! */
|
|
99
|
-
if (changedFieldRef.subFormRowId !== formulaFieldRef.subFormRowId) {
|
|
100
|
-
return
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
let formula = formulaFieldRef.field.options.formula
|
|
105
|
-
formula = replaceFieldsAndFunctionsOfFormula(VFR, formulaFieldRef, changedFieldRef) //替换字段值
|
|
106
|
-
if (!formula) {
|
|
107
|
-
return
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
//替换formula-js函数
|
|
111
|
-
const matchResult = formula.match(/[A-Za-z]*/g)
|
|
112
|
-
let matchedList = []
|
|
113
|
-
if (!!matchResult) {
|
|
114
|
-
matchResult.forEach(mi => {
|
|
115
|
-
if (!!mi && (findCalFunStartIndex(mi) !== -1) && !matchedList.includes(mi)) {
|
|
116
|
-
const funcName = mi.toUpperCase()
|
|
117
|
-
formula = formula.replaceAll(mi, 'formulaJs.' + funcName)
|
|
118
|
-
matchedList.push(mi)
|
|
119
|
-
}
|
|
120
|
-
})
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const formulaValue = evalFn(formula, DSV, VFR, formulaJs)
|
|
124
|
-
if(formulaFieldRef)formulaFieldRef.setValue(formulaValue)
|
|
125
|
-
return formulaValue
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// ... existing code ...
|
|
129
|
-
export function baseCalculateFormula(that,formulaStr, row /* VFR, DSV, formulaJs, formulaFieldRef, changedFieldRef */) {
|
|
130
|
-
if(!formulaStr)return
|
|
131
|
-
let formula = formulaStr;
|
|
132
|
-
let VFR = that.getFormRef();
|
|
133
|
-
let DSV = that.getGlobalDsv()
|
|
134
|
-
let formulaJs = formulajs
|
|
135
|
-
let formulaFieldRef = that;
|
|
136
|
-
let changedFieldRef = arguments[5];
|
|
137
|
-
|
|
138
|
-
// 增强子表单字段变化时的计算范围控制
|
|
139
|
-
if (formulaFieldRef.tableParam) {
|
|
140
|
-
} else if (!!formulaFieldRef.subFormItemFlag && !!changedFieldRef?.subFormItemFlag) {
|
|
141
|
-
/* 子表单字段变化,只能触发子表单同一行字段的计算公式重新计算 */
|
|
142
|
-
if (changedFieldRef.subFormRowId !== formulaFieldRef.subFormRowId) {
|
|
143
|
-
return
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// 预处理:识别并标记聚合函数,记录它们的参数字段所属子表单
|
|
148
|
-
const aggregationFunctions = ['SUM', 'AVERAGE', 'MAX', 'MIN', 'SUMIF', 'SUMIFS'];
|
|
149
|
-
let functionCalls = [];
|
|
150
|
-
|
|
151
|
-
// 解析公式中的函数调用
|
|
152
|
-
let functionCallMatch;
|
|
153
|
-
const functionCallRegex = /([A-Z]+)\s*\(([^)]*)\)/g;
|
|
154
|
-
while ((functionCallMatch = functionCallRegex.exec(formulaStr)) !== null) {
|
|
155
|
-
const funcName = functionCallMatch[1].toUpperCase();
|
|
156
|
-
const params = functionCallMatch[2];
|
|
157
|
-
|
|
158
|
-
if (aggregationFunctions.includes(funcName)) {
|
|
159
|
-
functionCalls.push({
|
|
160
|
-
name: funcName,
|
|
161
|
-
params: params,
|
|
162
|
-
fullMatch: functionCallMatch[0],
|
|
163
|
-
start: functionCallMatch.index
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// 替换字段值,增加对子表单引用子表单场景的特殊处理
|
|
169
|
-
formula = baseReplaceFieldsAndFunctionsOfFormula(VFR, formulaFieldRef, formula, row, functionCalls)
|
|
170
|
-
|
|
171
|
-
if (!formula) {
|
|
172
|
-
return
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
//替换formula-js函数
|
|
176
|
-
const matchResult = formula.match(/[A-Za-z]*/g)
|
|
177
|
-
let matchedList = []
|
|
178
|
-
if (!!matchResult) {
|
|
179
|
-
matchResult.forEach(mi => {
|
|
180
|
-
if (!!mi && (findCalFunStartIndex(mi) !== -1) && !matchedList.includes(mi)) {
|
|
181
|
-
const funcName = mi.toUpperCase()
|
|
182
|
-
formula = formula.replaceAll(mi, 'formulaJs.' + funcName)
|
|
183
|
-
matchedList.push(mi)
|
|
184
|
-
}
|
|
185
|
-
})
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
try {
|
|
189
|
-
const formulaValue = evalFn(formula, DSV, VFR, formulaJs)
|
|
190
|
-
return formulaValue
|
|
191
|
-
} catch (error) {
|
|
192
|
-
console.error('公式计算错误:', error, '公式:', formula);
|
|
193
|
-
return null;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// 优化 baseReplaceFieldsAndFunctionsOfFormula 方法,增加对聚合函数的特殊处理
|
|
198
|
-
export function baseReplaceFieldsAndFunctionsOfFormula(VFR, formulaFieldRef, formula, row, functionCalls = []) {
|
|
199
|
-
// let formula = formulaFieldRef.field.options.formula
|
|
200
|
-
const matchResult = formula.match(FORMULA_REG_EXP)
|
|
201
|
-
if (!matchResult) {
|
|
202
|
-
return formula
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
let resultFormula = formula
|
|
206
|
-
let quitFlag = false
|
|
207
|
-
|
|
208
|
-
// 记录所有字段引用及其所属子表单
|
|
209
|
-
let fieldReferences = [];
|
|
210
|
-
|
|
211
|
-
matchResult.forEach(mi => {
|
|
212
|
-
const thirdPart = mi.split('.')[2]
|
|
213
|
-
const nodeType = thirdPart.substring(0, thirdPart.length - 2)
|
|
214
|
-
if (nodeType === 'func') {
|
|
215
|
-
const funcName = mi.split('.')[1]
|
|
216
|
-
resultFormula = resultFormula.replace(mi, funcName)
|
|
217
|
-
return
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const firstPart = mi.split('.')[0]
|
|
221
|
-
const fieldId = firstPart.substring(2, firstPart.length)
|
|
222
|
-
const fieldSchema = getFieldWidgetById(VFR.formJsonObj.widgetList, fieldId, false)
|
|
223
|
-
if (!!fieldSchema) {
|
|
224
|
-
let fieldRef = VFR.getWidgetRef(fieldSchema.options.name)
|
|
225
|
-
if (!!fieldRef) {
|
|
226
|
-
let fieldKeyName = getFieldKeyName(fieldSchema)
|
|
227
|
-
let value = fieldRef.formModel[fieldKeyName]??null;
|
|
228
|
-
resultFormula = resultFormula.replace(mi, value)
|
|
229
|
-
} else { //getWidgetRef找不到,则可能是子表单字段
|
|
230
|
-
const subFormNameOfField = VFR.getSubFormNameOfWidget(fieldSchema.options.name)
|
|
231
|
-
|
|
232
|
-
// 记录字段引用信息
|
|
233
|
-
fieldReferences.push({
|
|
234
|
-
placeholder: mi,
|
|
235
|
-
fieldName: fieldSchema.options.name,
|
|
236
|
-
subFormName: subFormNameOfField
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
if (!!formulaFieldRef.subFormItemFlag || formulaFieldRef.tableParam || row) {
|
|
240
|
-
/* 如果当前计算字段是子表单字段,要判断公式中的子表单字段是否和当前计算字段是否属于同一子表单!! */
|
|
241
|
-
// 判断是否是同一子表单
|
|
242
|
-
const isSameSubForm = subFormNameOfField === formulaFieldRef?.parentWidget?.options?.name ||
|
|
243
|
-
subFormNameOfField === formulaFieldRef.subFormName;
|
|
244
|
-
|
|
245
|
-
// 检查该字段是否在某个聚合函数的参数中
|
|
246
|
-
let isInAggregationParam = false;
|
|
247
|
-
functionCalls.forEach(call => {
|
|
248
|
-
if (call.params.includes(mi)) {
|
|
249
|
-
isInAggregationParam = true;
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
if (isSameSubForm && !isInAggregationParam) {
|
|
254
|
-
// 同一子表单且不在聚合函数参数中,使用当前行数据
|
|
255
|
-
if(row){
|
|
256
|
-
let fieldKeyName = getFieldKeyName(fieldSchema)
|
|
257
|
-
let value = row[fieldKeyName]??null;
|
|
258
|
-
resultFormula = resultFormula.replaceAll(mi, value)
|
|
259
|
-
}else if (subFormNameOfField === formulaFieldRef?.parentWidget?.options?.name) {
|
|
260
|
-
let subFormRowId = formulaFieldRef.tableParam.row._X_ROW_KEY
|
|
261
|
-
fieldRef = VFR.getWidgetRef(fieldSchema.options.name + '_' + subFormRowId)
|
|
262
|
-
if (!!fieldRef) {
|
|
263
|
-
let value = fieldRef.currentValue??null;
|
|
264
|
-
resultFormula = resultFormula.replaceAll(mi, value)
|
|
265
|
-
} else {
|
|
266
|
-
quitFlag = true
|
|
267
|
-
console.error('Field not found: ' + fieldSchema.options.label)
|
|
268
|
-
}
|
|
269
|
-
} else if (subFormNameOfField === formulaFieldRef.subFormName) {
|
|
270
|
-
fieldRef = VFR.getWidgetRef(fieldSchema.options.name + '@row' + formulaFieldRef.subFormRowId)
|
|
271
|
-
if (!!fieldRef) {
|
|
272
|
-
resultFormula = resultFormula.replaceAll(mi, fieldRef.currentValue)
|
|
273
|
-
} else {
|
|
274
|
-
quitFlag = true
|
|
275
|
-
console.error('Field not found: ' + fieldSchema.options.label)
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
} else {
|
|
279
|
-
// 不同子表单或在聚合函数参数中,使用全部明细行数据创建数组表达式
|
|
280
|
-
let dataTableRef = VFR.getWidgetRef(subFormNameOfField)
|
|
281
|
-
if (!dataTableRef) {
|
|
282
|
-
console.error('Subform not found: ' + subFormNameOfField);
|
|
283
|
-
quitFlag = true;
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const subFormValue = VFR.formDataModel[fieldKeyName(dataTableRef.widget)] || [];
|
|
288
|
-
const subFieldName = fieldKeyName(fieldSchema);
|
|
289
|
-
|
|
290
|
-
// 构建有效的数组表达式
|
|
291
|
-
let arrayExpr = '[';
|
|
292
|
-
subFormValue.forEach((vi, idx) => {
|
|
293
|
-
const val = vi[subFieldName] ?? null;
|
|
294
|
-
// 确保数值类型正确处理
|
|
295
|
-
if (val === null || val === undefined || val === '') {
|
|
296
|
-
arrayExpr += (idx === 0) ? '0' : ', 0';
|
|
297
|
-
} else if (typeof val === 'string' && !isNaN(Number(val))) {
|
|
298
|
-
arrayExpr += (idx === 0) ? Number(val) : ', ' + Number(val);
|
|
299
|
-
} else if (typeof val === 'number') {
|
|
300
|
-
arrayExpr += (idx === 0) ? val : ', ' + val;
|
|
301
|
-
} else {
|
|
302
|
-
arrayExpr += (idx === 0) ? '0' : ', 0';
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
arrayExpr += ']';
|
|
306
|
-
|
|
307
|
-
resultFormula = resultFormula.replaceAll(mi, arrayExpr);
|
|
308
|
-
}
|
|
309
|
-
} else {
|
|
310
|
-
/* 在主表单字段的计算公式中使用子表单字段,应将子表单所有记录同字段的值代入!! */
|
|
311
|
-
let dataTableRef = VFR.getWidgetRef(subFormNameOfField)
|
|
312
|
-
const subFormValue = VFR.formDataModel[fieldKeyName(dataTableRef.widget)]
|
|
313
|
-
let allSubFieldValues = ''
|
|
314
|
-
const subFieldName = fieldKeyName(fieldSchema)
|
|
315
|
-
|
|
316
|
-
// 对于聚合函数,创建数组表达式
|
|
317
|
-
let isInAggregationParam = false;
|
|
318
|
-
functionCalls.forEach(call => {
|
|
319
|
-
if (call.params.includes(mi)) {
|
|
320
|
-
isInAggregationParam = true;
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
if (isInAggregationParam) {
|
|
325
|
-
let arrayExpr = '[';
|
|
326
|
-
subFormValue.forEach((vi, idx) => {
|
|
327
|
-
const val = vi[subFieldName] ?? 0;
|
|
328
|
-
arrayExpr += (idx === 0) ? val : ', ' + val;
|
|
329
|
-
});
|
|
330
|
-
arrayExpr += ']';
|
|
331
|
-
resultFormula = resultFormula.replaceAll(mi, arrayExpr);
|
|
332
|
-
} else {
|
|
333
|
-
// 非聚合函数,使用逗号分隔的字符串
|
|
334
|
-
subFormValue.forEach((vi, idx) => {
|
|
335
|
-
let val = vi[subFieldName]??null
|
|
336
|
-
allSubFieldValues = (idx === 0) ? val : allSubFieldValues + ', ' + val
|
|
337
|
-
})
|
|
338
|
-
resultFormula = resultFormula.replaceAll(mi, allSubFieldValues)
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
})
|
|
344
|
-
|
|
345
|
-
return quitFlag ? null : resultFormula
|
|
346
|
-
}
|
|
347
|
-
// ... existing code ...
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
function getFieldKeyName(widget) {
|
|
351
|
-
let o = widget.options.name;
|
|
352
|
-
return (widget.options.keyNameEnabled && widget.options.keyName) || o;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
function funOtherHanlde(){
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
export function calculateFormula2(formulaStr, data, that) {
|
|
360
|
-
if(!formulaStr)return
|
|
361
|
-
let formula = formulaStr;
|
|
362
|
-
let VFR = that.getFormRef();
|
|
363
|
-
let DSV = that.getGlobalDsv()
|
|
364
|
-
let formulaJs = formulajs
|
|
365
|
-
|
|
366
|
-
if(data){
|
|
367
|
-
for(let key in data){
|
|
368
|
-
formula = formula.replaceAll(`[${key}]`,(data[key] || 0))
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
//替换formula-js函数
|
|
373
|
-
const matchResult = formula.match(/[A-Za-z]*/g)
|
|
374
|
-
let matchedList = []
|
|
375
|
-
if (!!matchResult) {
|
|
376
|
-
matchResult.forEach(mi => {
|
|
377
|
-
if (!!mi && (findCalFunStartIndex(mi) !== -1) && !matchedList.includes(mi)) {
|
|
378
|
-
const funcName = mi.toUpperCase()
|
|
379
|
-
formula = formula.replaceAll(mi, 'formulaJs.' + funcName)
|
|
380
|
-
matchedList.push(mi)
|
|
381
|
-
}
|
|
382
|
-
})
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
const formulaValue = evalFn(formula, DSV, VFR, formulaJs)
|
|
386
|
-
return formulaValue
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* 判断字段是否用在计算公式中
|
|
391
|
-
* @param fieldName
|
|
392
|
-
* @param formula
|
|
393
|
-
* @param VFR
|
|
394
|
-
*/
|
|
395
|
-
export function fieldIsUsedInFormula(fieldName, formula, VFR, fieldTarget) {
|
|
396
|
-
const matchResult = formula.match(FORMULA_REG_EXP)
|
|
397
|
-
if (!matchResult) {
|
|
398
|
-
return false
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
let foundResult = false
|
|
402
|
-
matchResult.forEach(mi => {
|
|
403
|
-
const thirdPart = mi.split('.')[2]
|
|
404
|
-
const nodeType = thirdPart.substring(0, thirdPart.length - 2)
|
|
405
|
-
if (nodeType === 'func') {
|
|
406
|
-
return
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const firstPart = mi.split('.')[0]
|
|
410
|
-
const fieldId = firstPart.substring(2, firstPart.length)
|
|
411
|
-
let fieldSchema = getFieldWidgetById(VFR.formJsonObj.widgetList, fieldId, false)
|
|
412
|
-
if (!fieldSchema) {
|
|
413
|
-
console.error('The field used by formula not found: ', fieldId)
|
|
414
|
-
console.error('The formula is: ', formula)
|
|
415
|
-
}
|
|
416
|
-
if (fieldSchema && (fieldSchema.options.name === fieldName)) {
|
|
417
|
-
foundResult = true
|
|
418
|
-
}
|
|
419
|
-
})
|
|
420
|
-
|
|
421
|
-
return foundResult
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* 替换计算公式中的字段值
|
|
427
|
-
* @param VFR
|
|
428
|
-
* @param formulaFieldRef
|
|
429
|
-
* @returns {*}
|
|
430
|
-
*/
|
|
431
|
-
export function replaceFieldsAndFunctionsOfFormula(VFR, formulaFieldRef) {
|
|
432
|
-
let formula = formulaFieldRef.field.options.formula
|
|
433
|
-
const matchResult = formula.match(FORMULA_REG_EXP)
|
|
434
|
-
if (!matchResult) {
|
|
435
|
-
return formula
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
let resultFormula = formula
|
|
439
|
-
let quitFlag = false
|
|
440
|
-
matchResult.forEach(mi => {
|
|
441
|
-
const thirdPart = mi.split('.')[2]
|
|
442
|
-
const nodeType = thirdPart.substring(0, thirdPart.length - 2)
|
|
443
|
-
if (nodeType === 'func') {
|
|
444
|
-
const funcName = mi.split('.')[1]
|
|
445
|
-
resultFormula = resultFormula.replace(mi, funcName)
|
|
446
|
-
return
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
const firstPart = mi.split('.')[0]
|
|
450
|
-
const fieldId = firstPart.substring(2, firstPart.length)
|
|
451
|
-
const fieldSchema = getFieldWidgetById(VFR.formJsonObj.widgetList, fieldId, false)
|
|
452
|
-
if (!!fieldSchema) {
|
|
453
|
-
let fieldRef = VFR.getWidgetRef(fieldSchema.options.name)
|
|
454
|
-
if (!!fieldRef) {
|
|
455
|
-
//是否要考虑字符串值的替换??
|
|
456
|
-
resultFormula = resultFormula.replace(mi, fieldRef.currentValue)
|
|
457
|
-
} else { //getWidgetRef找不到,则可能是子表单字段
|
|
458
|
-
const subFormNameOfField = VFR.getSubFormNameOfWidget(fieldSchema.options.name)
|
|
459
|
-
if (!!formulaFieldRef.subFormItemFlag || formulaFieldRef.tableParam) {
|
|
460
|
-
/* 如果当前计算字段是子表单字段,要判断公式中的子表单字段是否和当前计算字段是否属于同一子表单!! */
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
if (subFormNameOfField === formulaFieldRef?.parentWidget?.options?.name) {
|
|
464
|
-
let subFormRowId = formulaFieldRef.tableParam.row._X_ROW_KEY
|
|
465
|
-
fieldRef = VFR.getWidgetRef(fieldSchema.options.name + '_' + subFormRowId)
|
|
466
|
-
if (!!fieldRef) {
|
|
467
|
-
resultFormula = resultFormula.replaceAll(mi, fieldRef.currentValue)
|
|
468
|
-
} else {
|
|
469
|
-
quitFlag = true
|
|
470
|
-
console.error('Field not found: ' + fieldSchema.options.label)
|
|
471
|
-
}
|
|
472
|
-
} else if (subFormNameOfField === formulaFieldRef.subFormName) {
|
|
473
|
-
fieldRef = VFR.getWidgetRef(fieldSchema.options.name + '@row' + formulaFieldRef.subFormRowId)
|
|
474
|
-
if (!!fieldRef) {
|
|
475
|
-
resultFormula = resultFormula.replaceAll(mi, fieldRef.currentValue)
|
|
476
|
-
} else {
|
|
477
|
-
quitFlag = true
|
|
478
|
-
console.error('Field not found: ' + fieldSchema.options.label)
|
|
479
|
-
}
|
|
480
|
-
} else {
|
|
481
|
-
console.error('Invalid formula!')
|
|
482
|
-
}
|
|
483
|
-
} else {
|
|
484
|
-
/* 在主表单字段的计算公式中使用子表单字段,应将子表单所有记录同字段的值代入!! */
|
|
485
|
-
// const subFormValue = VFR.formDataModel[subFormNameOfField]
|
|
486
|
-
let dataTableRef = VFR.getWidgetRef(subFormNameOfField)
|
|
487
|
-
const subFormValue = VFR.formDataModel[fieldKeyName(dataTableRef.widget)]
|
|
488
|
-
|
|
489
|
-
let allSubFieldValues = ''
|
|
490
|
-
// const subFieldName = fieldSchema.options.name
|
|
491
|
-
const subFieldName = fieldKeyName(fieldSchema)
|
|
492
|
-
subFormValue.forEach((vi, idx) => {
|
|
493
|
-
allSubFieldValues = (idx === 0) ? vi[subFieldName] : allSubFieldValues + ', ' + vi[subFieldName]
|
|
494
|
-
})
|
|
495
|
-
resultFormula = resultFormula.replaceAll(mi, allSubFieldValues)
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
})
|
|
500
|
-
|
|
501
|
-
return quitFlag ? null : resultFormula
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
function fieldKeyName(widget) {
|
|
505
|
-
let o = widget.options.name;
|
|
506
|
-
return (
|
|
507
|
-
(widget.options.keyNameEnabled && widget.options.keyName) || o
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* 获取字段值
|
|
513
|
-
*/
|
|
514
|
-
function getWidgetValue(VFR, formula, widgetName) {
|
|
515
|
-
const sIndex = formula.indexOf("(");
|
|
516
|
-
const func = formula.substring(0, sIndex);
|
|
517
|
-
|
|
518
|
-
const funcType = formulas.find(item => {
|
|
519
|
-
if (item.flist.some(fItem => {
|
|
520
|
-
return fItem.fName === func
|
|
521
|
-
})) {
|
|
522
|
-
return item;
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
if (translate(funcType.fClass) === "数学类型") {
|
|
526
|
-
return Number(VFR.getWidgetRef(widgetName).getValue());
|
|
527
|
-
} else {
|
|
528
|
-
return VFR.getWidgetRef(widgetName).getValue() + '';
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
// 查找公式中的函数是否在枚举中
|
|
533
|
-
export function hasFun(funName) {
|
|
534
|
-
for (let i = 0; i < FORMULA_JS_FUNCTIONS.length; i++) {
|
|
535
|
-
if (funName === FORMULA_JS_FUNCTIONS[i]) {
|
|
536
|
-
return true
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
return false
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
export function findCalFunStartIndex(formula) {
|
|
543
|
-
let startIndex = -1
|
|
544
|
-
for (let i = 0; i < FORMULA_JS_FUNCTIONS.length; i++) {
|
|
545
|
-
let index = formula.indexOf(FORMULA_JS_FUNCTIONS[i])
|
|
546
|
-
if (index !== -1) {
|
|
547
|
-
return index
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
return startIndex
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
/**
|
|
554
|
-
* 当删除子表单行时,重新计算相关联的计算字段
|
|
555
|
-
*/
|
|
556
|
-
export function recalculateFormulaOnSubFormRowDelete(VFR, DSV, formulaJs, formulaFieldRef) {
|
|
557
|
-
if (!!formulaFieldRef.subFormItemFlag) {
|
|
558
|
-
return
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
let formula = formulaFieldRef.field.options.formula
|
|
562
|
-
formula = replaceFieldsAndFunctionsOfFormula(VFR, formulaFieldRef) //替换字段值
|
|
563
|
-
if (!formula) {
|
|
564
|
-
return
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
//替换formula-js函数
|
|
568
|
-
const matchResult = formula.match(/[A-Za-z]*/g)
|
|
569
|
-
let matchedList = []
|
|
570
|
-
if (!!matchResult) {
|
|
571
|
-
matchResult.forEach(mi => {
|
|
572
|
-
if (!!mi && (findCalFunStartIndex(mi) !== -1) && !matchedList.includes(mi)) {
|
|
573
|
-
const funcName = mi.toUpperCase()
|
|
574
|
-
formula = formula.replaceAll(mi, 'formulaJs.' + funcName)
|
|
575
|
-
matchedList.push(mi)
|
|
576
|
-
}
|
|
577
|
-
})
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
console.log('formula: ', formula)
|
|
581
|
-
const formulaValue = evalFn(formula, DSV, VFR, formulaJs)
|
|
582
|
-
formulaFieldRef.setValue(formulaValue)
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
export function broadcastFormulaRecalculateEvent(subFormRef) {
|
|
586
|
-
let fieldNames = []
|
|
587
|
-
let getFieldNamesFn = (fw) => {
|
|
588
|
-
fieldNames.push(fw.options.name)
|
|
589
|
-
}
|
|
590
|
-
traverseFieldWidgetsOfContainer(subFormRef.widget, getFieldNamesFn)
|
|
591
|
-
fieldNames.map(fieldName => {
|
|
592
|
-
subFormRef.getFormRef().broadcast('FieldWidget', 'calculate-formula-sfRowDeleted', [null, fieldName])
|
|
593
|
-
})
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
//--------------------- 以下为公式计算的API方法 start ------------------//
|
|
597
|
-
// 日期格式化
|
|
598
|
-
export function dateFormat(date, fmt) {
|
|
599
|
-
date = new Date(date)
|
|
600
|
-
let a = ['日', '一', '二', '三', '四', '五', '六']
|
|
601
|
-
let o = {
|
|
602
|
-
'M+': date.getMonth() + 1, // 月份
|
|
603
|
-
'd+': date.getDate(), // 日
|
|
604
|
-
'h+': date.getHours(), // 小时
|
|
605
|
-
'm+': date.getMinutes(), // 分
|
|
606
|
-
's+': date.getSeconds(), // 秒
|
|
607
|
-
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
|
|
608
|
-
'S': date.getMilliseconds(), // 毫秒
|
|
609
|
-
'w': date.getDay(), // 周
|
|
610
|
-
'W': a[date.getDay()], // 大写周
|
|
611
|
-
'T': 'T'
|
|
612
|
-
}
|
|
613
|
-
if (/(y+)/.test(fmt)) {
|
|
614
|
-
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
|
|
615
|
-
}
|
|
616
|
-
for (let k in o) {
|
|
617
|
-
if (new RegExp('(' + k + ')').test(fmt)) {
|
|
618
|
-
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
return fmt
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
//月份加减
|
|
625
|
-
export function addMonths(yearMonthDay, monthNum) {
|
|
626
|
-
let arr = yearMonthDay.split('-'); //2020-08-19或2020-08
|
|
627
|
-
let year = parseInt(arr[0]);
|
|
628
|
-
let month = parseInt(arr[1]);
|
|
629
|
-
month = month + monthNum;
|
|
630
|
-
if (month > 12) { //月份加
|
|
631
|
-
let yearNum = parseInt((month - 1) / 12);
|
|
632
|
-
month = month % 12 === 0 ? 12 : month % 12;
|
|
633
|
-
year += yearNum;
|
|
634
|
-
} else if (month <= 0) { //月份减
|
|
635
|
-
month = Math.abs(month);
|
|
636
|
-
let yearNum = parseInt((month + 12) / 12);
|
|
637
|
-
year -= yearNum;
|
|
638
|
-
}
|
|
639
|
-
month = month < 10 ? "0" + month : month;
|
|
640
|
-
return year + "-" + month;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
// 获取当前日期 yyyy-MM-dd
|
|
644
|
-
export function TODAY() {
|
|
645
|
-
// return this.FUNAPI.DODAY().toLocaleDateString().replaceAll("/","-")
|
|
646
|
-
return dateFormat(new Date(), "yyyy-MM-dd")
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
// 获取当前时间 yyyy-MM-dd hh:mm:ss
|
|
650
|
-
export function NOW() {
|
|
651
|
-
// return this.FUNAPI.NOW().toLocaleDateString().replaceAll("/","-")
|
|
652
|
-
return dateFormat(new Date(), "yyyy-MM-dd hh:mm:ss")
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
/** 加减日期年
|
|
656
|
-
* @param {Object} date 日期
|
|
657
|
-
* @param {Object} month 加减的年
|
|
658
|
-
*/
|
|
659
|
-
export function EYEAR(date, year) {
|
|
660
|
-
try {
|
|
661
|
-
let myDate = new Date(date)
|
|
662
|
-
let newDate = myDate.setYear(myDate.getFullYear() + year)
|
|
663
|
-
return dateFormat(new Date(newDate), "yyyy-MM-dd")
|
|
664
|
-
} catch (e) {
|
|
665
|
-
//TODO handle the exception
|
|
666
|
-
//console.log(this.i18nt('designer.hint.formulaDateError'), date)
|
|
667
|
-
//console.error(this.i18nt('designer.hint.formulaDateErrorMsg'), e);
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
/** 加减日期月份
|
|
672
|
-
* @param {Object} date 日期
|
|
673
|
-
* @param {Object} month 加减的月份
|
|
674
|
-
*/
|
|
675
|
-
export function EMONTH(date, month) {
|
|
676
|
-
try {
|
|
677
|
-
let myDate = new Date(date)
|
|
678
|
-
let newDate = myDate.setMonth(myDate.getMonth() + month)
|
|
679
|
-
return dateFormat(new Date(newDate), "yyyy-MM-dd")
|
|
680
|
-
} catch (e) {
|
|
681
|
-
//TODO handle the exception
|
|
682
|
-
// console.log(this.i18nt('designer.hint.formulaDateError'), date)
|
|
683
|
-
// console.error(this.i18nt('designer.hint.formulaDateErrorMsg'), e);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
/** 加减日期天数
|
|
688
|
-
* @param {Object} date
|
|
689
|
-
* @param {Object} day 加减天数
|
|
690
|
-
*/
|
|
691
|
-
export function EDAY(date, day) {
|
|
692
|
-
try {
|
|
693
|
-
let myDate = new Date(date)
|
|
694
|
-
let newDate = myDate.setDate(myDate.getDate() + day)
|
|
695
|
-
return dateFormat(new Date(newDate), "yyyy-MM-dd")
|
|
696
|
-
} catch (e) {
|
|
697
|
-
//TODO handle the exception
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
const FORMULA_JS_FUNCTIONS = [
|
|
702
|
-
"INT",
|
|
703
|
-
"SUM",
|
|
704
|
-
"AVERAGE",
|
|
705
|
-
"MAX",
|
|
706
|
-
"MIN",
|
|
707
|
-
"ABS",
|
|
708
|
-
"ROUND",
|
|
709
|
-
"CEILING",
|
|
710
|
-
"LOG",
|
|
711
|
-
"MOD",
|
|
712
|
-
"POWER",
|
|
713
|
-
"AND",
|
|
714
|
-
"IF",
|
|
715
|
-
"IFS",
|
|
716
|
-
"IFERROR",
|
|
717
|
-
"IFNA",
|
|
718
|
-
"NOT",
|
|
719
|
-
"OR",
|
|
720
|
-
"SWITCH",
|
|
721
|
-
"XOR",
|
|
722
|
-
"YEAR",
|
|
723
|
-
"MONTH",
|
|
724
|
-
"DAY",
|
|
725
|
-
"TODAY",
|
|
726
|
-
"NOW",
|
|
727
|
-
"EMONTH",
|
|
728
|
-
"EDAY",
|
|
729
|
-
"FIND",
|
|
730
|
-
"LEFT",
|
|
731
|
-
"RIGHT",
|
|
732
|
-
"LEN",
|
|
733
|
-
"LOWER",
|
|
734
|
-
"UPPER",
|
|
735
|
-
"MID",
|
|
736
|
-
"TRIM",
|
|
737
|
-
];
|
|
738
|
-
|
|
739
|
-
export const formulas = [
|
|
740
|
-
{
|
|
741
|
-
fClass: "designer.hint.formulaFunctionMaths",
|
|
742
|
-
flist: [
|
|
743
|
-
{
|
|
744
|
-
fName: "INT",
|
|
745
|
-
fType: "designer.hint.formulaNumber",
|
|
746
|
-
fIntro: "designer.hint.formulaINT",
|
|
747
|
-
},
|
|
748
|
-
{
|
|
749
|
-
fName: "SUM",
|
|
750
|
-
fType: "designer.hint.formulaNumber",
|
|
751
|
-
fIntro: "designer.hint.formulaSUM",
|
|
752
|
-
},
|
|
753
|
-
{
|
|
754
|
-
fName: "SUMIF",
|
|
755
|
-
fType: "designer.hint.formulaNumber",
|
|
756
|
-
fIntro: "designer.hint.formulaSUMIF",
|
|
757
|
-
},
|
|
758
|
-
{
|
|
759
|
-
fName: "SUMIFS",
|
|
760
|
-
fType: "designer.hint.formulaNumber",
|
|
761
|
-
fIntro: "designer.hint.formulaSUMIFS",
|
|
762
|
-
},
|
|
763
|
-
{
|
|
764
|
-
fName: "AVERAGE",
|
|
765
|
-
fType: "designer.hint.formulaNumber",
|
|
766
|
-
fIntro: "designer.hint.formulaAVERAGE",
|
|
767
|
-
},
|
|
768
|
-
{
|
|
769
|
-
fName: "MAX",
|
|
770
|
-
fType: "designer.hint.formulaNumber",
|
|
771
|
-
fIntro: "designer.hint.formulaMAX",
|
|
772
|
-
},
|
|
773
|
-
{
|
|
774
|
-
fName: "MIN",
|
|
775
|
-
fType: "designer.hint.formulaNumber",
|
|
776
|
-
fIntro: "designer.hint.formulaMIN",
|
|
777
|
-
},
|
|
778
|
-
{
|
|
779
|
-
fName: "ABS",
|
|
780
|
-
fType: "designer.hint.formulaNumber",
|
|
781
|
-
fIntro: "designer.hint.formulaABS",
|
|
782
|
-
},
|
|
783
|
-
{
|
|
784
|
-
fName: "ROUND",
|
|
785
|
-
fType: "designer.hint.formulaNumber",
|
|
786
|
-
fIntro: "designer.hint.formulaROUND",
|
|
787
|
-
},
|
|
788
|
-
{
|
|
789
|
-
fName: "CEILING",
|
|
790
|
-
fType: "designer.hint.formulaNumber",
|
|
791
|
-
fIntro: "designer.hint.formulaCEILING",
|
|
792
|
-
},
|
|
793
|
-
{
|
|
794
|
-
fName: "LOG",
|
|
795
|
-
fType: "designer.hint.formulaNumber",
|
|
796
|
-
fIntro: "designer.hint.formulaLOG",
|
|
797
|
-
},
|
|
798
|
-
{
|
|
799
|
-
fName: "MOD",
|
|
800
|
-
fType: "designer.hint.formulaNumber",
|
|
801
|
-
fIntro: "designer.hint.formulaMOD",
|
|
802
|
-
},
|
|
803
|
-
{
|
|
804
|
-
fName: "POWER",
|
|
805
|
-
fType: "designer.hint.formulaNumber",
|
|
806
|
-
fIntro: "designer.hint.formulaPOWER",
|
|
807
|
-
},
|
|
808
|
-
],
|
|
809
|
-
},
|
|
810
|
-
{
|
|
811
|
-
fClass: "designer.hint.formulaFunctionLogic",
|
|
812
|
-
flist: [
|
|
813
|
-
{
|
|
814
|
-
fName: "AND",
|
|
815
|
-
fType: "designer.hint.formulaObject",
|
|
816
|
-
fIntro: "designer.hint.formulaAND",
|
|
817
|
-
},
|
|
818
|
-
{
|
|
819
|
-
fName: "IF",
|
|
820
|
-
fType: "designer.hint.formulaObject",
|
|
821
|
-
fIntro: "designer.hint.formulaIF",
|
|
822
|
-
},
|
|
823
|
-
{
|
|
824
|
-
fName: "IFS",
|
|
825
|
-
fType: "designer.hint.formulaObject",
|
|
826
|
-
fIntro: "designer.hint.formulaIFS",
|
|
827
|
-
},
|
|
828
|
-
{
|
|
829
|
-
fName: "IFERROR",
|
|
830
|
-
fType: "designer.hint.formulaObject",
|
|
831
|
-
fIntro: "designer.hint.formulaIFERROR",
|
|
832
|
-
},
|
|
833
|
-
{
|
|
834
|
-
fName: "IFNA",
|
|
835
|
-
fType: "designer.hint.formulaObject",
|
|
836
|
-
fIntro: "designer.hint.formulaIFNA",
|
|
837
|
-
},
|
|
838
|
-
{
|
|
839
|
-
fName: "NOT",
|
|
840
|
-
fType: "designer.hint.formulaObject",
|
|
841
|
-
fIntro: "designer.hint.formulaNOT",
|
|
842
|
-
},
|
|
843
|
-
{
|
|
844
|
-
fName: "OR",
|
|
845
|
-
fType: "designer.hint.formulaObject",
|
|
846
|
-
fIntro: "designer.hint.formulaOR",
|
|
847
|
-
},
|
|
848
|
-
{
|
|
849
|
-
fName: "SWITCH",
|
|
850
|
-
fType: "designer.hint.formulaObject",
|
|
851
|
-
fIntro: "designer.hint.formulaSWITCH",
|
|
852
|
-
},
|
|
853
|
-
{
|
|
854
|
-
fName: "XOR",
|
|
855
|
-
fType: "designer.hint.formulaObject",
|
|
856
|
-
fIntro: "designer.hint.formulaXOR",
|
|
857
|
-
},
|
|
858
|
-
],
|
|
859
|
-
},
|
|
860
|
-
{
|
|
861
|
-
fClass: "designer.hint.formulaFunctionTime",
|
|
862
|
-
flist: [
|
|
863
|
-
{
|
|
864
|
-
fName: "YEAR",
|
|
865
|
-
fType: "designer.hint.formulaDate",
|
|
866
|
-
fIntro: "designer.hint.formulaYEAR",
|
|
867
|
-
},
|
|
868
|
-
{
|
|
869
|
-
fName: "MONTH",
|
|
870
|
-
fType: "designer.hint.formulaDate",
|
|
871
|
-
fIntro: "designer.hint.formulaMONTH",
|
|
872
|
-
},
|
|
873
|
-
{
|
|
874
|
-
fName: "DAY",
|
|
875
|
-
fType: "designer.hint.formulaDate",
|
|
876
|
-
fIntro: "designer.hint.formulaDAY",
|
|
877
|
-
},
|
|
878
|
-
{
|
|
879
|
-
fName: "TODAY",
|
|
880
|
-
fType: "designer.hint.formulaDate",
|
|
881
|
-
fIntro: "designer.hint.formulaTODAY",
|
|
882
|
-
},
|
|
883
|
-
{
|
|
884
|
-
fName: "NOW",
|
|
885
|
-
fType: "designer.hint.formulaDate",
|
|
886
|
-
fIntro: "designer.hint.formulaNOW",
|
|
887
|
-
},
|
|
888
|
-
{
|
|
889
|
-
fName: "EMONTH",
|
|
890
|
-
fType: "designer.hint.formulaDate",
|
|
891
|
-
fIntro: "designer.hint.formulaEMONTH",
|
|
892
|
-
},
|
|
893
|
-
{
|
|
894
|
-
fName: "EDAY",
|
|
895
|
-
fType: "designer.hint.formulaDate",
|
|
896
|
-
fIntro: "designer.hint.formulaEDAY",
|
|
897
|
-
},
|
|
898
|
-
],
|
|
899
|
-
},
|
|
900
|
-
{
|
|
901
|
-
fClass: "designer.hint.formulaFunctionString",
|
|
902
|
-
flist: [
|
|
903
|
-
{
|
|
904
|
-
fName: "FIND",
|
|
905
|
-
fType: "designer.hint.formulaChar",
|
|
906
|
-
fIntro: "designer.hint.formulaFIND",
|
|
907
|
-
},
|
|
908
|
-
{
|
|
909
|
-
fName: "LEFT",
|
|
910
|
-
fType: "designer.hint.formulaChar",
|
|
911
|
-
fIntro: "designer.hint.formulaLEFT",
|
|
912
|
-
},
|
|
913
|
-
{
|
|
914
|
-
fName: "RIGHT",
|
|
915
|
-
fType: "designer.hint.formulaChar",
|
|
916
|
-
fIntro: "designer.hint.formulaRIGHT",
|
|
917
|
-
},
|
|
918
|
-
{
|
|
919
|
-
fName: "LEN",
|
|
920
|
-
fType: "designer.hint.formulaChar",
|
|
921
|
-
fIntro: "designer.hint.formulaLEN",
|
|
922
|
-
},
|
|
923
|
-
{
|
|
924
|
-
fName: "LOWER",
|
|
925
|
-
fType: "designer.hint.formulaChar",
|
|
926
|
-
fIntro: "designer.hint.formulaLOWER",
|
|
927
|
-
},
|
|
928
|
-
{
|
|
929
|
-
fName: "UPPER",
|
|
930
|
-
fType: "designer.hint.formulaChar",
|
|
931
|
-
fIntro: "designer.hint.formulaUPPER",
|
|
932
|
-
},
|
|
933
|
-
{
|
|
934
|
-
fName: "MID",
|
|
935
|
-
fType: "designer.hint.formulaChar",
|
|
936
|
-
fIntro: "designer.hint.formulaMID",
|
|
937
|
-
},
|
|
938
|
-
{
|
|
939
|
-
fName: "TRIM",
|
|
940
|
-
fType: "designer.hint.formulaChar",
|
|
941
|
-
fIntro: "designer.hint.formulaTRIM",
|
|
942
|
-
},
|
|
943
|
-
],
|
|
944
|
-
},
|
|
945
|
-
];
|