You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5767 lines
206 KiB
5767 lines
206 KiB
import { replaceHtml, getObjType, chatatABC, ABCatNum, luckysheetfontformat } from '../utils/util';
|
|
import { getSheetIndex, getRangetxt, getluckysheetfile } from '../methods/get';
|
|
import { setluckysheetfile } from '../methods/set';
|
|
import { luckyColor } from '../controllers/constant';
|
|
import sheetmanage from '../controllers/sheetmanage';
|
|
import menuButton from '../controllers/menuButton';
|
|
import server from '../controllers/server';
|
|
import luckysheetFreezen from '../controllers/freezen';
|
|
import {checkProtectionLocked,checkProtectionCellHidden} from '../controllers/protection';
|
|
import dataVerificationCtrl from '../controllers/dataVerificationCtrl';
|
|
import { seletedHighlistByindex, luckysheet_count_show } from '../controllers/select';
|
|
import { isRealNum, isRealNull, valueIsError, isEditMode } from './validate';
|
|
import { isdatetime, isdatatype } from './datecontroll';
|
|
import { getCellTextSplitArr,getCellTextInfo } from '../global/getRowlen';
|
|
import { getcellvalue,getcellFormula,getInlineStringNoStyle, getOrigincell } from './getdata';
|
|
import { setcellvalue } from './setdata';
|
|
import { genarate, valueShowEs } from './format';
|
|
import editor from './editor';
|
|
import tooltip from './tooltip';
|
|
import { rowLocation, colLocation, colLocationByIndex, mouseposition } from './location';
|
|
import { luckysheetRangeLast } from './cursorPos';
|
|
import { jfrefreshgrid } from './refresh';
|
|
import { isInlineStringCell,convertSpanToShareString } from '../controllers/inlineString';
|
|
// import luckysheet_function from '../function/luckysheet_function';
|
|
// import functionlist from '../function/functionlist';
|
|
import { luckysheet_compareWith, luckysheet_getarraydata, luckysheet_getcelldata, luckysheet_parseData, luckysheet_getValue, luckysheet_indirect_check, luckysheet_indirect_check_return, luckysheet_offset_check,luckysheet_calcADPMM,luckysheet_getSpecialReference } from '../function/func';
|
|
import Store from '../store';
|
|
import locale from '../locale/locale';
|
|
import json from './json';
|
|
import method from './method';
|
|
|
|
const luckysheetformula = {
|
|
error: {
|
|
v: "#VALUE!", //错误的参数或运算符
|
|
n: "#NAME?", //公式名称错误
|
|
na: "#N/A", //函数或公式中没有可用数值
|
|
r: "#REF!", //删除了由其他公式引用的单元格
|
|
d: "#DIV/0!", //除数是0或空单元格
|
|
nm: "#NUM!", //当公式或函数中某个数字有问题时
|
|
nl: "#NULL!", //交叉运算符(空格)使用不正确
|
|
sp: "#SPILL!" //数组范围有其它值
|
|
},
|
|
errorInfo: function(err) {
|
|
return err;
|
|
},
|
|
errorParamCheck: function(thisp, data, i) {
|
|
let type, require;
|
|
let _locale = locale();
|
|
let locale_formulaMore = _locale.formulaMore;
|
|
if(i < thisp.length){
|
|
type = thisp[i].type;
|
|
require = thisp[i].require;
|
|
}
|
|
else{
|
|
type = thisp[thisp.length - 1].type;
|
|
require = thisp[thisp.length - 1].require;
|
|
}
|
|
|
|
if(require == "o" && (data == null || data == "")){
|
|
return [true, locale_formulaMore.tipSuccessText];
|
|
}
|
|
|
|
if(type.indexOf("all") > -1){
|
|
return [true, locale_formulaMore.tipSuccessText];
|
|
}
|
|
else{
|
|
if(type.indexOf("range") > -1 && (getObjType(data) == "object" || getObjType(data) == "array")){
|
|
return [true, locale_formulaMore.tipSuccessText];
|
|
}
|
|
|
|
if(type.indexOf("number") > -1 && (isRealNum(data) || getObjType(data) == "boolean")){
|
|
return [true, locale_formulaMore.tipSuccessText];
|
|
}
|
|
|
|
if(type.indexOf("string") > -1 && getObjType(data) == "string"){
|
|
return [true, locale_formulaMore.tipSuccessText];
|
|
}
|
|
|
|
if(type.indexOf("date") > -1 && isdatetime(data)){
|
|
return [true, locale_formulaMore.tipSuccessText];
|
|
}
|
|
|
|
return [false, locale_formulaMore.tipParamErrorText];
|
|
}
|
|
},
|
|
getPureValueByData: function(data){
|
|
if(data.length == 0){
|
|
return [];
|
|
}
|
|
|
|
let output = [];
|
|
|
|
if(getObjType(data) == "array"){
|
|
if(getObjType(data[0]) == "array"){
|
|
for(let r = 0; r < data.length; r++){
|
|
let row = [];
|
|
|
|
for(let c = 0; c < data[0].length; c++){
|
|
let cell = data[r][c];
|
|
|
|
if(getObjType(cell) == "object"){
|
|
row.push(cell.v);
|
|
}
|
|
else{
|
|
row.push(cell);
|
|
}
|
|
}
|
|
|
|
output.push(row);
|
|
}
|
|
}
|
|
else{
|
|
for(let i = 0; i < data.length; i++){
|
|
let cell = data[i];
|
|
|
|
if(getObjType(cell) == "object"){
|
|
output.push(cell.v);
|
|
}
|
|
else{
|
|
output.push(cell);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
let cell = data;
|
|
|
|
if(getObjType(cell) == "object"){
|
|
output.push(cell.v);
|
|
}
|
|
else{
|
|
output.push(cell);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
},
|
|
//sparklines添加
|
|
readCellDataToOneArray: function(rangeValue){
|
|
let _this = this;
|
|
|
|
if(rangeValue == null){
|
|
return [];
|
|
}
|
|
|
|
if(getObjType(rangeValue) != "object"){
|
|
return [rangeValue];
|
|
}
|
|
|
|
let dataformat = [];
|
|
let data = [];
|
|
|
|
if(rangeValue != null && rangeValue.data != null){
|
|
data = rangeValue.data;
|
|
}
|
|
else if(rangeValue != null && !isRealNull(rangeValue.v)){
|
|
return [rangeValue.v];
|
|
}
|
|
else{
|
|
return [];
|
|
}
|
|
|
|
//适配excel的动态数组格式,{1,2,3,4,5}或者{{1,2,3},{4,5,6},{7,8,9}}
|
|
if(getObjType(data) == "array"){
|
|
data = _this.getPureValueByData(data);
|
|
}
|
|
else if(getObjType(data) == "object"){
|
|
data = data.v;
|
|
|
|
return [data];
|
|
}
|
|
else{
|
|
if(/\{.*?\}/.test(data)){
|
|
data = data.replace(/\{/g, "[").replace(/\}/g, "]");
|
|
}
|
|
|
|
data = eval('('+ data +')');
|
|
}
|
|
|
|
//把二维数组转换为一维数组,sparklines要求数据格式为一维数组
|
|
//let dataformat = [];
|
|
if(getObjType(data[0]) == "array"){
|
|
for(let i = 0; i < data.length; i++){
|
|
dataformat = dataformat.concat(data[i]);
|
|
}
|
|
}
|
|
else{
|
|
dataformat = data;
|
|
}
|
|
|
|
return dataformat;
|
|
},
|
|
//sparklines添加
|
|
//获得函数里某个参数的值,使用此函数需要在函数中执行luckysheet_getValue方法
|
|
getValueByFuncData: function(value, arg){
|
|
if(value == null){
|
|
return null;
|
|
}
|
|
|
|
let _this = this;
|
|
|
|
if(getObjType(value) == "array"){
|
|
if(arg == "avg"){
|
|
return luckysheet_function.AVERAGE.f.apply(luckysheet_function.AVERAGE, value);
|
|
}
|
|
else if(arg == "sum"){
|
|
return luckysheet_function.SUM.f.apply(luckysheet_function.SUM, value);
|
|
}
|
|
else{
|
|
if(getObjType(value[0]) == "object"){
|
|
return luckysheet.mask.getValueByFormat(value[0]);
|
|
}
|
|
else{
|
|
return value[0];
|
|
}
|
|
}
|
|
}
|
|
else if(getObjType(value) == "object"){
|
|
return luckysheet.mask.getValueByFormat(value);
|
|
}
|
|
else{
|
|
return value;
|
|
}
|
|
},
|
|
//sparklines添加
|
|
sparklinesColorMap:function(args, len){
|
|
let _this = this;
|
|
let colorLists = null;
|
|
|
|
if(len == null){
|
|
len = 5;
|
|
}
|
|
|
|
let index = 0;
|
|
|
|
if(args.length > len){
|
|
for(let i = len; i < args.length; i++){
|
|
let colorMap = args[i];
|
|
let colorListArray = _this.readCellDataToOneArray(colorMap);
|
|
|
|
for(let a = 0; a < colorListArray.length; a++){
|
|
let ca = colorListArray[a];
|
|
|
|
if(ca.indexOf(":") > -1){
|
|
if(!colorLists){
|
|
colorLists = {};
|
|
}
|
|
|
|
let calist = ca.split(":");
|
|
|
|
if(calist.length == 2){
|
|
colorLists[calist[0]] = calist[1];
|
|
}
|
|
else if(calist.length > 1){
|
|
colorLists[calist[0] + ":" + calist[1]] = calist[2];
|
|
}
|
|
}
|
|
else{
|
|
if(!colorLists){
|
|
colorLists = [];
|
|
}
|
|
|
|
colorLists.push(ca);
|
|
}
|
|
}
|
|
|
|
index++;
|
|
}
|
|
}
|
|
|
|
return colorLists;
|
|
},
|
|
//sparklines添加
|
|
colorList: ["#2ec7c9", "#fc5c5c", "#5ab1ef", "#ffb980", "#d87a80", "#8d98b3", "#e5cf0d", "#97b552", "#95706d","#dc69aa","#07a2a4","#9a7fd1","#588dd5","#f5994e","#c05050","#59678c","#c9ab00","#7eb00a","#6f5553","#c14089"],
|
|
classlist: {
|
|
"province": {
|
|
11: "北京",
|
|
12: "天津",
|
|
13: "河北",
|
|
14: "山西",
|
|
15: "内蒙古",
|
|
21: "辽宁",
|
|
22: "吉林",
|
|
23: "黑龙江",
|
|
31: "上海",
|
|
32: "江苏",
|
|
33: "浙江",
|
|
34: "安徽",
|
|
35: "福建",
|
|
36: "江西",
|
|
37: "山东",
|
|
41: "河南",
|
|
42: "湖北",
|
|
43: "湖南",
|
|
44: "广东",
|
|
45: "广西",
|
|
46: "海南",
|
|
50: "重庆",
|
|
51: "四川",
|
|
52: "贵州",
|
|
53: "云南",
|
|
54: "西藏",
|
|
61: "陕西",
|
|
62: "甘肃",
|
|
63: "青海",
|
|
64: "宁夏",
|
|
65: "新疆",
|
|
71: "台湾",
|
|
81: "香港",
|
|
82: "澳门",
|
|
91: "国外"
|
|
}
|
|
},
|
|
oldvalue: null,
|
|
dontupdate: function() {
|
|
let _this = this;
|
|
Store.luckysheetCellUpdate.length = 0; //clear array
|
|
$("#luckysheet-functionbox-cell, #luckysheet-rich-text-editor").html(_this.oldvalue);
|
|
_this.cancelNormalSelected();
|
|
if (_this.rangetosheet != Store.currentSheetIndex) {
|
|
sheetmanage.changeSheetExec(_this.rangetosheet);
|
|
}
|
|
},
|
|
fucntionboxshow: function(r, c) {
|
|
|
|
if(!checkProtectionCellHidden(r, c, Store.currentSheetIndex)){
|
|
$("#luckysheet-functionbox-cell").html("");
|
|
return;
|
|
}
|
|
|
|
let _this = this;
|
|
|
|
let d = Store.flowdata;
|
|
let value = "";
|
|
// && d[r][c].v != null
|
|
if (d[r] != null && d[r][c] != null) {
|
|
let cell = d[r][c];
|
|
|
|
if(isInlineStringCell(cell)){
|
|
value = getInlineStringNoStyle(r, c);
|
|
}
|
|
else if(cell.f != null){
|
|
value = getcellvalue(r, c, d, "f");
|
|
}
|
|
else{
|
|
value = valueShowEs(r, c, d);
|
|
}
|
|
}
|
|
|
|
_this.oldvalue = value;
|
|
$("#luckysheet-functionbox-cell").html(value);
|
|
},
|
|
//获得某个单元格或区域的偏移一定距离后的单元格( Sheet1!B6:C8 格式)
|
|
cellOffset: function(range,rows,cols,height,width){// 参数:range or cell , rows,cols,height,width
|
|
let startCell = range.startCell;
|
|
let rowl = range.rowl;
|
|
let coll = range.coll;
|
|
let startCellRow = parseInt(startCell.replace(/[^0-9]/g, ""));
|
|
let startCellCol = ABCatNum(startCell.replace(/[^A-Za-z]/g, ""));
|
|
|
|
let row = [],col = [],offsetRange;
|
|
row[0] = startCellRow + rows;
|
|
col[0] = startCellCol + cols;
|
|
|
|
row[1] = row[0] + height - 1;
|
|
col[1] = col[0] + width - 1;
|
|
|
|
col[0] = chatatABC(col[0]);
|
|
col[1] = chatatABC(col[1]);
|
|
|
|
let cellF = col[0] + row[0];
|
|
let cellL = col[1] + row[1];
|
|
|
|
if(cellF == cellL){
|
|
offsetRange = range.sheetName + "!"+ cellF;
|
|
}
|
|
else{
|
|
offsetRange = range.sheetName + "!"+ cellF + ":" + cellL;
|
|
}
|
|
|
|
return offsetRange;
|
|
},
|
|
parseDatetoNum: function(date){ //函数中获取到时间格式或者数字形式统一转化为数字进行运算
|
|
let _this = this;
|
|
|
|
if(typeof(date) == "object" && typeof date.v == "number"){
|
|
date = date.v;
|
|
}
|
|
else if(isdatatype(date) == "num"){
|
|
date = parseFloat(date);
|
|
}
|
|
else if(isdatatype(date) == "date"){
|
|
date = genarate(date)[2];
|
|
}
|
|
else{
|
|
return _this.error.v;
|
|
}
|
|
|
|
return date;
|
|
},
|
|
//获取一维数组
|
|
getRangeArray: function(range){
|
|
let rangeNow = [];
|
|
let fmt = "General";
|
|
|
|
if(range.length == 1){ //一行
|
|
for(let c = 0; c < range[0].length; c++){
|
|
if(range[0][c] != null && range[0][c].v){
|
|
rangeNow.push(range[0][c].v);
|
|
let f = range[0][c].ct.fa;
|
|
fmt = (fmt == "General") ? f : fmt;
|
|
}
|
|
else{
|
|
//若单元格为null或为空,此处推入null(待考虑是否使用"null")
|
|
rangeNow.push(null);
|
|
}
|
|
}
|
|
}
|
|
else if(range[0].length == 1){ //一列
|
|
for(let r = 0; r < range.length; r++){
|
|
if(range[r][0] != null && range[r][0].v){
|
|
rangeNow.push(range[r][0].v);
|
|
let f = range[r][0].ct.fa;
|
|
fmt = (fmt == "General") ? f : fmt;
|
|
}
|
|
else{
|
|
rangeNow.push(null);
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
for(let r = 0; r < range.length; r++){
|
|
for(let c = 0; c < range[r].length; c++){
|
|
if(range[r][c] != null && range[r][c].v){
|
|
rangeNow.push(range[r][c].v);
|
|
let f = range[r][c].ct.fa;
|
|
fmt = (fmt == "General") ? f : fmt;
|
|
}
|
|
else{
|
|
rangeNow.push(null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
range = rangeNow;
|
|
|
|
return [range, fmt];
|
|
},
|
|
//获取二维数组:qksheet格式[[{v,m,ct}] ==> [1]
|
|
getRangeArrayTwo: function(range){
|
|
let data = $.extend(true, [], range);
|
|
|
|
if(data.length == 1){ //一行
|
|
for(let c = 0; c < data[0].length; c++){
|
|
if(data[0][c] instanceof Object){
|
|
if(data[0][c] != null && data[0][c] instanceof Object && !!data[0][c].m){
|
|
data[0][c] = data[0][c].m;
|
|
}
|
|
else{
|
|
if(data[0][c] != null && data[0][c] instanceof Object && !!data[0][c].v){
|
|
data[0][c] = data[0][c].v;
|
|
}
|
|
else{
|
|
data[0][c] = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(data[0].length == 1){ //一列
|
|
for(let r = 0; r < data.length; r++){
|
|
if(data[r][0] instanceof Object){
|
|
if(data[r][0] != null && data[r][0] instanceof Object && !!data[r][0].m){
|
|
data[r][0] = data[r][0].m;
|
|
}
|
|
else{
|
|
if(data[r][0] != null && data[r][0] instanceof Object && !!data[r][0].v){
|
|
data[r][0] = data[r][0].v;
|
|
}
|
|
else{
|
|
data[r][0] = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
for(let r = 0; r < data.length; r++){
|
|
for(let c = 0; c < data[r].length; c++){
|
|
if(data[r][c] instanceof Object){
|
|
if(data[r][c] != null && data[r][c] instanceof Object && !!data[r][c].m){
|
|
data[r][c] = data[r][c].m;
|
|
}
|
|
else{
|
|
if(data[r][c] != null && data[r][c] instanceof Object && !!data[r][c].v){
|
|
data[r][c] = data[r][c].v;
|
|
}
|
|
else{
|
|
data[r][c] = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return data;
|
|
},
|
|
isWildcard: function(a, b){ //正则匹配通配符: * ? ~* ~?,a目标参数,b通配符
|
|
let _this = this;
|
|
|
|
a = a.toString();
|
|
b = b.toString();
|
|
|
|
if(_this.isCompareOperator(b).flag){
|
|
b = _this.isCompareOperator(b).num;
|
|
}
|
|
|
|
let str = "";
|
|
for(let i = 0; i < b.length; i++){
|
|
let v = b.charAt(i);
|
|
|
|
if(v == "*" ){
|
|
str += ".*";
|
|
}
|
|
else if(v == "?"){
|
|
str += ".";
|
|
}
|
|
else if(v == "~"){
|
|
if(b.charAt(i+1) == "*"){
|
|
str += "\\*";
|
|
i++;
|
|
}
|
|
else if(b.charAt(i+1) == "?"){
|
|
str += "\\?";
|
|
i++;
|
|
}
|
|
else{
|
|
str += "~";
|
|
}
|
|
}
|
|
else{
|
|
str += v;
|
|
}
|
|
}
|
|
|
|
let reg = new RegExp("^" + str + "$", "g");
|
|
|
|
return !!a.match(reg);
|
|
},
|
|
isCompareOperator: function(str){ //判断前一个或者两个字符是否是比较运算符
|
|
str = str.toString();
|
|
let ope = ""; //存放比较运算符
|
|
let num = ""; //截取比较运算符之后的数字用于实际比较
|
|
let strOne = str.substr(0,1);
|
|
let strTwo = str.substr(1,1);
|
|
let flag = false;
|
|
let ret;
|
|
|
|
if(strOne == ">"){
|
|
if(strTwo == "="){
|
|
ope = str.substr(0,2);
|
|
num = str.substr(2);
|
|
flag = true;
|
|
}
|
|
else if(strTwo != "="){
|
|
ope = str.substr(0,1);
|
|
num = str.substr(1);
|
|
flag = true;
|
|
}
|
|
}
|
|
else if(strOne == "<"){
|
|
if(strTwo == "=" || strTwo == ">"){
|
|
ope = str.substr(0,2);
|
|
num = str.substr(2);
|
|
flag = true;
|
|
}
|
|
else if(strTwo != "=" && strTwo != ">"){
|
|
ope = str.substr(0,1);
|
|
num = str.substr(1);
|
|
flag = true;
|
|
}
|
|
}
|
|
else if(strOne == "=" && strTwo != "="){
|
|
ope = str.substr(0,1);
|
|
num = str.substr(1);
|
|
flag = true;
|
|
}
|
|
|
|
ret = { "flag": flag, "ope": ope, "num": num };
|
|
|
|
return ret;
|
|
},
|
|
acompareb: function(a, b){ //a 与 b比较,b可为含比较符,通配符
|
|
let _this = this;
|
|
let flag = false;
|
|
|
|
if(isRealNum(b)){
|
|
flag = luckysheet_compareWith(a, "==", b);
|
|
}
|
|
else if(typeof(b) == "string"){ //条件输入字符串,如:">233"
|
|
if(b.indexOf("*") != -1 || b.indexOf("?") != -1){ // 正则匹配:输入通配符:"黑*","白?",以及"白?黑*~*"
|
|
//通配符函数
|
|
return _this.isWildcard(a, b);
|
|
}
|
|
else if(_this.isCompareOperator(b).flag){ //"黑糖"
|
|
let ope = _this.isCompareOperator(b).ope;
|
|
let num = _this.isCompareOperator(b).num;
|
|
flag = luckysheet_compareWith(a, ope, num);
|
|
}
|
|
else{
|
|
flag = luckysheet_compareWith(a, "==", b);
|
|
}
|
|
}
|
|
|
|
return flag;
|
|
},
|
|
compareParams: function(fp, sp, sym){ //比较两个字符串或者数字的大小,支持比较对象,暂不支持数组
|
|
let flag = false;
|
|
|
|
//判断a和b的数据类型
|
|
let classNameA = toString.call(fp),
|
|
classNameB = toString.call(sp);
|
|
|
|
if(sym == ">" && fp > sp){
|
|
flag = true;
|
|
}
|
|
else if(sym == ">=" && fp >= sp){
|
|
flag = true;
|
|
}
|
|
else if(sym == "<" && fp < sp){
|
|
flag = true;
|
|
}
|
|
else if(sym == "<=" && fp <= sp){
|
|
flag = true;
|
|
}
|
|
else if(sym == "=" && fp == sp){
|
|
flag = true;
|
|
}
|
|
else if(sym == "<>" && fp != sp){
|
|
flag = true;
|
|
}
|
|
|
|
//对象类型比较相等
|
|
if(classNameA == '[object Object]' && classNameB == '[object Object]'){
|
|
//获取a和b的属性长度
|
|
let propsA = Object.getOwnPropertyNames(fp),
|
|
propsB = Object.getOwnPropertyNames(sp);
|
|
|
|
if(propsA.length != propsB.length){
|
|
return false;
|
|
}
|
|
|
|
for(let i = 0; i < propsA.length; i++){
|
|
let propName=propsA[i];
|
|
//如果对应属性对应值不相等,则返回false
|
|
if(fp[propName] !== sp[propName]){
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//数组类型
|
|
if(classNameA == '[object Array]' && classNameB == '[object Array]'){
|
|
if(fp.toString() == sp.toString()){
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return flag;
|
|
},
|
|
parseDecimal: function(num){
|
|
num = parseFloat(num);
|
|
let d = parseInt(num, 10);
|
|
|
|
if(d == 0){
|
|
return num;
|
|
}
|
|
|
|
num = num % d;
|
|
return num;
|
|
},
|
|
getcellrange: function(txt, formulaIndex) {
|
|
if(txt==null || txt.length==0){
|
|
return;
|
|
}
|
|
|
|
let sheettxt = "",
|
|
rangetxt = "",
|
|
sheetIndex = null,
|
|
sheetdata = null;
|
|
|
|
let luckysheetfile = getluckysheetfile();
|
|
|
|
if (txt.indexOf("!") > -1) {
|
|
if(txt in this.cellTextToIndexList){
|
|
return this.cellTextToIndexList[txt];
|
|
}
|
|
|
|
let val = txt.split("!");
|
|
sheettxt = val[0];
|
|
rangetxt = val[1];
|
|
|
|
sheettxt = sheettxt.replace(/\\'/g, "'");
|
|
if(sheettxt.substr(0,1)=="'" && sheettxt.substr(sheettxt.length-1,1)=="'"){
|
|
sheettxt = sheettxt.substring(1,sheettxt.length-1);
|
|
}
|
|
for (let i in luckysheetfile) {
|
|
if (sheettxt == luckysheetfile[i].name) {
|
|
sheetIndex = luckysheetfile[i].index;
|
|
sheetdata = luckysheetfile[i].data;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
let i = formulaIndex;
|
|
if(i==null){
|
|
i = Store.currentSheetIndex;
|
|
}
|
|
if(txt+"_" + i in this.cellTextToIndexList){
|
|
return this.cellTextToIndexList[txt+"_" + i];
|
|
}
|
|
let index = getSheetIndex(i);
|
|
sheettxt = luckysheetfile[index].name;
|
|
sheetIndex = luckysheetfile[index].index;
|
|
sheetdata = Store.flowdata;
|
|
rangetxt = txt;
|
|
}
|
|
|
|
if (rangetxt.indexOf(":") == -1) {
|
|
let row = parseInt(rangetxt.replace(/[^0-9]/g, "")) - 1;
|
|
let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, ""));
|
|
|
|
if (!isNaN(row) && !isNaN(col)) {
|
|
let item = {
|
|
"row": [row, row],
|
|
"column": [col, col],
|
|
"sheetIndex": sheetIndex
|
|
};
|
|
this.addToCellIndexList(txt,item);
|
|
return item;
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
else {
|
|
rangetxt = rangetxt.split(":");
|
|
let row = [],col = [];
|
|
row[0] = parseInt(rangetxt[0].replace(/[^0-9]/g, "")) - 1;
|
|
row[1] = parseInt(rangetxt[1].replace(/[^0-9]/g, "")) - 1;
|
|
if (isNaN(row[0])) {
|
|
row[0] = 0;
|
|
}
|
|
if (isNaN(row[1])) {
|
|
row[1] = sheetdata.length - 1;
|
|
}
|
|
if (row[0] > row[1]) {
|
|
return null;
|
|
}
|
|
col[0] = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, ""));
|
|
col[1] = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, ""));
|
|
if (isNaN(col[0])) {
|
|
col[0] = 0;
|
|
}
|
|
if (isNaN(col[1])) {
|
|
col[1] = sheetdata[0].length - 1;
|
|
}
|
|
if (col[0] > col[1]) {
|
|
return null;
|
|
}
|
|
|
|
let item = {
|
|
"row": row,
|
|
"column": col,
|
|
"sheetIndex": sheetIndex
|
|
};
|
|
this.addToCellIndexList(txt,item);
|
|
return item;
|
|
}
|
|
},
|
|
rangeHightlightHTML: '<div id="luckysheet-formula-functionrange-highlight-${id}" rangeindex="${id}" class="luckysheet-selection-highlight luckysheet-formula-functionrange-highlight"><div data-type="top" class="luckysheet-selection-copy-top luckysheet-copy"></div><div data-type="right" class="luckysheet-selection-copy-right luckysheet-copy"></div><div data-type="bottom" class="luckysheet-selection-copy-bottom luckysheet-copy"></div><div data-type="left" class="luckysheet-selection-copy-left luckysheet-copy"></div><div class="luckysheet-selection-copy-hc"></div><div data-type="lt" class="luckysheet-selection-highlight-topleft luckysheet-highlight"></div><div data-type="rt" class="luckysheet-selection-highlight-topright luckysheet-highlight"></div><div data-type="lb" class="luckysheet-selection-highlight-bottomleft luckysheet-highlight"></div><div data-type="rb" class="luckysheet-selection-highlight-bottomright luckysheet-highlight"></div></div>',
|
|
createRangeHightlight: function() {
|
|
let _this = this;
|
|
|
|
let $span = $("#luckysheet-rich-text-editor").find("span.luckysheet-formula-functionrange-cell");
|
|
$("#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight").remove();
|
|
|
|
$span.each(function() {
|
|
let rangeindex = $(this).attr("rangeindex"),
|
|
range = $(this).text();
|
|
|
|
$("#luckysheet-formula-functionrange").append(replaceHtml(_this.rangeHightlightHTML, {
|
|
"id": rangeindex
|
|
}));
|
|
|
|
let cellrange = _this.getcellrange(range);
|
|
let rangeid = "luckysheet-formula-functionrange-highlight-" + rangeindex;
|
|
|
|
if (cellrange == null) {
|
|
|
|
}
|
|
else if (cellrange.sheetIndex == Store.currentSheetIndex || (cellrange.sheetIndex == -1 && _this.rangetosheet == Store.currentSheetIndex)) {
|
|
$("#" + rangeid).data("range", cellrange)
|
|
.find(".luckysheet-copy")
|
|
.css({ "background": luckyColor[rangeindex] })
|
|
.end()
|
|
.find(".luckysheet-highlight")
|
|
.css({ "background": luckyColor[rangeindex] })
|
|
.end()
|
|
.find(".luckysheet-selection-copy-hc")
|
|
.css({ "background": luckyColor[rangeindex] });
|
|
|
|
seletedHighlistByindex(rangeid, cellrange.row[0], cellrange.row[1], cellrange.column[0], cellrange.column[1]);
|
|
}
|
|
});
|
|
|
|
$("#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight").show();
|
|
},
|
|
searchHTML: '<div id="luckysheet-formula-search-c" class="luckysheet-formula-search-c"></div>',
|
|
helpHTML: '<div id="luckysheet-formula-help-c" class="luckysheet-formula-help-c"> <div class="luckysheet-formula-help-close" title="${helpClose}"><i class="fa fa-times" aria-hidden="true"></i></div> <div class="luckysheet-formula-help-collapse" title="${helpCollapse}"><i class="fa fa-angle-up" aria-hidden="true"></i></div> <div class="luckysheet-formula-help-title"><div class="luckysheet-formula-help-title-formula"> <span class="luckysheet-arguments-help-function-name">SUM</span> <span class="luckysheet-arguments-paren">(</span> <span class="luckysheet-arguments-parameter-holder"> <span class="luckysheet-arguments-help-parameter luckysheet-arguments-help-parameter-active" dir="auto">A2:A100</span>, <span class="luckysheet-arguments-help-parameter" dir="auto">101</span> </span> <span class="luckysheet-arguments-paren">)</span> </div></div> <div class="luckysheet-formula-help-content"> <div class="luckysheet-formula-help-content-example"> <div class="luckysheet-arguments-help-section-title">${helpExample}</div> <div class="luckysheet-arguments-help-formula"> <span class="luckysheet-arguments-help-function-name">SUM</span> <span class="luckysheet-arguments-paren">(</span> <span class="luckysheet-arguments-parameter-holder"> <span class="luckysheet-arguments-help-parameter luckysheet-arguments-help-parameter-active" dir="auto">A2:A100</span>, <span class="luckysheet-arguments-help-parameter" dir="auto">101</span> </span> <span class="luckysheet-arguments-paren">)</span> </div> </div> <div class="luckysheet-formula-help-content-detail"> <div class="luckysheet-arguments-help-section"> <div class="luckysheet-arguments-help-section-title luckysheet-arguments-help-parameter-name">${helpAbstract}</div> <span class="luckysheet-arguments-help-parameter-content">${helpAbstract}</span> </div> </div> <div class="luckysheet-formula-help-content-param"> ${param} </div> </div> <div class="luckysheet-formula-help-foot"></div></div>',
|
|
getrangeseleciton: function() {
|
|
let currSelection = window.getSelection();
|
|
let anchor = $(currSelection.anchorNode);
|
|
let anchorOffset = currSelection.anchorOffset;
|
|
|
|
if (anchor.parent().is("span") && anchorOffset != 0) {
|
|
let txt = $.trim(anchor.text()),
|
|
lasttxt = "";
|
|
|
|
if (txt.length == 0 && anchor.parent().prev().length > 0) {
|
|
let ahr = anchor.parent().prev();
|
|
txt = $.trim(ahr.text());
|
|
lasttxt = txt.substr(txt.length - 1, 1);
|
|
return ahr;
|
|
}
|
|
else {
|
|
lasttxt = txt.substr(anchorOffset - 1, 1);
|
|
return anchor.parent();
|
|
}
|
|
}
|
|
else if (anchor.is("#luckysheet-rich-text-editor") || anchor.is("#luckysheet-functionbox-cell")) {
|
|
let txt = $.trim(anchor.find("span").last().text());
|
|
|
|
if (txt.length == 0 && anchor.find("span").length > 1) {
|
|
let ahr = anchor.find("span");
|
|
txt = $.trim(ahr.eq(ahr.length - 2).text());
|
|
return ahr;
|
|
}
|
|
else {
|
|
return anchor.find("span").last();
|
|
}
|
|
}
|
|
else if (anchor.parent().is("#luckysheet-rich-text-editor") || anchor.parent().is("#luckysheet-functionbox-cell") || anchorOffset == 0) {
|
|
if (anchorOffset == 0) {
|
|
anchor = anchor.parent();
|
|
}
|
|
|
|
if (anchor.prev().length > 0) {
|
|
let txt = $.trim(anchor.prev().text());
|
|
let lasttxt = txt.substr(txt.length - 1, 1);
|
|
return anchor.prev();
|
|
}
|
|
}
|
|
|
|
return null;
|
|
},
|
|
searchFunctionPosition: function($menu, $editor, x, y, isparam) {
|
|
let winH = $(window).height(),
|
|
winW = $(window).width();
|
|
let menuW = $menu.outerWidth(),
|
|
menuH = $menu.outerHeight();
|
|
|
|
if (isparam == null) {
|
|
isparam = false;
|
|
}
|
|
|
|
let left = x;
|
|
if (x + menuW > winW) {
|
|
left = x - menuW + $editor.outerWidth();
|
|
}
|
|
else {
|
|
left = x;
|
|
}
|
|
|
|
let top = y;
|
|
if (y + menuH > winH) {
|
|
top = y - menuH;
|
|
}
|
|
else {
|
|
top = y + $editor.outerHeight();
|
|
if (!isparam) {
|
|
$menu.html($menu.find(".luckysheet-formula-search-item").get().reverse());
|
|
}
|
|
}
|
|
|
|
if (top < 0) {
|
|
top = 0;
|
|
}
|
|
if (left < 0) {
|
|
left = 0;
|
|
}
|
|
|
|
$menu.css({
|
|
"top": top,
|
|
"left": left
|
|
}).show();
|
|
},
|
|
searchFunctionCell: null,
|
|
searchFunction: function($editer) {
|
|
let _this = this;
|
|
let functionlist = Store.functionlist;
|
|
|
|
let $cell = _this.getrangeseleciton();
|
|
_this.searchFunctionCell = $cell;
|
|
|
|
|
|
|
|
if ($cell == null || $editer == null) {
|
|
return;
|
|
}
|
|
let inputContent = $editer.text();
|
|
let searchtxt = $cell.text().toUpperCase();
|
|
let reg = /^[a-zA-Z]|[a-zA-Z_]+$/;
|
|
|
|
if (!reg.test(searchtxt) || inputContent.substr(0, 1)!="=") {
|
|
return;
|
|
}
|
|
|
|
let result = {
|
|
"f": [],
|
|
"s": [],
|
|
"t": []
|
|
},
|
|
result_i = 0;
|
|
|
|
for (let i = 0; i < functionlist.length; i++) {
|
|
let item = functionlist[i],
|
|
n = item.n;
|
|
|
|
if (n == searchtxt) {
|
|
result.f.unshift(item);
|
|
result_i++;
|
|
}
|
|
else if (n.substr(0, searchtxt.length) == searchtxt) {
|
|
result.s.unshift(item);
|
|
result_i++;
|
|
}
|
|
else if (n.indexOf(searchtxt) > -1) {
|
|
result.t.unshift(item);
|
|
result_i++;
|
|
}
|
|
|
|
if (result_i >= 10) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
let list = result.t.concat(result.s.concat(result.f));
|
|
if (list.length <= 0) {
|
|
return;
|
|
}
|
|
|
|
let listHTML = _this.searchFunctionHTML(list);
|
|
$("#luckysheet-formula-search-c").html(listHTML).show();
|
|
$("#luckysheet-formula-help-c").hide();
|
|
|
|
let $c = $editer.parent(),
|
|
offset = $c.offset();
|
|
_this.searchFunctionPosition($("#luckysheet-formula-search-c"), $c, offset.left, offset.top);
|
|
},
|
|
searchFunctionEnter: function($obj) {
|
|
let _this = this;
|
|
|
|
let functxt = $obj.data("func");
|
|
_this.searchFunctionCell.text(functxt).after('<span dir="auto" class="luckysheet-formula-text-color">(</span>');
|
|
_this.setCaretPosition(_this.searchFunctionCell.next().get(0), 0, 1);
|
|
$("#luckysheet-formula-search-c").hide();
|
|
_this.helpFunctionExe(_this.searchFunctionCell.closest("div"), _this.searchFunctionCell.next());
|
|
},
|
|
searchFunctionHTML: function(list) {
|
|
let _this = this;
|
|
|
|
if ($("#luckysheet-formula-search-c").length == 0) {
|
|
$("body").append(_this.searchHTML);
|
|
$("#luckysheet-formula-search-c").on("mouseover", ".luckysheet-formula-search-item", function() {
|
|
$("#luckysheet-formula-search-c").find(".luckysheet-formula-search-item").removeClass("luckysheet-formula-search-item-active");
|
|
$(this).addClass("luckysheet-formula-search-item-active");
|
|
}).on("mouseout", ".luckysheet-formula-search-item", function() {
|
|
|
|
}).on("click", ".luckysheet-formula-search-item", function() {
|
|
if (_this.searchFunctionCell == null) {
|
|
return;
|
|
}
|
|
_this.searchFunctionEnter($(this));
|
|
});
|
|
}
|
|
|
|
let itemHTML = '<div data-func="${n}" class="luckysheet-formula-search-item ${class}"><div class="luckysheet-formula-search-func">${n}</div><div class="luckysheet-formula-search-detail">${a}</div></div>';
|
|
let retHTML = "";
|
|
|
|
for (let i = 0; i < list.length; i++) {
|
|
let item = list[i];
|
|
|
|
if (i == list.length - 1) {
|
|
retHTML += replaceHtml(itemHTML, {
|
|
"class": "luckysheet-formula-search-item-active",
|
|
"n": item.n,
|
|
"a": item.a
|
|
});
|
|
}
|
|
else {
|
|
retHTML += replaceHtml(itemHTML, {
|
|
"class": "",
|
|
"n": item.n,
|
|
"a": item.a
|
|
});
|
|
}
|
|
}
|
|
|
|
return retHTML;
|
|
},
|
|
functionlistPosition: {},
|
|
helpFunction: function($editer, funcname, paramIndex) {
|
|
let _this = this;
|
|
let functionlist = Store.functionlist;
|
|
|
|
let $func = functionlist[_this.functionlistPosition[$.trim(funcname).toUpperCase()]];
|
|
if ($func == null) {
|
|
return;
|
|
}
|
|
|
|
let _locale = locale();
|
|
let locale_formulaMore = _locale.formulaMore;
|
|
|
|
$("#luckysheet-formula-help-c .luckysheet-arguments-help-function-name").html($func.n);
|
|
$("#luckysheet-formula-help-c .luckysheet-arguments-help-parameter-content").html($func.d);
|
|
|
|
let helpformula = '<span class="luckysheet-arguments-help-function-name">${name}</span> <span class="luckysheet-arguments-paren">(</span> <span class="luckysheet-arguments-parameter-holder"> ${param} </span> <span class="luckysheet-arguments-paren">)</span>';
|
|
let helpformulaItem = '<span class="luckysheet-arguments-help-parameter" dir="auto">${param}</span>';
|
|
let helpformulaArg = '<div class="luckysheet-arguments-help-section"><div class="luckysheet-arguments-help-section-title">${param}</div><span class="luckysheet-arguments-help-parameter-content">${content}</span></div>';
|
|
|
|
//"n": "AVERAGE",
|
|
//"t": "1",
|
|
//"d": "返回数据集的算术平均值,对文本忽略不计。",
|
|
//"a": "返回数据集的算术平均值",
|
|
//"p": [{ "name": "数值1", "example": "A2:A100", "detail": "计算平均值时用到的第一个数值或范围。", "require": "m", "repeat": "n", "type": "rangenumber" },
|
|
// { "name": "数值2", "example": "B2:B100", "detail": "计算平均值时用到的其他数值或范围。", "require": "o", "repeat": "y", "type": "rangenumber" }
|
|
//]
|
|
let fht = "",
|
|
ahf = "",
|
|
fhcp = "";
|
|
|
|
for (let i = 0; i < $func.p.length; i++) {
|
|
let paramitem = $func.p[i];
|
|
let name = paramitem.name,
|
|
nameli = paramitem.name;
|
|
|
|
if (paramitem.repeat == "y") {
|
|
name += ", ...";
|
|
nameli += '<span class="luckysheet-arguments-help-argument-info">...-'+locale_formulaMore.allowRepeatText+'</span>';
|
|
}
|
|
if (paramitem.require == "o") {
|
|
name = "[" + name + "]";
|
|
nameli += '<span class="luckysheet-arguments-help-argument-info">-['+locale_formulaMore.allowOptionText+']</span>';
|
|
}
|
|
|
|
fht += '<span class="luckysheet-arguments-help-parameter" dir="auto">' + name + '</span>, ';
|
|
ahf += '<span class="luckysheet-arguments-help-parameter" dir="auto">' + paramitem.example + '</span>, ';
|
|
fhcp += replaceHtml(helpformulaArg, {
|
|
"param": nameli,
|
|
"content": paramitem.detail
|
|
});
|
|
}
|
|
|
|
fht = fht.substr(0, fht.length - 2);
|
|
ahf = ahf.substr(0, ahf.length - 2);
|
|
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-title .luckysheet-arguments-parameter-holder").html(fht); //介绍
|
|
$("#luckysheet-formula-help-c .luckysheet-arguments-help-formula .luckysheet-arguments-parameter-holder").html(ahf); //示例
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-content-param").html(fhcp); //参数
|
|
|
|
if(paramIndex == null){
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-title-formula .luckysheet-arguments-help-function-name").css("font-weight", "bold");
|
|
}
|
|
else{
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-title-formula .luckysheet-arguments-help-function-name").css("font-weight", "normal");
|
|
let index = paramIndex >= $func.p.length ? $func.p.length - 1 : paramIndex;
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-title .luckysheet-arguments-parameter-holder .luckysheet-arguments-help-parameter").removeClass("luckysheet-arguments-help-parameter-active");
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-title .luckysheet-arguments-parameter-holder .luckysheet-arguments-help-parameter").eq(index).addClass("luckysheet-arguments-help-parameter-active");
|
|
$("#luckysheet-formula-help-c .luckysheet-arguments-help-formula .luckysheet-arguments-parameter-holder .luckysheet-arguments-help-parameter").removeClass("luckysheet-arguments-help-parameter-active");
|
|
$("#luckysheet-formula-help-c .luckysheet-arguments-help-formula .luckysheet-arguments-parameter-holder .luckysheet-arguments-help-parameter").eq(index).addClass("luckysheet-arguments-help-parameter-active");
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-content-param .luckysheet-arguments-help-section").removeClass("luckysheet-arguments-help-parameter-active");
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-content-param .luckysheet-arguments-help-section").eq(index).addClass("luckysheet-arguments-help-parameter-active");
|
|
}
|
|
|
|
let $c = $editer.parent(),
|
|
offset = $c.offset();
|
|
_this.searchFunctionPosition($("#luckysheet-formula-help-c"), $c, offset.left, offset.top, true);
|
|
},
|
|
helpFunctionExe: function($editer, currSelection) {
|
|
let _this = this;
|
|
let functionlist = Store.functionlist;
|
|
let _locale = locale();
|
|
let locale_formulaMore = _locale.formulaMore;
|
|
if ($("#luckysheet-formula-help-c").length == 0) {
|
|
$("body").after(replaceHtml(_this.helpHTML,{
|
|
helpClose:locale_formulaMore.helpClose,
|
|
helpCollapse:locale_formulaMore.helpCollapse,
|
|
helpExample:locale_formulaMore.helpExample,
|
|
helpAbstract:locale_formulaMore.helpAbstract,
|
|
}));
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-close").click(function() {
|
|
$("#luckysheet-formula-help-c").hide();
|
|
});
|
|
$("#luckysheet-formula-help-c .luckysheet-formula-help-collapse").click(function() {
|
|
let $content = $("#luckysheet-formula-help-c .luckysheet-formula-help-content");
|
|
$content.slideToggle(100, function() {
|
|
let $c = _this.rangeResizeTo.parent(),
|
|
offset = $c.offset();
|
|
_this.searchFunctionPosition($("#luckysheet-formula-help-c"), $c, offset.left, offset.top, true);
|
|
});
|
|
|
|
if ($content.is(":hidden")) {
|
|
$(this).html('<i class="fa fa-angle-up" aria-hidden="true"></i>');
|
|
}
|
|
else {
|
|
$(this).html('<i class="fa fa-angle-down" aria-hidden="true"></i>');
|
|
}
|
|
});
|
|
|
|
for (let i = 0; i < functionlist.length; i++) {
|
|
_this.functionlistPosition[functionlist[i].n] = i;
|
|
}
|
|
}
|
|
|
|
if(!currSelection){
|
|
return;
|
|
}
|
|
|
|
let $prev = currSelection,
|
|
funcLen = $editer.length,
|
|
$span = $editer.find("span"),
|
|
currentIndex = currSelection.index(),
|
|
i = currentIndex;
|
|
|
|
if ($prev == null) {
|
|
return;
|
|
}
|
|
|
|
let funcName = null, paramindex= null;
|
|
|
|
if($span.eq(i).is(".luckysheet-formula-text-func")){
|
|
funcName = $span.eq(i).text();
|
|
}
|
|
else{
|
|
let $cur = null, exceptIndex = [-1, -1];
|
|
|
|
while (--i > 0) {
|
|
$cur = $span.eq(i);
|
|
|
|
if($cur.is(".luckysheet-formula-text-func") || $.trim($cur.text()).toUpperCase() in _this.functionlistPosition){
|
|
funcName = $cur.text();
|
|
paramindex = null;
|
|
let endstate = true;
|
|
|
|
for(let a = i; a <= currentIndex; a++){
|
|
if(!paramindex){
|
|
paramindex = 0;
|
|
}
|
|
|
|
if(a >= exceptIndex[0] && a <= exceptIndex[1]){
|
|
continue;
|
|
}
|
|
|
|
$cur = $span.eq(a);
|
|
if($cur.is(".luckysheet-formula-text-rpar")){
|
|
exceptIndex = [i , a];
|
|
funcName = null;
|
|
endstate = false;
|
|
break;
|
|
}
|
|
|
|
if($cur.is(".luckysheet-formula-text-comma")){
|
|
paramindex++;
|
|
}
|
|
}
|
|
|
|
if(endstate){
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(funcName == null){
|
|
return;
|
|
}
|
|
|
|
_this.helpFunction($editer, funcName, paramindex);
|
|
},
|
|
rangeHightlightselected: function($editer, kcode) {
|
|
let _this = this;
|
|
|
|
let currSelection = _this.getrangeseleciton();
|
|
$("#luckysheet-formula-search-c, #luckysheet-formula-help-c").hide();
|
|
$("#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight .luckysheet-selection-copy-hc").css("opacity", "0.03");
|
|
$("#luckysheet-formula-search-c, #luckysheet-formula-help-c").hide();
|
|
_this.helpFunctionExe($editer, currSelection);
|
|
|
|
console.log(currSelection, $(currSelection).closest(".luckysheet-formula-functionrange-cell").length);
|
|
if ($(currSelection).closest(".luckysheet-formula-functionrange-cell").length == 0) {
|
|
_this.searchFunction($editer);
|
|
return;
|
|
}
|
|
|
|
let $anchorOffset = $(currSelection).closest(".luckysheet-formula-functionrange-cell");
|
|
let rangeindex = $anchorOffset.attr("rangeindex");
|
|
let rangeid = "luckysheet-formula-functionrange-highlight-" + rangeindex;
|
|
|
|
$("#" + rangeid).find(".luckysheet-selection-copy-hc").css({
|
|
"opacity": "0.13"
|
|
});
|
|
},
|
|
updatecell: function(r, c, value, isRefresh=true) {
|
|
|
|
let _this = this;
|
|
|
|
let $input = $("#luckysheet-rich-text-editor");
|
|
let inputText = $input.text(), inputHtml = $input.html();
|
|
|
|
|
|
if (_this.rangetosheet != null && _this.rangetosheet != Store.currentSheetIndex) {
|
|
sheetmanage.changeSheetExec(_this.rangetosheet);
|
|
}
|
|
|
|
if(!checkProtectionLocked(r, c, Store.currentSheetIndex)){
|
|
return;
|
|
}
|
|
|
|
//数据验证 输入数据无效时禁止输入
|
|
if(dataVerificationCtrl.dataVerification != null){
|
|
let dvItem = dataVerificationCtrl.dataVerification[r + '_' + c];
|
|
|
|
if(dvItem != null && dvItem.prohibitInput && !dataVerificationCtrl.validateCellData(inputText, dvItem)){
|
|
let failureText = dataVerificationCtrl.getFailureText(dvItem);
|
|
tooltip.info(failureText, '');
|
|
_this.cancelNormalSelected();
|
|
return;
|
|
}
|
|
}
|
|
|
|
let curv = Store.flowdata[r][c];
|
|
|
|
// Store old value for hook function
|
|
const oldValue = JSON.stringify(curv);
|
|
|
|
let isPrevInline = isInlineStringCell(curv);
|
|
let isCurInline = (inputText.slice(0, 1) != "=" && inputHtml.substr(0,5) == "<span");
|
|
if(!value && !isCurInline && isPrevInline){
|
|
delete curv.ct.s;
|
|
curv.ct.t = "g";
|
|
curv.ct.fa = "General";
|
|
value = "";
|
|
}
|
|
else if(isCurInline){
|
|
if (getObjType(curv) != "object") {
|
|
curv = {};
|
|
}
|
|
delete curv.f;
|
|
delete curv.v;
|
|
delete curv.m;
|
|
|
|
if(curv.ct==null){
|
|
curv.ct = {};
|
|
curv.ct.fa = "General";
|
|
}
|
|
|
|
curv.ct.t = "inlineStr";
|
|
curv.ct.s = convertSpanToShareString($input.find("span"));
|
|
}
|
|
|
|
// API, we get value from user
|
|
value = value || $input.text();
|
|
|
|
// Hook function
|
|
if(!method.createHookFunction("cellUpdateBefore", r, c, value, isRefresh)){
|
|
_this.cancelNormalSelected();
|
|
return;
|
|
}
|
|
|
|
if(!isCurInline){
|
|
if(isRealNull(value) && !isPrevInline){
|
|
if(curv == null || (isRealNull(curv.v) && curv.spl == null && curv.f == null)){
|
|
_this.cancelNormalSelected();
|
|
return;
|
|
}
|
|
}
|
|
else if(curv!=null && curv.qp != 1){
|
|
if (getObjType(curv) == "object" && (value == curv.f || value == curv.v || value == curv.m)) {
|
|
_this.cancelNormalSelected();
|
|
return;
|
|
}
|
|
else if (value == curv) {
|
|
_this.cancelNormalSelected();
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (getObjType(value) == "string" && value.slice(0, 1) == "=" && value.length > 1) {
|
|
|
|
}
|
|
else if(getObjType(curv) == "object" && curv.ct != null && curv.ct.fa != null && curv.ct.fa != "@" && !isRealNull(value)){
|
|
delete curv.m;//更新时间m处理 , 会实际删除单元格数据的参数(flowdata时已删除)
|
|
if(curv.f != null){ //如果原来是公式,而更新的数据不是公式,则把公式删除
|
|
delete curv.f;
|
|
delete curv.spl; //删除单元格的sparklines的配置串
|
|
}
|
|
}
|
|
}
|
|
|
|
window.luckysheet_getcelldata_cache = null;
|
|
|
|
let isRunExecFunction = true;
|
|
|
|
let d = editor.deepCopyFlowData(Store.flowdata);
|
|
let dynamicArrayItem = null; //动态数组
|
|
|
|
if (getObjType(curv) == "object") {
|
|
|
|
if(!isCurInline){
|
|
|
|
if(getObjType(value) == "string" && value.slice(0, 1) == "=" && value.length > 1){
|
|
let v = _this.execfunction(value, r, c, undefined, true);
|
|
isRunExecFunction = false;
|
|
curv = d[r][c];
|
|
curv.v = v[1];
|
|
curv.f = v[2];
|
|
|
|
//打进单元格的sparklines的配置串, 报错需要单独处理。
|
|
if(v.length == 4 && v[3].type == "sparklines"){
|
|
delete curv.m;
|
|
delete curv.v;
|
|
|
|
let curCalv = v[3].data;
|
|
|
|
if(getObjType(curCalv) == "array" && getObjType(curCalv[0]) != "object"){
|
|
curv.v = curCalv[0];
|
|
}
|
|
else{
|
|
curv.spl = v[3].data;
|
|
}
|
|
}
|
|
else if(v.length == 4 && v[3].type == "dynamicArrayItem"){
|
|
dynamicArrayItem = v[3].data;
|
|
}
|
|
}
|
|
// from API setCellValue,luckysheet.setCellValue(0, 0, {f: "=sum(D1)", bg:"#0188fb"}),value is an object, so get attribute f as value
|
|
else if(getObjType(value) == "object"){
|
|
let valueFunction = value.f;
|
|
|
|
if(getObjType(valueFunction) == "string" && valueFunction.slice(0, 1) == "=" && valueFunction.length > 1){
|
|
let v = _this.execfunction(valueFunction, r, c, undefined, true);
|
|
isRunExecFunction = false;
|
|
// get v/m/ct
|
|
|
|
curv = d[r][c];
|
|
curv.v = v[1];
|
|
curv.f = v[2];
|
|
|
|
//打进单元格的sparklines的配置串, 报错需要单独处理。
|
|
if(v.length == 4 && v[3].type == "sparklines"){
|
|
delete curv.m;
|
|
delete curv.v;
|
|
|
|
let curCalv = v[3].data;
|
|
|
|
if(getObjType(curCalv) == "array" && getObjType(curCalv[0]) != "object"){
|
|
curv.v = curCalv[0];
|
|
}
|
|
else{
|
|
curv.spl = v[3].data;
|
|
}
|
|
}
|
|
else if(v.length == 4 && v[3].type == "dynamicArrayItem"){
|
|
dynamicArrayItem = v[3].data;
|
|
}
|
|
}
|
|
// from API setCellValue,luckysheet.setCellValue(0, 0, {f: "=sum(D1)", bg:"#0188fb"}),value is an object, so get attribute f as value
|
|
else {
|
|
for(let attr in value){
|
|
curv[attr] = value[attr];
|
|
}
|
|
// let valueFunction = value.f;
|
|
|
|
// if(getObjType(valueFunction) == "string" && valueFunction.slice(0, 1) == "=" && valueFunction.length > 1){
|
|
// let v = _this.execfunction(valueFunction, r, c, undefined, true);
|
|
// isRunExecFunction = false;
|
|
// // get v/m/ct
|
|
// curv = d[r][c];
|
|
// curv.v = v[1];
|
|
// // get f
|
|
// curv.f = v[2];
|
|
|
|
// // get other cell style attribute
|
|
// delete value.v;
|
|
// delete value.m;
|
|
// delete value.f;
|
|
// Object.assign(curv,value);
|
|
|
|
// //打进单元格的sparklines的配置串, 报错需要单独处理。
|
|
// if(v.length == 4 && v[3].type == "sparklines"){
|
|
// delete curv.m;
|
|
// delete curv.v;
|
|
|
|
// let curCalv = v[3].data;
|
|
|
|
// if(getObjType(curCalv) == "array" && getObjType(curCalv[0]) != "object"){
|
|
// curv.v = curCalv[0];
|
|
// }
|
|
// else{
|
|
// curv.spl = v[3].data;
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
else {
|
|
_this.delFunctionGroup(r, c);
|
|
_this.execFunctionGroup(r, c, value);
|
|
isRunExecFunction = false;
|
|
|
|
curv = d[r][c];
|
|
// let gd = _this.execFunctionGlobalData[r+"_"+c+"_"+Store.currentSheetIndex];
|
|
// if(gd!=null){
|
|
// curv.v = gd.v;
|
|
// }
|
|
curv.v = value;
|
|
|
|
delete curv.f;
|
|
delete curv.spl;
|
|
|
|
if(curv.qp == 1 && ('' + value).substr(0,1)!="'"){//if quotePrefix is 1, cell is force string, cell clear quotePrefix when it is updated
|
|
curv.qp = 0;
|
|
if(curv.ct!=null){
|
|
curv.ct.fa = "General";
|
|
curv.ct.t = "n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
value = curv;
|
|
}
|
|
else {
|
|
if(getObjType(value) == "string" && value.slice(0, 1) == "=" && value.length > 1){
|
|
let v = _this.execfunction(value, r, c, undefined, true);
|
|
isRunExecFunction = false;
|
|
value = {
|
|
"v": v[1],
|
|
"f": v[2]
|
|
};
|
|
|
|
|
|
//打进单元格的sparklines的配置串, 报错需要单独处理。
|
|
if(v.length == 4 && v[3].type == "sparklines"){
|
|
let curCalv = v[3].data;
|
|
|
|
if(getObjType(curCalv) == "array" && getObjType(curCalv[0]) != "object"){
|
|
value.v = curCalv[0];
|
|
}
|
|
else{
|
|
value.spl = v[3].data;
|
|
}
|
|
}
|
|
else if(v.length == 4 && v[3].type == "dynamicArrayItem"){
|
|
dynamicArrayItem = v[3].data;
|
|
}
|
|
}
|
|
// from API setCellValue,luckysheet.setCellValue(0, 0, {f: "=sum(D1)", bg:"#0188fb"}),value is an object, so get attribute f as value
|
|
else if(getObjType(value) == "object"){
|
|
let valueFunction = value.f;
|
|
|
|
if(getObjType(valueFunction) == "string" && valueFunction.slice(0, 1) == "=" && valueFunction.length > 1){
|
|
let v = _this.execfunction(valueFunction, r, c, undefined, true);
|
|
isRunExecFunction = false;
|
|
// value = {
|
|
// "v": v[1],
|
|
// "f": v[2]
|
|
// };
|
|
|
|
// update attribute v
|
|
value.v = v[1];
|
|
value.f = v[2];
|
|
|
|
//打进单元格的sparklines的配置串, 报错需要单独处理。
|
|
if(v.length == 4 && v[3].type == "sparklines"){
|
|
let curCalv = v[3].data;
|
|
|
|
if(getObjType(curCalv) == "array" && getObjType(curCalv[0]) != "object"){
|
|
value.v = curCalv[0];
|
|
}
|
|
else{
|
|
value.spl = v[3].data;
|
|
}
|
|
}
|
|
else if(v.length == 4 && v[3].type == "dynamicArrayItem"){
|
|
dynamicArrayItem = v[3].data;
|
|
}
|
|
}
|
|
else{
|
|
let v = curv;
|
|
if(value.v==null){
|
|
value.v = v;
|
|
}
|
|
}
|
|
|
|
}
|
|
else{
|
|
_this.delFunctionGroup(r, c);
|
|
_this.execFunctionGroup(r, c, value);
|
|
isRunExecFunction = false;
|
|
}
|
|
}
|
|
|
|
// value maybe an object
|
|
setcellvalue(r, c, d, value);
|
|
_this.cancelNormalSelected();
|
|
|
|
let RowlChange = false;
|
|
let cfg = $.extend(true, {}, getluckysheetfile()[getSheetIndex(Store.currentSheetIndex)]["config"]);
|
|
if(cfg["rowlen"] == null){
|
|
cfg["rowlen"] = {};
|
|
}
|
|
|
|
if((d[r][c].tb == "2" && d[r][c].v != null) || isInlineStringCell(d[r][c])){//自动换行
|
|
let defaultrowlen = Store.defaultrowlen;;
|
|
|
|
let canvas = $("#luckysheetTableContent").get(0).getContext("2d");
|
|
// offlinecanvas.textBaseline = 'top'; //textBaseline以top计算
|
|
|
|
// let fontset = luckysheetfontformat(d[r][c]);
|
|
// offlinecanvas.font = fontset;
|
|
|
|
if(cfg["customHeight"] && cfg["customHeight"][r]==1){
|
|
|
|
}
|
|
else{
|
|
// let currentRowLen = defaultrowlen;
|
|
// if(cfg["rowlen"][r] != null){
|
|
// currentRowLen = cfg["rowlen"][r];
|
|
// }
|
|
|
|
let cellWidth = colLocationByIndex(c)[1] - colLocationByIndex(c)[0] - 2;
|
|
|
|
let textInfo = getCellTextInfo(d[r][c], canvas,{
|
|
r:r,
|
|
c:c,
|
|
cellWidth:cellWidth
|
|
});
|
|
|
|
let currentRowLen = defaultrowlen;
|
|
// console.log("rowlen", textInfo);
|
|
if(textInfo!=null){
|
|
currentRowLen = textInfo.textHeightAll+2;
|
|
}
|
|
|
|
// let strValue = getcellvalue(r, c, d).toString();
|
|
// let measureText = offlinecanvas.measureText(strValue);
|
|
|
|
// let textMetrics = measureText.width;
|
|
// let cellWidth = colLocationByIndex(c)[1] - colLocationByIndex(c)[0] - 4;
|
|
// let oneLineTextHeight = measureText.actualBoundingBoxDescent - measureText.actualBoundingBoxAscent;
|
|
|
|
// if(textMetrics > cellWidth){
|
|
// let strArr = [];//文本截断数组
|
|
// strArr = getCellTextSplitArr(strValue, strArr, cellWidth, offlinecanvas);
|
|
|
|
// let computeRowlen = oneLineTextHeight * strArr.length + 4;
|
|
// //比较计算高度和当前高度取最大高度
|
|
// if(computeRowlen > currentRowLen){
|
|
// currentRowLen = computeRowlen;
|
|
// }
|
|
// }
|
|
|
|
if(currentRowLen > defaultrowlen){
|
|
cfg["rowlen"][r] = currentRowLen;
|
|
RowlChange = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//动态数组
|
|
let dynamicArray = null;
|
|
if(!!dynamicArrayItem){
|
|
// let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];
|
|
dynamicArray = $.extend(true, [], this.insertUpdateDynamicArray(dynamicArrayItem));
|
|
// dynamicArray.push(dynamicArrayItem);
|
|
|
|
}
|
|
|
|
let allParam = {
|
|
"dynamicArray": dynamicArray
|
|
}
|
|
|
|
if(RowlChange){
|
|
allParam = {
|
|
"cfg": cfg,
|
|
"dynamicArray": dynamicArray,
|
|
"RowlChange": RowlChange
|
|
}
|
|
}
|
|
|
|
setTimeout(() => {
|
|
// Hook function
|
|
method.createHookFunction("cellUpdated", r, c, JSON.parse(oldValue), Store.flowdata[r][c], isRefresh);
|
|
}, 0);
|
|
|
|
if(isRefresh){
|
|
jfrefreshgrid(d, [{ "row": [r, r], "column": [c, c] }], allParam, isRunExecFunction);
|
|
// Store.luckysheetCellUpdate.length = 0; //clear array
|
|
_this.execFunctionGlobalData = null; //销毁
|
|
}
|
|
else{
|
|
return {
|
|
data:d,
|
|
allParam:allParam
|
|
};
|
|
}
|
|
},
|
|
cancelNormalSelected: function() {
|
|
let _this = this;
|
|
|
|
_this.canceFunctionrangeSelected();
|
|
|
|
$("#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight").remove();
|
|
$("#luckysheet-input-box").removeAttr("style");
|
|
$("#luckysheet-input-box-index").hide();
|
|
$("#luckysheet-wa-functionbox-cancel, #luckysheet-wa-functionbox-confirm").removeClass("luckysheet-wa-calculate-active");
|
|
|
|
_this.rangestart = false;
|
|
_this.rangedrag_column_start = false;
|
|
_this.rangedrag_row_start = false;
|
|
},
|
|
canceFunctionrangeSelected: function() {
|
|
$("#luckysheet-formula-functionrange-select").hide();
|
|
$("#luckysheet-row-count-show, #luckysheet-column-count-show").hide();
|
|
// $("#luckysheet-cols-h-selected, #luckysheet-rows-h-selected").hide();
|
|
$("#luckysheet-formula-search-c, #luckysheet-formula-help-c").hide();
|
|
},
|
|
iscellformat: function(txt) {
|
|
let re_abc = /[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][123456789]/;
|
|
},
|
|
iscelldata: function(txt) { //判断是否为单元格格式
|
|
let val = txt.split("!"),
|
|
rangetxt;
|
|
|
|
if (val.length > 1) {
|
|
rangetxt = val[1];
|
|
}
|
|
else {
|
|
rangetxt = val[0];
|
|
}
|
|
|
|
let reg_cell = /^(([a-zA-Z]+)|([$][a-zA-Z]+))(([0-9]+)|([$][0-9]+))$/g; //增加正则判断单元格为字母+数字的格式:如 A1:B3
|
|
let reg_cellRange = /^(((([a-zA-Z]+)|([$][a-zA-Z]+))(([0-9]+)|([$][0-9]+)))|((([a-zA-Z]+)|([$][a-zA-Z]+))))$/g; //增加正则判断单元格为字母+数字或字母的格式:如 A1:B3,A:A
|
|
|
|
if (rangetxt.indexOf(":") == -1) {
|
|
let row = parseInt(rangetxt.replace(/[^0-9]/g, "")) - 1;
|
|
let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, ""));
|
|
|
|
if (!isNaN(row) && !isNaN(col) && rangetxt.toString().match(reg_cell)) {
|
|
return true;
|
|
}
|
|
else if (!isNaN(row)) {
|
|
return false;
|
|
}
|
|
else if (!isNaN(col)) {
|
|
return false;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
reg_cellRange = /^(((([a-zA-Z]+)|([$][a-zA-Z]+))(([0-9]+)|([$][0-9]+)))|((([a-zA-Z]+)|([$][a-zA-Z]+)))|((([0-9]+)|([$][0-9]+s))))$/g;
|
|
|
|
rangetxt = rangetxt.split(":");
|
|
|
|
let row = [],col = [];
|
|
row[0] = parseInt(rangetxt[0].replace(/[^0-9]/g, "")) - 1;
|
|
row[1] = parseInt(rangetxt[1].replace(/[^0-9]/g, "")) - 1;
|
|
if (row[0] > row[1]) {
|
|
return false;
|
|
}
|
|
|
|
col[0] = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, ""));
|
|
col[1] = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, ""));
|
|
if (col[0] > col[1]) {
|
|
return false;
|
|
}
|
|
|
|
if(rangetxt[0].toString().match(reg_cellRange) && rangetxt[1].toString().match(reg_cellRange)){
|
|
return true;
|
|
}
|
|
else{
|
|
return false;
|
|
}
|
|
}
|
|
},
|
|
operator: '==|!=|<>|<=|>=|=|+|-|>|<|/|*|%|&|^',
|
|
operatorjson: null,
|
|
functionCopy: function(txt, mode, step) {
|
|
let _this = this;
|
|
|
|
if (_this.operatorjson == null) {
|
|
let arr = _this.operator.split("|"),
|
|
op = {};
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
op[arr[i].toString()] = 1;
|
|
}
|
|
|
|
_this.operatorjson = op;
|
|
}
|
|
|
|
if (mode == null) {
|
|
mode = "down";
|
|
}
|
|
|
|
if (step == null) {
|
|
step = 1;
|
|
}
|
|
|
|
if (txt.substr(0, 1) == "=") {
|
|
txt = txt.substr(1);
|
|
}
|
|
|
|
let funcstack = txt.split("");
|
|
let i = 0,
|
|
str = "",
|
|
function_str = "",
|
|
ispassby = true;
|
|
|
|
let matchConfig = {
|
|
"bracket": 0,
|
|
"comma": 0,
|
|
"squote": 0,
|
|
"dquote": 0
|
|
};
|
|
|
|
while (i < funcstack.length) {
|
|
let s = funcstack[i];
|
|
|
|
if (s == "(" && matchConfig.dquote == 0) {
|
|
matchConfig.bracket += 1;
|
|
|
|
if (str.length > 0) {
|
|
function_str += str + "(";
|
|
}
|
|
else {
|
|
function_str += "(";
|
|
}
|
|
|
|
str = "";
|
|
}
|
|
else if (s == ")" && matchConfig.dquote == 0) {
|
|
matchConfig.bracket -= 1;
|
|
function_str += _this.functionCopy(str, mode, step) + ")";
|
|
str = "";
|
|
}
|
|
else if (s == '"' && matchConfig.squote == 0) {
|
|
if (matchConfig.dquote > 0) {
|
|
function_str += str + '"';
|
|
matchConfig.dquote -= 1;
|
|
str = "";
|
|
}
|
|
else {
|
|
matchConfig.dquote += 1;
|
|
str += '"';
|
|
}
|
|
}
|
|
else if (s == ',' && matchConfig.dquote == 0) {
|
|
function_str += _this.functionCopy(str, mode, step) + ',';
|
|
str = "";
|
|
}
|
|
else if (s == '&' && matchConfig.dquote == 0) {
|
|
if (str.length > 0) {
|
|
function_str += _this.functionCopy(str, mode, step) + "&";
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += "&";
|
|
}
|
|
}
|
|
else if (s in _this.operatorjson && matchConfig.dquote == 0) {
|
|
let s_next = "";
|
|
|
|
if ((i + 1) < funcstack.length) {
|
|
s_next = funcstack[i + 1];
|
|
}
|
|
|
|
let p = i - 1,
|
|
s_pre = null;
|
|
|
|
if(p >= 0){
|
|
do {
|
|
s_pre = funcstack[p--];
|
|
}
|
|
while (p>=0 && s_pre ==" ")
|
|
}
|
|
|
|
if ((s + s_next) in _this.operatorjson) {
|
|
if (str.length > 0) {
|
|
function_str += _this.functionCopy(str, mode, step) + s + s_next;
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += s + s_next;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
else if(!(/[^0-9]/.test(s_next)) && s=="-" && (s_pre=="(" || s_pre == null || s_pre == "," || s_pre == " " || s_pre in _this.operatorjson ) ){
|
|
str += s;
|
|
}
|
|
else {
|
|
if (str.length > 0) {
|
|
function_str += _this.functionCopy(str, mode, step) + s;
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += s;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
|
|
if (i == funcstack.length - 1) {
|
|
if (_this.iscelldata($.trim(str))) {
|
|
if (mode == "down") {
|
|
function_str += _this.downparam($.trim(str), step);
|
|
}
|
|
else if (mode == "up") {
|
|
function_str += _this.upparam($.trim(str), step);
|
|
}
|
|
else if (mode == "left") {
|
|
function_str += _this.leftparam($.trim(str), step);
|
|
}
|
|
else if (mode == "right") {
|
|
function_str += _this.rightparam($.trim(str), step);
|
|
}
|
|
}
|
|
else {
|
|
function_str += $.trim(str);
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return function_str;
|
|
},
|
|
isfreezonFuc: function(txt) {
|
|
let row = txt.replace(/[^0-9]/g, "");
|
|
let col = txt.replace(/[^A-Za-z]/g, "");
|
|
let row$ = txt.substr(txt.indexOf(row) - 1, 1);
|
|
let col$ = txt.substr(txt.indexOf(col) - 1, 1);
|
|
let ret = [false, false];
|
|
|
|
if (row$ == "$") {
|
|
ret[0] = true;
|
|
}
|
|
if (col$ == "$") {
|
|
ret[1] = true;
|
|
}
|
|
|
|
return ret;
|
|
},
|
|
setfreezonFuceExe: function(rangetxt) {
|
|
let row = parseInt(rangetxt.replace(/[^0-9]/g, ""));
|
|
let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, ""));
|
|
let $row = "$",
|
|
$col = "$";
|
|
|
|
if (!isNaN(row) && !isNaN(col)) {
|
|
return $col + chatatABC(col) + $row + (row);
|
|
}
|
|
else if (!isNaN(row)) {
|
|
return $row + (row);
|
|
}
|
|
else if (!isNaN(col)) {
|
|
return $col + chatatABC(col);
|
|
}
|
|
else {
|
|
return rangetxt;
|
|
}
|
|
},
|
|
setfreezonFuc: function(event) {
|
|
let _this = this;
|
|
|
|
let obj = _this.getrangeseleciton();
|
|
if (!_this.iscelldata(obj.text())) {
|
|
return;
|
|
}
|
|
|
|
let txt = obj.text(),
|
|
pos = window.getSelection().anchorOffset;
|
|
let val = txt.split("!"),
|
|
rangetxt, prefix = "";
|
|
|
|
if (val.length > 1) {
|
|
rangetxt = val[1];
|
|
prefix = val[0] + "!";
|
|
}
|
|
else {
|
|
rangetxt = val[0];
|
|
}
|
|
|
|
let newtxt = "",
|
|
newpos = "";
|
|
let rangetxtIndex = rangetxt.indexOf(":");
|
|
|
|
if (rangetxtIndex == -1) {
|
|
newtxt = prefix + _this.setfreezonFuceExe(rangetxt);
|
|
newpos = newtxt.length;
|
|
}
|
|
else {
|
|
rangetxt = rangetxt.split(":");
|
|
|
|
if (pos > rangetxtIndex) {
|
|
let ret = prefix + rangetxt[0] + ":" + _this.setfreezonFuceExe(rangetxt[1]);
|
|
newtxt = ret;
|
|
newpos = ret.length;
|
|
}
|
|
else {
|
|
let firsttxt = prefix + _this.setfreezonFuceExe(rangetxt[0]);
|
|
let ret = firsttxt + ":" + rangetxt[1];
|
|
newtxt = ret;
|
|
newpos = firsttxt.length;
|
|
}
|
|
}
|
|
|
|
obj.text(prefix + newtxt);
|
|
_this.setCaretPosition(obj.get(0), 0, newpos);
|
|
},
|
|
updateparam: function(orient, txt, step) {
|
|
let _this = this;
|
|
|
|
let val = txt.split("!"),
|
|
rangetxt, prefix = "";
|
|
|
|
if (val.length > 1) {
|
|
rangetxt = val[1];
|
|
prefix = val[0] + "!";
|
|
}
|
|
else {
|
|
rangetxt = val[0];
|
|
}
|
|
|
|
if (rangetxt.indexOf(":") == -1) {
|
|
let row = parseInt(rangetxt.replace(/[^0-9]/g, ""));
|
|
let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, ""));
|
|
let freezonFuc = _this.isfreezonFuc(rangetxt);
|
|
let $row = freezonFuc[0] ? "$" : "",
|
|
$col = freezonFuc[1] ? "$" : "";
|
|
|
|
if (orient == "u" && !freezonFuc[0]) {
|
|
row -= step;
|
|
}
|
|
else if (orient == "r" && !freezonFuc[1]) {
|
|
col += step;
|
|
}
|
|
else if (orient == "l" && !freezonFuc[1]) {
|
|
col -= step;
|
|
}
|
|
else if (orient == "d" && !freezonFuc[0]) {
|
|
row += step;
|
|
}
|
|
|
|
if(row[0] < 0 || col[0] < 0){
|
|
return _this.error.r;
|
|
}
|
|
|
|
if (!isNaN(row) && !isNaN(col)) {
|
|
return prefix + $col + chatatABC(col) + $row + (row);
|
|
}
|
|
else if (!isNaN(row)) {
|
|
return prefix + $row + (row);
|
|
}
|
|
else if (!isNaN(col)) {
|
|
return prefix + $col + chatatABC(col);
|
|
}
|
|
else {
|
|
return txt;
|
|
}
|
|
}
|
|
else {
|
|
rangetxt = rangetxt.split(":");
|
|
let row = [],
|
|
col = [];
|
|
|
|
row[0] = parseInt(rangetxt[0].replace(/[^0-9]/g, ""));
|
|
row[1] = parseInt(rangetxt[1].replace(/[^0-9]/g, ""));
|
|
if (row[0] > row[1]) {
|
|
return txt;
|
|
}
|
|
|
|
col[0] = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, ""));
|
|
col[1] = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, ""));
|
|
if (col[0] > col[1]) {
|
|
return txt;
|
|
}
|
|
|
|
let freezonFuc0 = _this.isfreezonFuc(rangetxt[0]);
|
|
let freezonFuc1 = _this.isfreezonFuc(rangetxt[1]);
|
|
let $row0 = freezonFuc0[0] ? "$" : "",
|
|
$col0 = freezonFuc0[1] ? "$" : "";
|
|
let $row1 = freezonFuc1[0] ? "$" : "",
|
|
$col1 = freezonFuc1[1] ? "$" : "";
|
|
|
|
if (orient == "u") {
|
|
if (!freezonFuc0[0]) {
|
|
row[0] -= step;
|
|
}
|
|
|
|
if (!freezonFuc1[0]) {
|
|
row[1] -= step;
|
|
}
|
|
}
|
|
else if (orient == "r") {
|
|
if (!freezonFuc0[1]) {
|
|
col[0] += step;
|
|
}
|
|
|
|
if (!freezonFuc1[1]) {
|
|
col[1] += step;
|
|
}
|
|
}
|
|
else if (orient == "l") {
|
|
if (!freezonFuc0[1]) {
|
|
col[0] -= step;
|
|
}
|
|
|
|
if (!freezonFuc1[1]) {
|
|
col[1] -= step;
|
|
}
|
|
}
|
|
else if(orient=="d") {
|
|
if (!freezonFuc0[0]) {
|
|
row[0] += step;
|
|
}
|
|
|
|
if (!freezonFuc1[0]) {
|
|
row[1] += step;
|
|
}
|
|
}
|
|
|
|
if(row[0] < 0 || col[0] < 0){
|
|
return _this.error.r;
|
|
}
|
|
|
|
if (isNaN(col[0]) && isNaN(col[1])) {
|
|
return prefix + $row0 + (row[0]) + ":" + $row1 + (row[1]);
|
|
}
|
|
else if (isNaN(row[0]) && isNaN(row[1])) {
|
|
return prefix + $col0 + chatatABC(col[0]) + ":" + $col1 + chatatABC(col[1]);
|
|
}
|
|
else {
|
|
return prefix + $col0 + chatatABC(col[0]) + $row0 + (row[0]) + ":" + $col1 + chatatABC(col[1]) + $row1 + (row[1]);
|
|
}
|
|
}
|
|
},
|
|
downparam: function(txt, step) {
|
|
return this.updateparam("d", txt, step);
|
|
},
|
|
upparam: function(txt, step) {
|
|
return this.updateparam("u", txt, step);
|
|
},
|
|
leftparam: function(txt, step) {
|
|
return this.updateparam("l", txt, step);
|
|
},
|
|
rightparam: function(txt, step) {
|
|
return this.updateparam("r", txt, step);
|
|
},
|
|
functionStrChange: function(txt, type, rc, orient, stindex, step) {
|
|
let _this = this;
|
|
|
|
if (_this.operatorjson == null) {
|
|
let arr = _this.operator.split("|"),
|
|
op = {};
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
op[arr[i].toString()] = 1;
|
|
}
|
|
|
|
_this.operatorjson = op;
|
|
}
|
|
|
|
if (txt.substr(0, 1) == "=") {
|
|
txt = txt.substr(1);
|
|
}
|
|
|
|
let funcstack = txt.split("");
|
|
let i = 0,
|
|
str = "",
|
|
function_str = "",
|
|
ispassby = true;
|
|
|
|
let matchConfig = {
|
|
"bracket": 0, //括号
|
|
"comma": 0, //逗号
|
|
"squote": 0, //单引号
|
|
"dquote": 0 //双引号
|
|
};
|
|
|
|
while (i < funcstack.length) {
|
|
let s = funcstack[i];
|
|
|
|
if (s == "(" && matchConfig.dquote == 0) {
|
|
matchConfig.bracket += 1;
|
|
|
|
if (str.length > 0) {
|
|
function_str += str + "(";
|
|
}
|
|
else {
|
|
function_str += "(";
|
|
}
|
|
|
|
str = "";
|
|
}
|
|
else if (s == ")" && matchConfig.dquote == 0) {
|
|
matchConfig.bracket -= 1;
|
|
function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + ")";
|
|
str = "";
|
|
}
|
|
else if (s == '"' && matchConfig.squote == 0) {
|
|
if (matchConfig.dquote > 0) {
|
|
function_str += str + '"';
|
|
matchConfig.dquote -= 1;
|
|
str = "";
|
|
}
|
|
else {
|
|
matchConfig.dquote += 1;
|
|
str += '"';
|
|
}
|
|
}
|
|
else if (s == ',' && matchConfig.dquote == 0) {
|
|
function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + ',';
|
|
str = "";
|
|
}
|
|
else if (s == '&' && matchConfig.dquote == 0) {
|
|
if (str.length > 0) {
|
|
function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + "&";
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += "&";
|
|
}
|
|
}
|
|
else if (s in _this.operatorjson && matchConfig.dquote == 0) {
|
|
let s_next = "";
|
|
|
|
if ((i + 1) < funcstack.length) {
|
|
s_next = funcstack[i + 1];
|
|
}
|
|
|
|
let p = i - 1,
|
|
s_pre = null;;
|
|
|
|
if(p >= 0){
|
|
do {
|
|
s_pre = funcstack[p--];
|
|
}
|
|
while (p>=0 && s_pre ==" ")
|
|
}
|
|
|
|
if ((s + s_next) in _this.operatorjson) {
|
|
if (str.length > 0) {
|
|
function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + s + s_next;
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += s + s_next;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
else if(!(/[^0-9]/.test(s_next)) && s=="-" && (s_pre=="(" || s_pre == null || s_pre == "," || s_pre == " " || s_pre in _this.operatorjson ) ){
|
|
str += s;
|
|
}
|
|
else {
|
|
if (str.length > 0) {
|
|
function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + s;
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += s;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
|
|
if (i == funcstack.length - 1) {
|
|
if (_this.iscelldata($.trim(str))) {
|
|
function_str += _this.functionStrChange_range($.trim(str), type, rc, orient, stindex, step);
|
|
}
|
|
else {
|
|
function_str += $.trim(str);
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return function_str;
|
|
},
|
|
functionStrChange_range: function(txt, type, rc, orient, stindex, step){
|
|
let _this = this;
|
|
|
|
let val = txt.split("!"),
|
|
rangetxt, prefix = "";
|
|
|
|
if (val.length > 1) {
|
|
rangetxt = val[1];
|
|
prefix = val[0] + "!";
|
|
}
|
|
else {
|
|
rangetxt = val[0];
|
|
}
|
|
|
|
let r1, r2, c1, c2;
|
|
let $row0, $row1, $col0, $col1;
|
|
|
|
if (rangetxt.indexOf(":") == -1) {
|
|
r1 = r2 = parseInt(rangetxt.replace(/[^0-9]/g, "")) - 1;
|
|
c1 = c2 = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, ""));
|
|
|
|
let freezonFuc = _this.isfreezonFuc(rangetxt);
|
|
|
|
$row0 = $row1 = freezonFuc[0] ? "$" : "",
|
|
$col0 = $col1 = freezonFuc[1] ? "$" : "";
|
|
}
|
|
else {
|
|
rangetxt = rangetxt.split(":");
|
|
|
|
r1 = parseInt(rangetxt[0].replace(/[^0-9]/g, "")) - 1;
|
|
r2 = parseInt(rangetxt[1].replace(/[^0-9]/g, "")) - 1;
|
|
if (r1 > r2) {
|
|
return txt;
|
|
}
|
|
|
|
c1 = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, ""));
|
|
c2 = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, ""));
|
|
if (c1 > c2) {
|
|
return txt;
|
|
}
|
|
|
|
let freezonFuc0 = _this.isfreezonFuc(rangetxt[0]);
|
|
$row0 = freezonFuc0[0] ? "$" : "";
|
|
$col0 = freezonFuc0[1] ? "$" : "";
|
|
|
|
let freezonFuc1 = _this.isfreezonFuc(rangetxt[1]);
|
|
$row1 = freezonFuc1[0] ? "$" : "";
|
|
$col1 = freezonFuc1[1] ? "$" : "";
|
|
}
|
|
|
|
if(type == "del"){
|
|
if(rc == "row"){
|
|
if(r1 >= stindex && r2 <= stindex + step - 1){
|
|
return _this.error.r;
|
|
}
|
|
|
|
if(r1 > stindex + step - 1){
|
|
r1 -= step;
|
|
}
|
|
else if(r1 >= stindex){
|
|
r1 = stindex;
|
|
}
|
|
|
|
if(r2 > stindex + step - 1){
|
|
r2 -= step;
|
|
}
|
|
else if(r2 >= stindex){
|
|
r2 = stindex - 1;
|
|
}
|
|
|
|
if(r1 < 0){
|
|
r1 = 0;
|
|
}
|
|
|
|
if(r2 < r1){
|
|
r2 = r1;
|
|
}
|
|
}
|
|
else if(rc == "col"){
|
|
if(c1 >= stindex && c2 <= stindex + step - 1){
|
|
return _this.error.r;
|
|
}
|
|
|
|
if(c1 > stindex + step - 1){
|
|
c1 -= step;
|
|
}
|
|
else if(c1 >= stindex){
|
|
c1 = stindex;
|
|
}
|
|
|
|
if(c2 > stindex + step - 1){
|
|
c2 -= step;
|
|
}
|
|
else if(c2 >= stindex){
|
|
c2 = stindex - 1;
|
|
}
|
|
|
|
if(c1 < 0){
|
|
c1 = 0;
|
|
}
|
|
|
|
if(c2 < c1){
|
|
c2 = c1;
|
|
}
|
|
}
|
|
|
|
if(r1 == r2 && c1 == c2){
|
|
if (!isNaN(r1) && !isNaN(c1)) {
|
|
return prefix + $col0 + chatatABC(c1) + $row0 + (r1 + 1);
|
|
}
|
|
else if (!isNaN(r1)) {
|
|
return prefix + $row0 + (r1 + 1);
|
|
}
|
|
else if (!isNaN(c1)) {
|
|
return prefix + $col0 + chatatABC(c1);
|
|
}
|
|
else {
|
|
return txt;
|
|
}
|
|
}
|
|
else{
|
|
if (isNaN(c1) && isNaN(c2)) {
|
|
return prefix + $row0 + (r1 + 1) + ":" + $row1 + (r2 + 1);
|
|
}
|
|
else if (isNaN(r1) && isNaN(r2)) {
|
|
return prefix + $col0 + chatatABC(c1) + ":" + $col1 + chatatABC(c2);
|
|
}
|
|
else {
|
|
return prefix + $col0 + chatatABC(c1) + $row0 + (r1 + 1) + ":" + $col1 + chatatABC(c2) + $row1 + (r2 + 1);
|
|
}
|
|
}
|
|
}
|
|
else if(type == "add"){
|
|
if(rc == "row"){
|
|
if(orient == "lefttop"){
|
|
if(r1 >= stindex){
|
|
r1 += step;
|
|
}
|
|
|
|
if(r2 >= stindex){
|
|
r2 += step;
|
|
}
|
|
}
|
|
else if(orient == "rightbottom"){
|
|
if(r1 > stindex){
|
|
r1 += step;
|
|
}
|
|
|
|
if(r2 > stindex){
|
|
r2 += step;
|
|
}
|
|
}
|
|
}
|
|
else if(rc == "col"){
|
|
if(orient == "lefttop"){
|
|
if(c1 >= stindex){
|
|
c1 += step;
|
|
}
|
|
|
|
if(c2 >= stindex){
|
|
c2 += step;
|
|
}
|
|
}
|
|
else if(orient == "rightbottom"){
|
|
if(c1 > stindex){
|
|
c1 += step;
|
|
}
|
|
|
|
if(c2 > stindex){
|
|
c2 += step;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(r1 == r2 && c1 == c2){
|
|
if (!isNaN(r1) && !isNaN(c1)) {
|
|
return prefix + $col0 + chatatABC(c1) + $row0 + (r1 + 1);
|
|
}
|
|
else if (!isNaN(r1)) {
|
|
return prefix + $row0 + (r1 + 1);
|
|
}
|
|
else if (!isNaN(c1)) {
|
|
return prefix + $col0 + chatatABC(c1);
|
|
}
|
|
else {
|
|
return txt;
|
|
}
|
|
}
|
|
else{
|
|
if (isNaN(c1) && isNaN(c2)) {
|
|
return prefix + $row0 + (r1 + 1) + ":" + $row1 + (r2 + 1);
|
|
}
|
|
else if (isNaN(r1) && isNaN(r2)) {
|
|
return prefix + $col0 + chatatABC(c1) + ":" + $col1 + chatatABC(c2);
|
|
}
|
|
else {
|
|
return prefix + $col0 + chatatABC(c1) + $row0 + (r1 + 1) + ":" + $col1 + chatatABC(c2) + $row1 + (r2 + 1);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
israngeseleciton: function(istooltip) {
|
|
let _this = this;
|
|
|
|
if (_this.operatorjson == null) {
|
|
let arr = _this.operator.split("|"),
|
|
op = {};
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
op[arr[i].toString()] = 1;
|
|
}
|
|
|
|
_this.operatorjson = op;
|
|
}
|
|
|
|
if (istooltip == null) {
|
|
istooltip = false;
|
|
}
|
|
|
|
let currSelection = window.getSelection();
|
|
let anchor = $(currSelection.anchorNode);
|
|
let anchorOffset = currSelection.anchorOffset;
|
|
|
|
if (anchor.parent().is("span") && anchorOffset != 0) {
|
|
let txt = $.trim(anchor.text()),
|
|
lasttxt = "";
|
|
|
|
if (txt.length == 0 && anchor.parent().prev().length > 0) {
|
|
let ahr = anchor.parent().prev();
|
|
txt = $.trim(ahr.text());
|
|
lasttxt = txt.substr(txt.length - 1, 1);
|
|
_this.rangeSetValueTo = ahr;
|
|
}
|
|
else {
|
|
lasttxt = txt.substr(anchorOffset - 1, 1);
|
|
_this.rangeSetValueTo = anchor.parent();
|
|
}
|
|
|
|
if ((istooltip && (lasttxt == "(" || lasttxt == ",")) || (!istooltip && (lasttxt == "(" || lasttxt == "," || lasttxt == "=" || lasttxt in _this.operatorjson || lasttxt == "&"))) {
|
|
return true;
|
|
}
|
|
}
|
|
else if (anchor.is("#luckysheet-rich-text-editor") || anchor.is("#luckysheet-functionbox-cell")) {
|
|
let txt = $.trim(anchor.find("span").last().text()),
|
|
lasttxt;
|
|
|
|
_this.rangeSetValueTo = anchor.find("span").last();
|
|
|
|
if (txt.length == 0 && anchor.find("span").length > 1) {
|
|
let ahr = anchor.find("span");
|
|
txt = $.trim(ahr.eq(ahr.length - 2).text());
|
|
_this.rangeSetValueTo = ahr;
|
|
}
|
|
|
|
lasttxt = txt.substr(txt.length - 1, 1);
|
|
|
|
if ((istooltip && (lasttxt == "(" || lasttxt == ",")) || (!istooltip && (lasttxt == "(" || lasttxt == "," || lasttxt == "=" || lasttxt in _this.operatorjson || lasttxt == "&"))) {
|
|
return true;
|
|
}
|
|
}
|
|
else if (anchor.parent().is("#luckysheet-rich-text-editor") || anchor.parent().is("#luckysheet-functionbox-cell") || anchorOffset == 0) {
|
|
if (anchorOffset == 0) {
|
|
anchor = anchor.parent();
|
|
}
|
|
|
|
if (anchor.prev().length > 0) {
|
|
let txt = $.trim(anchor.prev().text());
|
|
let lasttxt = txt.substr(txt.length - 1, 1);
|
|
|
|
_this.rangeSetValueTo = anchor.prev();
|
|
|
|
if ((istooltip && (lasttxt == "(" || lasttxt == ",")) || (!istooltip && (lasttxt == "(" || lasttxt == "," || lasttxt == "=" || lasttxt in _this.operatorjson || lasttxt == "&"))) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
},
|
|
rangechangeindex: null,
|
|
rangestart: false,
|
|
rangetosheet: null,
|
|
rangeSetValueTo: null,
|
|
func_selectedrange: {}, //函数选区范围
|
|
rangeSetValue: function(selected, obj) {
|
|
let _this = this;
|
|
|
|
let range="", rf = selected["row"][0], cf = selected["column"][0];
|
|
if(Store.config["merge"] != null && (rf + "_" + cf) in Store.config["merge"]){
|
|
range = getRangetxt(Store.currentSheetIndex, {
|
|
column:[cf, cf],
|
|
row:[rf, rf],
|
|
}, _this.rangetosheet);
|
|
}
|
|
else{
|
|
range = getRangetxt(Store.currentSheetIndex, selected, _this.rangetosheet);
|
|
}
|
|
|
|
let $editor;
|
|
|
|
if (_this.rangestart || _this.rangedrag_column_start || _this.rangedrag_row_start) {
|
|
if($("#luckysheet-search-formula-parm").is(":visible")||$("#luckysheet-search-formula-parm-select").is(":visible")){
|
|
//公式参数框选取范围
|
|
$editor = $("#luckysheet-rich-text-editor");
|
|
$("#luckysheet-search-formula-parm-select-input").val(range);
|
|
$("#luckysheet-search-formula-parm .parmBox").eq(_this.data_parm_index).find(".txt input").val(range);
|
|
|
|
//参数对应值显示
|
|
let txtdata = luckysheet_getcelldata(range).data;
|
|
if(txtdata instanceof Array){
|
|
//参数为多个单元格选区
|
|
let txtArr=[];
|
|
|
|
for(let i = 0; i < txtdata.length; i++){
|
|
for(let j = 0; j < txtdata[i].length; j++){
|
|
if(txtdata[i][j] == null){
|
|
txtArr.push(null);
|
|
}
|
|
else{
|
|
txtArr.push(txtdata[i][j].v);
|
|
}
|
|
}
|
|
}
|
|
|
|
$("#luckysheet-search-formula-parm .parmBox").eq(_this.data_parm_index).find(".val").text(" = {"+ txtArr.join(",") +"}");
|
|
}
|
|
else{
|
|
//参数为单个单元格选区
|
|
$("#luckysheet-search-formula-parm .parmBox").eq(_this.data_parm_index).find(".val").text(" = {"+ txtdata.v +"}");
|
|
}
|
|
|
|
//计算结果显示
|
|
let isVal = true; //参数不为空
|
|
let parmValArr = []; //参数值集合
|
|
let lvi = -1; //最后一个有值的参数索引
|
|
$("#luckysheet-search-formula-parm .parmBox").each(function(i, e){
|
|
let parmtxt = $(e).find(".txt input").val();
|
|
if(parmtxt == "" && $(e).find(".txt input").attr("data_parm_require") == "m"){
|
|
isVal = false;
|
|
}
|
|
if(parmtxt != ""){
|
|
lvi = i;
|
|
}
|
|
})
|
|
|
|
//单元格显示
|
|
let functionHtmlTxt;
|
|
if(lvi == -1){
|
|
functionHtmlTxt = "=" + $("#luckysheet-search-formula-parm .luckysheet-modal-dialog-title-text").text() + "()";
|
|
}
|
|
else if(lvi == 0){
|
|
functionHtmlTxt = "=" + $("#luckysheet-search-formula-parm .luckysheet-modal-dialog-title-text").text() + "(" + $("#luckysheet-search-formula-parm .parmBox").eq(0).find(".txt input").val() + ")";
|
|
}
|
|
else{
|
|
for(let j = 0; j <= lvi; j++){
|
|
parmValArr.push($("#luckysheet-search-formula-parm .parmBox").eq(j).find(".txt input").val());
|
|
}
|
|
functionHtmlTxt = "=" + $("#luckysheet-search-formula-parm .luckysheet-modal-dialog-title-text").text() + "(" + parmValArr.join(",") + ")";
|
|
}
|
|
|
|
let function_str = _this.functionHTMLGenerate(functionHtmlTxt);
|
|
$("#luckysheet-rich-text-editor").html(function_str);
|
|
$("#luckysheet-functionbox-cell").html($("#luckysheet-rich-text-editor").html());
|
|
|
|
if(isVal){
|
|
//公式计算
|
|
let fp = $.trim(_this.functionParserExe($("#luckysheet-rich-text-editor").text()));
|
|
let result = eval(fp);
|
|
$("#luckysheet-search-formula-parm .result span").text(result);
|
|
}
|
|
}
|
|
else{
|
|
let currSelection = window.getSelection();
|
|
let anchorOffset = currSelection.anchorNode;
|
|
$editor = $(anchorOffset).closest("div");
|
|
|
|
let $span = $editor.find("span[rangeindex='" + _this.rangechangeindex + "']").html(range);
|
|
|
|
_this.setCaretPosition($span.get(0), 0, range.length);
|
|
}
|
|
}
|
|
else {
|
|
let function_str = '<span class="luckysheet-formula-functionrange-cell" rangeindex="' + _this.functionHTMLIndex + '" dir="auto" style="color:' + luckyColor[_this.functionHTMLIndex] + ';">' + range + '</span>';
|
|
let $t = $(function_str).insertAfter(_this.rangeSetValueTo);
|
|
_this.rangechangeindex = _this.functionHTMLIndex;
|
|
$editor = $(_this.rangeSetValueTo).closest("div");
|
|
|
|
_this.setCaretPosition($editor.find("span[rangeindex='" + _this.rangechangeindex + "']").get(0), 0, range.length);
|
|
_this.functionHTMLIndex++;
|
|
}
|
|
|
|
if ($editor.attr("id") == "luckysheet-rich-text-editor") {
|
|
$("#luckysheet-functionbox-cell").html($("#luckysheet-rich-text-editor").html());
|
|
}
|
|
else {
|
|
$("#luckysheet-rich-text-editor").html($("#luckysheet-functionbox-cell").html());
|
|
}
|
|
},
|
|
rangedrag: function(event) {
|
|
let _this = this;
|
|
|
|
let mouse = mouseposition(event.pageX, event.pageY);
|
|
let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft();
|
|
let y = mouse[1] + $("#luckysheet-cell-main").scrollTop();
|
|
|
|
let row_location = rowLocation(y),
|
|
row = row_location[1],
|
|
row_pre = row_location[0],
|
|
row_index = row_location[2];
|
|
|
|
let col_location = colLocation(x),
|
|
col = col_location[1],
|
|
col_pre = col_location[0],
|
|
col_index = col_location[2];
|
|
|
|
let top = 0,
|
|
height = 0,
|
|
rowseleted = [];
|
|
|
|
if (_this.func_selectedrange.top > row_pre) {
|
|
top = row_pre;
|
|
height = _this.func_selectedrange.top + _this.func_selectedrange.height - row_pre;
|
|
rowseleted = [row_index, _this.func_selectedrange.row[1]];
|
|
}
|
|
else if (_this.func_selectedrange.top == row_pre) {
|
|
top = row_pre;
|
|
height = _this.func_selectedrange.top + _this.func_selectedrange.height - row_pre;
|
|
rowseleted = [row_index, _this.func_selectedrange.row[0]];
|
|
}
|
|
else {
|
|
top = _this.func_selectedrange.top;
|
|
height = row - _this.func_selectedrange.top - 1;
|
|
rowseleted = [_this.func_selectedrange.row[0], row_index];
|
|
}
|
|
|
|
let left = 0,
|
|
width = 0,
|
|
columnseleted = [];
|
|
|
|
if (_this.func_selectedrange.left > col_pre) {
|
|
left = col_pre;
|
|
width = _this.func_selectedrange.left + _this.func_selectedrange.width - col_pre;
|
|
columnseleted = [col_index, _this.func_selectedrange.column[1]];
|
|
}
|
|
else if (_this.func_selectedrange.left == col_pre) {
|
|
left = col_pre;
|
|
width = _this.func_selectedrange.left + _this.func_selectedrange.width - col_pre;
|
|
columnseleted = [col_index, _this.func_selectedrange.column[0]];
|
|
}
|
|
else {
|
|
left = _this.func_selectedrange.left;
|
|
width = col - _this.func_selectedrange.left - 1;
|
|
columnseleted = [_this.func_selectedrange.column[0], col_index];
|
|
}
|
|
|
|
rowseleted[0] = luckysheetFreezen.changeFreezenIndex(rowseleted[0], "h");
|
|
rowseleted[1] = luckysheetFreezen.changeFreezenIndex(rowseleted[1], "h");
|
|
columnseleted[0] = luckysheetFreezen.changeFreezenIndex(columnseleted[0], "v");
|
|
columnseleted[1] = luckysheetFreezen.changeFreezenIndex(columnseleted[1], "v");
|
|
|
|
let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, _this.func_selectedrange, top , height, left , width);
|
|
if(changeparam != null){
|
|
columnseleted = changeparam[0];
|
|
rowseleted= changeparam[1];
|
|
top = changeparam[2];
|
|
height = changeparam[3];
|
|
left = changeparam[4];
|
|
width = changeparam[5];
|
|
}
|
|
|
|
_this.func_selectedrange["row"] = rowseleted;
|
|
_this.func_selectedrange["column"] = columnseleted;
|
|
|
|
_this.func_selectedrange["left_move"] = left;
|
|
_this.func_selectedrange["width_move"] = width;
|
|
_this.func_selectedrange["top_move"] = top;
|
|
_this.func_selectedrange["height_move"] = height;
|
|
|
|
luckysheet_count_show(left, top, width, height, rowseleted, columnseleted);
|
|
|
|
$("#luckysheet-formula-functionrange-select").css({
|
|
"left": left,
|
|
"width": width,
|
|
"top": top,
|
|
"height": height
|
|
}).show();
|
|
|
|
if($("#luckysheet-ifFormulaGenerator-multiRange-dialog").is(":visible")){
|
|
//if公式生成器 选择范围
|
|
let range = getRangetxt(Store.currentSheetIndex, { "row": rowseleted, "column": columnseleted }, Store.currentSheetIndex);
|
|
$("#luckysheet-ifFormulaGenerator-multiRange-dialog input").val(range);
|
|
}
|
|
else{
|
|
_this.rangeSetValue({
|
|
"row": rowseleted,
|
|
"column": columnseleted
|
|
});
|
|
}
|
|
|
|
luckysheetFreezen.scrollFreezen(rowseleted, columnseleted);
|
|
},
|
|
rangedrag_column_start: false,
|
|
rangedrag_row_start: false,
|
|
rangedrag_column: function(event) {
|
|
let _this = this;
|
|
|
|
let mouse = mouseposition(event.pageX, event.pageY);
|
|
let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft();
|
|
let y = mouse[1] + $("#luckysheet-cell-main").scrollTop();
|
|
|
|
let visibledatarow = Store.visibledatarow;
|
|
let row_index = visibledatarow.length - 1,
|
|
row = visibledatarow[row_index],
|
|
row_pre = 0;
|
|
|
|
let col_location = colLocation(x),
|
|
col = col_location[1],
|
|
col_pre = col_location[0],
|
|
col_index = col_location[2];
|
|
|
|
let left = 0,
|
|
width = 0,
|
|
columnseleted = [];
|
|
|
|
if (_this.func_selectedrange.left > col_pre) {
|
|
left = col_pre;
|
|
width = _this.func_selectedrange.left + _this.func_selectedrange.width - col_pre;
|
|
columnseleted = [col_index, _this.func_selectedrange.column[1]];
|
|
}
|
|
else if (_this.func_selectedrange.left == col_pre) {
|
|
left = col_pre;
|
|
width = _this.func_selectedrange.left + _this.func_selectedrange.width - col_pre;
|
|
columnseleted = [col_index, _this.func_selectedrange.column[0]];
|
|
}
|
|
else {
|
|
left = _this.func_selectedrange.left;
|
|
width = col - _this.func_selectedrange.left - 1;
|
|
columnseleted = [_this.func_selectedrange.column[0], col_index];
|
|
}
|
|
|
|
//rowseleted[0] = luckysheetFreezen.changeFreezenIndex(rowseleted[0], "h");
|
|
//rowseleted[1] = luckysheetFreezen.changeFreezenIndex(rowseleted[1], "h");
|
|
columnseleted[0] = luckysheetFreezen.changeFreezenIndex(columnseleted[0], "v");
|
|
columnseleted[1] = luckysheetFreezen.changeFreezenIndex(columnseleted[1], "v");
|
|
|
|
let changeparam = menuButton.mergeMoveMain(columnseleted, [0, row_index], _this.func_selectedrange, row_pre , row - row_pre - 1, left , width);
|
|
if(changeparam != null){
|
|
columnseleted = changeparam[0];
|
|
// rowseleted= changeparam[1];
|
|
// top = changeparam[2];
|
|
// height = changeparam[3];
|
|
left = changeparam[4];
|
|
width = changeparam[5];
|
|
}
|
|
|
|
_this.func_selectedrange["column"] = columnseleted;
|
|
_this.func_selectedrange["left_move"] = left;
|
|
_this.func_selectedrange["width_move"] = width;
|
|
|
|
luckysheet_count_show(left, row_pre, width, row - row_pre - 1, [0, row_index], columnseleted);
|
|
|
|
_this.rangeSetValue({
|
|
"row": [null, null],
|
|
"column": columnseleted
|
|
});
|
|
|
|
$("#luckysheet-formula-functionrange-select").css({
|
|
"left": left,
|
|
"width": width,
|
|
"top": row_pre,
|
|
"height": row - row_pre - 1
|
|
}).show();
|
|
|
|
luckysheetFreezen.scrollFreezen([0, row_index], columnseleted);
|
|
},
|
|
rangedrag_row: function(event) {
|
|
let _this = this;
|
|
|
|
let mouse = mouseposition(event.pageX, event.pageY);
|
|
let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft();
|
|
let y = mouse[1] + $("#luckysheet-cell-main").scrollTop();
|
|
|
|
let row_location = rowLocation(y),
|
|
row = row_location[1],
|
|
row_pre = row_location[0],
|
|
row_index = row_location[2];
|
|
|
|
let visibledatacolumn = Store.visibledatacolumn;
|
|
let col_index = visibledatacolumn.length - 1,
|
|
col = visibledatacolumn[col_index],
|
|
col_pre = 0;
|
|
|
|
let top = 0,
|
|
height = 0,
|
|
rowseleted = [];
|
|
|
|
if (_this.func_selectedrange.top > row_pre) {
|
|
top = row_pre;
|
|
height = _this.func_selectedrange.top + _this.func_selectedrange.height - row_pre;
|
|
rowseleted = [row_index, _this.func_selectedrange.row[1]];
|
|
}
|
|
else if (_this.func_selectedrange.top == row_pre) {
|
|
top = row_pre;
|
|
height = _this.func_selectedrange.top + _this.func_selectedrange.height - row_pre;
|
|
rowseleted = [row_index, _this.func_selectedrange.row[0]];
|
|
}
|
|
else {
|
|
top = _this.func_selectedrange.top;
|
|
height = row - _this.func_selectedrange.top - 1;
|
|
rowseleted = [_this.func_selectedrange.row[0], row_index];
|
|
}
|
|
|
|
rowseleted[0] = luckysheetFreezen.changeFreezenIndex(rowseleted[0], "h");
|
|
rowseleted[1] = luckysheetFreezen.changeFreezenIndex(rowseleted[1], "h");
|
|
// columnseleted[0] = luckysheetFreezen.changeFreezenIndex(columnseleted[0], "v");
|
|
// columnseleted[1] = luckysheetFreezen.changeFreezenIndex(columnseleted[1], "v");
|
|
|
|
let changeparam = menuButton.mergeMoveMain([0, col_index], rowseleted, _this.func_selectedrange, top, height, col_pre, col - col_pre - 1);
|
|
if(changeparam != null){
|
|
// columnseleted = changeparam[0];
|
|
rowseleted= changeparam[1];
|
|
top = changeparam[2];
|
|
height = changeparam[3];
|
|
// left = changeparam[4];
|
|
// width = changeparam[5];
|
|
}
|
|
|
|
_this.func_selectedrange["row"] = rowseleted;
|
|
_this.func_selectedrange["top_move"] = top;
|
|
_this.func_selectedrange["height_move"] = height;
|
|
|
|
luckysheet_count_show(col_pre, top, col - col_pre - 1, height, rowseleted, [0, col_index]);
|
|
|
|
_this.rangeSetValue({
|
|
"row": rowseleted,
|
|
"column": [null, null]
|
|
});
|
|
|
|
$("#luckysheet-formula-functionrange-select").css({
|
|
"left": col_pre,
|
|
"width": col - col_pre - 1,
|
|
"top": top,
|
|
"height": height
|
|
}).show();
|
|
|
|
luckysheetFreezen.scrollFreezen(rowseleted, [0, col_index]);
|
|
},
|
|
rangedragged: function() {},
|
|
rangeResizeObj: null,
|
|
rangeResize: null,
|
|
rangeResizeIndex: null,
|
|
rangeResizexy: null,
|
|
rangeResizeWinH: null,
|
|
rangeResizeWinW: null,
|
|
rangeResizeTo: null,
|
|
rangeResizeDraging: function(event, luckysheetCurrentChartResizeObj, luckysheetCurrentChartResizeXy, luckysheetCurrentChartResize, luckysheetCurrentChartResizeWinW, luckysheetCurrentChartResizeWinH, ch_width, rh_height) {
|
|
let _this = this;
|
|
|
|
let scrollTop = $("#luckysheet-scrollbar-y").scrollTop(),
|
|
scrollLeft = $("#luckysheet-scrollbar-x").scrollLeft();
|
|
let mouse = mouseposition(event.pageX, event.pageY);
|
|
let x = mouse[0] + scrollLeft;
|
|
let y = mouse[1] + scrollTop;
|
|
|
|
let row_location = rowLocation(y),
|
|
row = row_location[1],
|
|
row_pre = row_location[0],
|
|
row_index = row_location[2];
|
|
let col_location = colLocation(x),
|
|
col = col_location[1],
|
|
col_pre = col_location[0],
|
|
col_index = col_location[2];
|
|
|
|
if (x < 0 || y < 0) {
|
|
return false;
|
|
}
|
|
|
|
let topchange = row_pre - luckysheetCurrentChartResizeXy[1],
|
|
leftchange = col_pre - luckysheetCurrentChartResizeXy[0];
|
|
let top = luckysheetCurrentChartResizeXy[5],
|
|
height = luckysheetCurrentChartResizeXy[3],
|
|
left = luckysheetCurrentChartResizeXy[4],
|
|
width = luckysheetCurrentChartResizeXy[2];
|
|
|
|
if (luckysheetCurrentChartResize == "lt" || luckysheetCurrentChartResize == "lb") {
|
|
if (luckysheetCurrentChartResizeXy[0] + luckysheetCurrentChartResizeXy[2] < col_pre) {
|
|
return;
|
|
}
|
|
|
|
left = col_pre;
|
|
width = luckysheetCurrentChartResizeXy[2] - leftchange;
|
|
|
|
if (left > luckysheetCurrentChartResizeXy[2] + luckysheetCurrentChartResizeXy[4] - col + col_pre) {
|
|
left = luckysheetCurrentChartResizeXy[2] + luckysheetCurrentChartResizeXy[4] - col + col_pre;
|
|
width = luckysheetCurrentChartResizeXy[2] - (luckysheetCurrentChartResizeXy[2] + luckysheetCurrentChartResizeXy[4] - col + col_pre - luckysheetCurrentChartResizeXy[0]);
|
|
}
|
|
else if (left <= 0) {
|
|
left = 0;
|
|
width = luckysheetCurrentChartResizeXy[2] + luckysheetCurrentChartResizeXy[0];
|
|
}
|
|
}
|
|
|
|
if (luckysheetCurrentChartResize == "rt" || luckysheetCurrentChartResize == "rb") {
|
|
if (luckysheetCurrentChartResizeXy[6] - luckysheetCurrentChartResizeXy[2] > col) {
|
|
return;
|
|
}
|
|
|
|
width = luckysheetCurrentChartResizeXy[2] + col - luckysheetCurrentChartResizeXy[6];
|
|
|
|
if (width < col - col_pre - 1) {
|
|
width = col - col_pre - 1;
|
|
}
|
|
else if (width >= ch_width - left) {
|
|
width = ch_width - left;
|
|
}
|
|
}
|
|
|
|
if (luckysheetCurrentChartResize == "lt" || luckysheetCurrentChartResize == "rt") {
|
|
if (luckysheetCurrentChartResizeXy[1] + luckysheetCurrentChartResizeXy[3] < row_pre) {
|
|
return;
|
|
}
|
|
|
|
top = row_pre;
|
|
height = luckysheetCurrentChartResizeXy[3] - topchange;
|
|
|
|
if (top > luckysheetCurrentChartResizeXy[3] + luckysheetCurrentChartResizeXy[5] - row + row_pre) {
|
|
top = luckysheetCurrentChartResizeXy[3] + luckysheetCurrentChartResizeXy[5] - row + row_pre;
|
|
height = luckysheetCurrentChartResizeXy[3] - (luckysheetCurrentChartResizeXy[3] + luckysheetCurrentChartResizeXy[5] - row + row_pre - luckysheetCurrentChartResizeXy[1]);
|
|
}
|
|
else if (top <= 0) {
|
|
top = 0;
|
|
height = luckysheetCurrentChartResizeXy[3] + luckysheetCurrentChartResizeXy[1];
|
|
}
|
|
}
|
|
|
|
if (luckysheetCurrentChartResize == "lb" || luckysheetCurrentChartResize == "rb") {
|
|
if (luckysheetCurrentChartResizeXy[7] - luckysheetCurrentChartResizeXy[3] > row) {
|
|
return;
|
|
}
|
|
|
|
height = luckysheetCurrentChartResizeXy[3] + row - luckysheetCurrentChartResizeXy[7];
|
|
|
|
if (height < row - row_pre - 1) {
|
|
height = row - row_pre - 1;
|
|
}
|
|
else if (height >= rh_height - top) {
|
|
height = rh_height - top;
|
|
}
|
|
}
|
|
|
|
let rangeindex = _this.rangeResizeIndex;
|
|
let selected = {
|
|
"top": top,
|
|
"left": left,
|
|
"height": height,
|
|
"width": width
|
|
};
|
|
let range = _this.getSelectedFromRange(selected);
|
|
let rangetxt = getRangetxt(Store.currentSheetIndex, range, _this.rangetosheet);
|
|
let $span = _this.rangeResizeTo.find("span[rangeindex='" + rangeindex + "']").html(rangetxt);
|
|
luckysheetRangeLast(_this.rangeResizeTo[0]);
|
|
luckysheetCurrentChartResizeObj.css(selected).data("range", range);
|
|
},
|
|
getSelectedFromRange: function(obj) {
|
|
let row_st = obj.top + 2,
|
|
row_ed = obj.top + obj.height - 2;
|
|
let col_st = obj.left + 2,
|
|
col_ed = obj.left + obj.width - 2;
|
|
|
|
let ret = {
|
|
"row": [
|
|
rowLocation(row_st)[2],
|
|
rowLocation(row_ed)[2]
|
|
],
|
|
"column": [
|
|
colLocation(col_st)[2],
|
|
colLocation(col_ed)[2]
|
|
]
|
|
};
|
|
|
|
return ret;
|
|
},
|
|
rangeResizeDragged: function(event, luckysheetCurrentChartResizeObj, luckysheetCurrentChartResizeXy, luckysheetCurrentChartResize, luckysheetCurrentChartResizeWinW, luckysheetCurrentChartResizeWinH) {
|
|
let _this = this;
|
|
|
|
_this.rangeResize = null;
|
|
$("#luckysheet-formula-functionrange-highlight-" + _this.rangeResizeIndex).find(".luckysheet-selection-copy-hc").css("opacity", 0.03);
|
|
},
|
|
rangeMovexy: null,
|
|
rangeMove: false,
|
|
rangeMoveObj: null,
|
|
rangeMoveIndex: null,
|
|
rangeMoveRangedata: null,
|
|
rangeMoveDraging: function(event, luckysheet_cell_selected_move_index, luckysheet_select_save, obj, sheetBarHeight, statisticBarHeight) {
|
|
let _this = this;
|
|
|
|
let mouse = mouseposition(event.pageX, event.pageY);
|
|
let scrollLeft = $("#luckysheet-scrollbar-x").scrollLeft();
|
|
let scrollTop = $("#luckysheet-scrollbar-y").scrollTop();
|
|
let x = mouse[0] + scrollLeft;
|
|
let y = mouse[1] + scrollTop;
|
|
|
|
let winH = $(window).height() + scrollTop - sheetBarHeight - statisticBarHeight,
|
|
winW = $(window).width() + scrollLeft;
|
|
|
|
let row_index_original = luckysheet_cell_selected_move_index[0],
|
|
col_index_original = luckysheet_cell_selected_move_index[1];
|
|
let row_s = luckysheet_select_save["row"][0] - row_index_original + rowLocation(y)[2],
|
|
row_e = luckysheet_select_save["row"][1] - row_index_original + rowLocation(y)[2];
|
|
let col_s = luckysheet_select_save["column"][0] - col_index_original + colLocation(x)[2],
|
|
col_e = luckysheet_select_save["column"][1] - col_index_original + colLocation(x)[2];
|
|
|
|
if (row_s < 0 || y < 0) {
|
|
row_s = 0;
|
|
row_e = luckysheet_select_save["row"][1] - luckysheet_select_save["row"][0];
|
|
}
|
|
if (col_s < 0 || x < 0) {
|
|
col_s = 0;
|
|
col_e = luckysheet_select_save["column"][1] - luckysheet_select_save["column"][0];
|
|
}
|
|
|
|
let visibledatarow = Store.visibledatarow;
|
|
if (row_e >= visibledatarow[visibledatarow.length - 1] || y > winH) {
|
|
row_s = visibledatarow.length - 1 - luckysheet_select_save["row"][1] + luckysheet_select_save["row"][0];
|
|
row_e = visibledatarow.length - 1;
|
|
}
|
|
let visibledatacolumn = Store.visibledatacolumn;
|
|
if (col_e >= visibledatacolumn[visibledatacolumn.length - 1] || x > winW) {
|
|
col_s = visibledatacolumn.length - 1 - luckysheet_select_save["column"][1] + luckysheet_select_save["column"][0];
|
|
col_e = visibledatacolumn.length - 1;
|
|
}
|
|
|
|
let col_pre = col_s - 1 == -1 ? 0 : visibledatacolumn[col_s - 1],
|
|
col = visibledatacolumn[col_e];
|
|
let row_pre = row_s - 1 == -1 ? 0 : visibledatarow[row_s - 1],
|
|
row = visibledatarow[row_e];
|
|
let rangeindex = _this.rangeMoveIndex;
|
|
let selected = {
|
|
"left": col_pre,
|
|
"width": col - col_pre - 2,
|
|
"top": row_pre,
|
|
"height": row - row_pre - 2,
|
|
"display": "block"
|
|
};
|
|
let range = _this.getSelectedFromRange(selected);
|
|
let rangetxt = getRangetxt(Store.currentSheetIndex, range, _this.rangetosheet);
|
|
let $span = _this.rangeResizeTo.find("span[rangeindex='" + rangeindex + "']").html(rangetxt);
|
|
luckysheetRangeLast(_this.rangeResizeTo[0]);
|
|
_this.rangeMoveRangedata = range;
|
|
obj.css(selected);
|
|
},
|
|
rangeMoveDragged: function(obj) {
|
|
let _this = this;
|
|
|
|
_this.rangeMove = false;
|
|
$("#luckysheet-formula-functionrange-highlight-" + _this.rangeMoveIndex).data("range", _this.rangeMoveRangedata).find(".luckysheet-selection-copy-hc").css("opacity", 0.03);
|
|
},
|
|
functionHTMLIndex: 0,
|
|
functionRangeIndex: null,
|
|
findrangeindex: function(v, vp) {
|
|
let _this = this;
|
|
|
|
let re = /<span.*?>/g;
|
|
let v_a = v.replace(re, ""),
|
|
vp_a = vp.replace(re, "");
|
|
v_a = v_a.split('</span>');
|
|
vp_a = vp_a.split('</span>');
|
|
v_a.pop();
|
|
vp_a.pop();
|
|
|
|
let pfri = _this.functionRangeIndex;
|
|
let i = 0;
|
|
let spanlen = vp_a.length > v_a.length ? v_a.length : vp_a.length;
|
|
|
|
let vplen = vp_a.length, vlen = v_a.length;
|
|
//不增加元素输入
|
|
if(vplen == vlen){
|
|
let i = pfri[0];
|
|
let p = vp_a[i], n = v_a[i];
|
|
|
|
if(p == null){
|
|
if(vp_a.length <= i){
|
|
pfri = [vp_a.length - 1, vp_a.length - 1];
|
|
}
|
|
else if(v_a.length<=i){
|
|
pfri = [v_a.length - 1, v_a.length - 1];
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
else if(p.length == n.length){
|
|
if(vp_a[i + 1] != null && v_a[i + 1] != null && vp_a[i + 1].length < v_a[i + 1].length){
|
|
pfri[0] = pfri[0] + 1;
|
|
pfri[1] = 1;
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
else if(p.length > n.length){
|
|
if(p != null && v_a[i + 1] != null && v_a[i + 1].substr(0,1) == '"' && (p.indexOf("{") > -1 || p.indexOf("}") > -1)){
|
|
pfri[0] = pfri[0] + 1;
|
|
pfri[1] = 1;
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
else if(p.length < n.length){
|
|
if(pfri[1] > n.length){
|
|
pfri[1] = n.length;
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
}
|
|
//减少元素输入
|
|
else if(vplen > vlen){
|
|
let i = pfri[0];
|
|
let p = vp_a[i], n = v_a[i];
|
|
|
|
if(n == null){
|
|
if(v_a[i - 1].indexOf("{") > -1){
|
|
pfri[0] = pfri[0] -1;
|
|
let start = v_a[i - 1].search("{");
|
|
pfri[1] = pfri[1] + start;
|
|
}
|
|
else{
|
|
pfri[0] = 0;
|
|
pfri[1] = 0;
|
|
}
|
|
}
|
|
else if(p.length == n.length){
|
|
if(v_a[i + 1] != null && (v_a[i + 1].substr(0,1) == '"' || v_a[i + 1].substr(0,1) == '{' || v_a[i + 1].substr(0,1) == '}')){
|
|
pfri[0] = pfri[0] + 1;
|
|
pfri[1] = 1;
|
|
}
|
|
else if(p != null && p.length > 2 && p.substr(0,1) == '"' && p.substr(p.length - 1, 1) == '"' ){
|
|
//pfri[1] = n.length-1;
|
|
}
|
|
else if(v_a[i] != null && v_a[i] == '")'){
|
|
pfri[1] = 1;
|
|
}
|
|
else if(v_a[i] != null && v_a[i] == '"}'){
|
|
pfri[1] = 1;
|
|
}
|
|
else if(v_a[i] != null && v_a[i] == '{)'){
|
|
pfri[1] = 1;
|
|
}
|
|
else{
|
|
pfri[1] = n.length;
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
else if(p.length > n.length){
|
|
if(v_a[i + 1] != null && (v_a[i + 1].substr(0,1) == '"' || v_a[i + 1].substr(0,1) == '{' || v_a[i+1].substr(0,1) == '}')){
|
|
pfri[0] = pfri[0] + 1;
|
|
pfri[1] = 1;
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
else if(p.length < n.length){
|
|
return pfri;
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
//增加元素输入
|
|
else if(vplen < vlen){
|
|
let i = pfri[0];
|
|
let p = vp_a[i], n = v_a[i];
|
|
|
|
if(p == null){
|
|
pfri[0] = v_a.length - 1;
|
|
|
|
if(n != null){
|
|
pfri[1] = n.length;
|
|
}
|
|
else{
|
|
pfri[1] = 1;
|
|
}
|
|
}
|
|
else if(p.length == n.length){
|
|
if(vp_a[i + 1] != null && (vp_a[i + 1].substr(0, 1) == '"' || vp_a[i + 1].substr(0, 1) == '{' || vp_a[i + 1].substr(0, 1) == '}') ){
|
|
pfri[1] = n.length;
|
|
}
|
|
else if(v_a[i + 1] != null && v_a[i + 1].substr(0, 1) == '"' && ( v_a[i + 1].substr(0, 1) == '{' || v_a[i + 1].substr(0, 1) == '}') ){
|
|
pfri[0] = pfri[0] + 1;
|
|
pfri[1] = 1;
|
|
}
|
|
else if(n != null && n.substr(0, 1) == '"' && n.substr(n.length - 1, 1) == '"' && p.substr(0, 1) == '"' && p.substr(p.length - 1, 1) == ')'){
|
|
pfri[1] = n.length;
|
|
}
|
|
else if(n != null && n.substr(0, 1) == '{' && n.substr(n.length - 1, 1) == '}' && p.substr(0, 1) == '{' && p.substr(p.length - 1, 1) == ')'){
|
|
pfri[1] = n.length;
|
|
}
|
|
else{
|
|
pfri[0] = pfri[0] + vlen - vplen;
|
|
if(v_a.length > vp_a.length){
|
|
pfri[1] = v_a[i + 1].length;
|
|
}
|
|
else{
|
|
pfri[1] = 1;
|
|
}
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
else if(p.length > n.length){
|
|
if(p != null && p.substr(0, 1) == '"'){
|
|
pfri[1] = n.length;
|
|
}
|
|
else if(v_a[i + 1] != null && /{.*?}/.test(v_a[i + 1])){
|
|
pfri[0] = pfri[0] + 1;
|
|
pfri[1] = v_a[i + 1].length;
|
|
}
|
|
else if(p != null && v_a[i + 1].substr(0, 1) == '"' && (p.indexOf("{") > -1 || p.indexOf("}") > -1)){
|
|
pfri[0] = pfri[0] + 1;
|
|
pfri[1] = 1;
|
|
}
|
|
else if(p != null && (p.indexOf("{") > -1 || p.indexOf("}") > -1)){
|
|
|
|
}
|
|
else{
|
|
pfri[0] = pfri[0] + vlen - vplen - 1;
|
|
pfri[1] = v_a[i - 1].length;
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
else if(p.length < n.length){
|
|
return pfri;
|
|
}
|
|
|
|
return pfri;
|
|
}
|
|
|
|
return null;
|
|
},
|
|
setCaretPosition: function(textDom, children, pos) {
|
|
try{
|
|
let el = textDom;
|
|
let range = document.createRange();
|
|
let sel = window.getSelection();
|
|
range.setStart(el.childNodes[children], pos);
|
|
range.collapse(true);
|
|
sel.removeAllRanges();
|
|
sel.addRange(range);
|
|
el.focus();
|
|
}
|
|
catch(err) {
|
|
luckysheetRangeLast(this.rangeResizeTo[0]);
|
|
}
|
|
},
|
|
functionRange: function(obj, v, vp) {
|
|
let _this = this;
|
|
|
|
if (window.getSelection) { //ie11 10 9 ff safari
|
|
let currSelection = window.getSelection();
|
|
let fri = _this.findrangeindex(v, vp);
|
|
|
|
if (fri == null) {
|
|
currSelection.selectAllChildren(obj.get(0));
|
|
currSelection.collapseToEnd();
|
|
}
|
|
else {
|
|
_this.setCaretPosition(obj.find("span").get(fri[0]), 0, fri[1]);
|
|
}
|
|
}
|
|
else if (document.selection) { //ie10 9 8 7 6 5
|
|
_this.functionRangeIndex.moveToElementText(obj); //range定位到obj
|
|
_this.functionRangeIndex.collapse(false); //光标移至最后
|
|
_this.functionRangeIndex.select();
|
|
}
|
|
},
|
|
functionInputHanddler: function($to, $input, kcode) {
|
|
if(isEditMode()){//此模式下禁用公式栏
|
|
return;
|
|
}
|
|
|
|
let _this = this;
|
|
|
|
let $copy = $to,
|
|
$editer = $input;
|
|
let value1 = $editer.html(),
|
|
value1txt = $editer.text();
|
|
|
|
setTimeout(function() {
|
|
let value = $editer.text(),
|
|
valuetxt = value;
|
|
|
|
if (value.length > 0 && value.substr(0, 1) == "=" && (kcode != 229 || value.length == 1)) {
|
|
value = _this.functionHTMLGenerate(value);
|
|
value1 = _this.functionHTMLGenerate(value1txt);
|
|
|
|
if (window.getSelection) { // all browsers, except IE before version 9
|
|
let currSelection = window.getSelection();
|
|
if($(currSelection.anchorNode).is("div")){
|
|
let editorlen = $("#luckysheet-rich-text-editor span").length;
|
|
_this.functionRangeIndex = [editorlen-1, $("#luckysheet-rich-text-editor").find("span").eq(editorlen-1).text().length];
|
|
}
|
|
else{
|
|
_this.functionRangeIndex = [$(currSelection.anchorNode).parent().index(), currSelection.anchorOffset];
|
|
}
|
|
}
|
|
else { // Internet Explorer before version 9
|
|
let textRange = document.selection.createRange();
|
|
_this.functionRangeIndex = textRange;
|
|
}
|
|
|
|
$editer.html(value);
|
|
_this.functionRange($editer, value, value1);
|
|
_this.canceFunctionrangeSelected();
|
|
|
|
if(kcode != 46){//delete不执行此函数
|
|
_this.createRangeHightlight();
|
|
}
|
|
|
|
$copy.html(value);
|
|
_this.rangestart = false;
|
|
_this.rangedrag_column_start = false;
|
|
_this.rangedrag_row_start = false;
|
|
|
|
_this.rangeHightlightselected($editer, kcode);
|
|
|
|
}
|
|
else if(value1txt.substr(0, 1) != "=" ){
|
|
//&& value1.indexOf("span")>-1
|
|
// $editer.html(value1);
|
|
|
|
// let w = window.getSelection();
|
|
// if(w!=null && w.type!="None"){
|
|
// let range = w.getRangeAt(0);
|
|
// let c = range.startContainer;
|
|
|
|
// if(c.id=="luckysheet-rich-text-editor" || $(c).closest("#luckysheet-rich-text-editor")){
|
|
// $functionbox.html(value);
|
|
// }
|
|
// else if(c.id=="luckysheet-functionbox-cell" || $(c).closest("#luckysheet-functionbox-cell")){
|
|
// if(value1.indexOf("span")>-1){
|
|
|
|
// }
|
|
// else{
|
|
// $editer.html(value);
|
|
// }
|
|
// }
|
|
|
|
// }
|
|
// console.trace();
|
|
// console.log(value, $copy.attr("id"));
|
|
|
|
if($copy.attr("id")=="luckysheet-rich-text-editor"){
|
|
if($copy.html().substr(0,5) == "<span"){
|
|
|
|
}
|
|
else{
|
|
$copy.html(value);
|
|
}
|
|
}
|
|
else{
|
|
$copy.html(value);
|
|
}
|
|
}
|
|
|
|
|
|
}, 1);
|
|
},
|
|
functionHTMLGenerate: function(txt) {
|
|
let _this = this;
|
|
|
|
if (txt.length == 0 || txt.substr(0, 1) != "=") {
|
|
return txt;
|
|
}
|
|
|
|
_this.functionHTMLIndex = 0;
|
|
|
|
return '<span dir="auto" class="luckysheet-formula-text-color">=</span>' + _this.functionHTML(txt);
|
|
},
|
|
functionHTML: function(txt) {
|
|
let _this = this;
|
|
|
|
if (_this.operatorjson == null) {
|
|
let arr = _this.operator.split("|"),
|
|
op = {};
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
op[arr[i].toString()] = 1;
|
|
}
|
|
|
|
_this.operatorjson = op;
|
|
}
|
|
|
|
if (txt.substr(0, 1) == "=") {
|
|
txt = txt.substr(1);
|
|
}
|
|
|
|
let funcstack = txt.split("");
|
|
let i = 0,
|
|
str = "",
|
|
function_str = "",
|
|
ispassby = true;
|
|
let matchConfig = {
|
|
"bracket": 0,
|
|
"comma": 0,
|
|
"squote": 0,
|
|
"dquote": 0,
|
|
"braces": 0
|
|
}
|
|
|
|
while (i < funcstack.length) {
|
|
let s = funcstack[i];
|
|
|
|
if (s == "(" && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
matchConfig.bracket += 1;
|
|
|
|
if (str.length > 0) {
|
|
function_str += '<span dir="auto" class="luckysheet-formula-text-func">' + str + '</span><span dir="auto" class="luckysheet-formula-text-lpar">(</span>';
|
|
}
|
|
else {
|
|
function_str += '<span dir="auto" class="luckysheet-formula-text-lpar">(</span>';
|
|
}
|
|
|
|
str = "";
|
|
}
|
|
else if (s == ")" && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
matchConfig.bracket -= 1;
|
|
function_str += _this.functionHTML(str) + '<span dir="auto" class="luckysheet-formula-text-rpar">)</span>';
|
|
str = "";
|
|
}
|
|
else if(s=="{" && matchConfig.dquote == 0) {
|
|
str += '{';
|
|
matchConfig.braces += 1;
|
|
}
|
|
else if(s=="}" && matchConfig.dquote == 0) {
|
|
str += '}';
|
|
matchConfig.braces -= 1;
|
|
}
|
|
else if (s == '"' && matchConfig.squote == 0) {
|
|
if (matchConfig.dquote > 0) {
|
|
if (str.length > 0) {
|
|
function_str += str + '"</span>';
|
|
}
|
|
else {
|
|
function_str += '"</span>';
|
|
}
|
|
|
|
matchConfig.dquote -= 1;
|
|
str = "";
|
|
}
|
|
else {
|
|
matchConfig.dquote += 1;
|
|
|
|
if (str.length > 0) {
|
|
function_str += _this.functionHTML(str) + '<span dir="auto" class="luckysheet-formula-text-string">"';
|
|
}
|
|
else {
|
|
function_str += '<span dir="auto" class="luckysheet-formula-text-string">"';
|
|
}
|
|
|
|
str = "";
|
|
}
|
|
}
|
|
else if (s == ',' && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
//matchConfig.comma += 1;
|
|
function_str += _this.functionHTML(str) + '<span dir="auto" class="luckysheet-formula-text-comma">,</span>';
|
|
str = "";
|
|
}
|
|
else if (s == '&' && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
if (str.length > 0) {
|
|
function_str += _this.functionHTML(str) + '<span dir="auto" class="luckysheet-formula-text-calc">' + '&' + '</span>';;
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += '<span dir="auto" class="luckysheet-formula-text-calc">' + '&' + '</span>';
|
|
}
|
|
}
|
|
else if (s in _this.operatorjson && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
let s_next = "";
|
|
if ((i + 1) < funcstack.length) {
|
|
s_next = funcstack[i + 1];
|
|
}
|
|
|
|
let p = i-1, s_pre = null;;
|
|
if(p >= 0){
|
|
do {
|
|
s_pre = funcstack[p--];
|
|
}
|
|
while (p >= 0 && s_pre ==" ")
|
|
}
|
|
|
|
if ((s + s_next) in _this.operatorjson) {
|
|
if (str.length > 0) {
|
|
function_str += _this.functionHTML(str) + '<span dir="auto" class="luckysheet-formula-text-calc">' + s + s_next + '</span>';
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += '<span dir="auto" class="luckysheet-formula-text-calc">' + s + s_next + '</span>';
|
|
}
|
|
|
|
i++;
|
|
}
|
|
else if(!(/[^0-9]/.test(s_next)) && s=="-" && (s_pre=="(" || s_pre == null || s_pre == "," || s_pre == " " || s_pre in _this.operatorjson ) ){
|
|
str += s;
|
|
}
|
|
else {
|
|
if (str.length > 0) {
|
|
function_str += _this.functionHTML(str) + '<span dir="auto" class="luckysheet-formula-text-calc">' + s + '</span>';
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += '<span dir="auto" class="luckysheet-formula-text-calc">' + s + '</span>';
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
|
|
if (i == funcstack.length - 1) {
|
|
//function_str += str;
|
|
if (_this.iscelldata($.trim(str))) {
|
|
function_str += '<span class="luckysheet-formula-functionrange-cell" rangeindex="' + _this.functionHTMLIndex + '" dir="auto" style="color:' + luckyColor[_this.functionHTMLIndex] + ';">' + str + '</span>';
|
|
_this.functionHTMLIndex++;
|
|
}
|
|
else if (matchConfig.dquote > 0) {
|
|
function_str += str + '</span>';
|
|
}
|
|
else if (str.indexOf("</span>") == -1 && str.length > 0) {
|
|
let regx = /{.*?}/;
|
|
|
|
if(regx.test($.trim(str))){
|
|
let arraytxt = regx.exec(str)[0];
|
|
let arraystart = str.search(regx);
|
|
let alltxt = "";
|
|
|
|
if(arraystart > 0){
|
|
alltxt += '<span dir="auto" class="luckysheet-formula-text-color">' + str.substr(0, arraystart) + '</span>';
|
|
}
|
|
|
|
alltxt += '<span dir="auto" style="color:#959a05" class="luckysheet-formula-text-array">' + arraytxt + '</span>';
|
|
|
|
if(arraystart + arraytxt.length < str.length){
|
|
alltxt += '<span dir="auto" class="luckysheet-formula-text-color">' + str.substr(arraystart + arraytxt.length, str.length) + '</span>';
|
|
}
|
|
|
|
function_str += alltxt;
|
|
}
|
|
else{
|
|
function_str += '<span dir="auto" class="luckysheet-formula-text-color">' + str + '</span>';
|
|
}
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return function_str;
|
|
},
|
|
getfunctionParam: function(txt) {
|
|
let _this = this;
|
|
|
|
if (_this.operatorjson == null) {
|
|
let arr = _this.operator.split("|"),
|
|
op = {};
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
op[arr[i].toString()] = 1;
|
|
}
|
|
|
|
_this.operatorjson = op;
|
|
}
|
|
|
|
if (txt.substr(0, 1) == "=") {
|
|
txt = txt.substr(1);
|
|
}
|
|
|
|
let funcstack = txt.split("");
|
|
let i = 0,
|
|
str = "",
|
|
function_str = "";
|
|
let matchConfig = {
|
|
"bracket": 0,
|
|
"comma": 0,
|
|
"squote": 0,
|
|
"dquote": 0,
|
|
"compare": 0
|
|
}
|
|
|
|
//bracket 0为运算符括号、1为函数括号
|
|
let fn = null, param = [], bracket = [];
|
|
|
|
while (i < funcstack.length) {
|
|
let s = funcstack[i];
|
|
|
|
if (s == "(" && matchConfig.dquote == 0) {
|
|
if (str.length > 0 && bracket.length==0) {
|
|
fn = str.toUpperCase();
|
|
bracket.push(1);
|
|
str = "";
|
|
}
|
|
else if(bracket.length==0) {
|
|
//function_str += "(";
|
|
bracket.push(0);
|
|
str = "";
|
|
}
|
|
else{
|
|
bracket.push(0);
|
|
str += s;
|
|
}
|
|
}
|
|
else if (s == ")" && matchConfig.dquote == 0) {
|
|
let bt = bracket.pop();
|
|
|
|
if(bracket.length == 0){
|
|
param.push(str);
|
|
str = "";
|
|
}
|
|
else{
|
|
str += s;
|
|
}
|
|
}
|
|
else if (s == '"') {
|
|
str += '"';
|
|
|
|
if (matchConfig.dquote > 0) {
|
|
matchConfig.dquote -= 1;
|
|
str = "";
|
|
}
|
|
else {
|
|
matchConfig.dquote += 1;
|
|
}
|
|
}
|
|
else if (s == ',' && matchConfig.dquote == 0) {
|
|
if(bracket.length <= 1){
|
|
param.push(str);
|
|
str = "";
|
|
}
|
|
else{
|
|
str += ",";
|
|
}
|
|
}
|
|
else if (s in _this.operatorjson && matchConfig.dquote == 0) {
|
|
let s_next = "";
|
|
if ((i + 1) < funcstack.length) {
|
|
s_next = funcstack[i + 1];
|
|
}
|
|
|
|
let p = i-1, s_pre = null;;
|
|
if(p >= 0){
|
|
do {
|
|
s_pre = funcstack[p--];
|
|
}
|
|
while (p >= 0 && s_pre ==" ")
|
|
}
|
|
|
|
if(!(/[^0-9]/.test(s_next)) && s=="-" && (s_pre=="(" || s_pre == null || s_pre == "," || s_pre == " " || s_pre in _this.operatorjson ) ){
|
|
if (matchConfig.dquote == 0) {
|
|
str += $.trim(s);
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
}
|
|
else{
|
|
function_str= "";
|
|
str = "";
|
|
}
|
|
}
|
|
else {
|
|
if (matchConfig.dquote == 0) {
|
|
str += $.trim(s);
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return {"fn": fn, "param": param};
|
|
},
|
|
calPostfixExpression: function(cal){
|
|
if(cal.length == 0){
|
|
return "";
|
|
}
|
|
|
|
let stack = [];
|
|
for(let i = cal.length - 1; i >= 0; i--){
|
|
let c = cal[i];
|
|
if(c in this.operatorjson){
|
|
let s2 = stack.pop();
|
|
let s1 = stack.pop();
|
|
|
|
let str = "luckysheet_compareWith(" + s1 + ",'" + c + "', " + s2 + ")";
|
|
|
|
stack.push(str);
|
|
}
|
|
else{
|
|
stack.push(c);
|
|
}
|
|
}
|
|
|
|
if(stack.length > 0){
|
|
return stack[0];
|
|
}
|
|
else{
|
|
return "";
|
|
}
|
|
},
|
|
checkBracketNum: function(fp){
|
|
let bra_l = fp.match(/\(/g),
|
|
bra_r = fp.match(/\)/g),
|
|
bra_tl_txt = fp.match(/(['"])(?:(?!\1).)*?\1/g),
|
|
bra_tr_txt = fp.match(/(['"])(?:(?!\1).)*?\1/g);
|
|
|
|
let bra_l_len = 0, bra_r_len = 0;
|
|
if (bra_l != null) {
|
|
bra_l_len += bra_l.length;
|
|
}
|
|
if (bra_r != null) {
|
|
bra_r_len += bra_r.length;
|
|
}
|
|
|
|
let bra_tl_len = 0, bra_tr_len = 0;
|
|
if(bra_tl_txt != null){
|
|
for(let i = 0; i < bra_tl_txt.length; i++){
|
|
let bra_tl = bra_tl_txt[i].match(/\(/g);
|
|
if (bra_tl != null) {
|
|
bra_tl_len += bra_tl.length;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bra_tr_txt != null){
|
|
for(let i = 0; i < bra_tr_txt.length; i++){
|
|
let bra_tr = bra_tr_txt[i].match(/\)/g);
|
|
if (bra_tr != null) {
|
|
bra_tr_len += bra_tr.length;
|
|
}
|
|
}
|
|
}
|
|
|
|
bra_l_len -= bra_tl_len;
|
|
bra_r_len -= bra_tr_len;
|
|
|
|
if(bra_l_len != bra_r_len){
|
|
return false;
|
|
}
|
|
else{
|
|
return true;
|
|
}
|
|
},
|
|
operatorPriority: {
|
|
"^": 0,
|
|
"%": 1,
|
|
"*": 1,
|
|
"/": 1,
|
|
"+": 2,
|
|
"-": 2
|
|
},
|
|
functionParserExe:function(txt){
|
|
let _this = this;
|
|
// let txt1 = txt.toUpperCase();
|
|
// return this.functionParser(txt, function(c){
|
|
// _this.addToCellList(txt, c);
|
|
// });
|
|
return this.functionParser(txt);
|
|
},
|
|
functionParser: function(txt, cellRangeFunction) {
|
|
let _this = this;
|
|
|
|
if (_this.operatorjson == null) {
|
|
let arr = _this.operator.split("|"),
|
|
op = {};
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
op[arr[i].toString()] = 1;
|
|
}
|
|
|
|
_this.operatorjson = op;
|
|
}
|
|
|
|
if(txt==null){
|
|
return "";
|
|
}
|
|
|
|
if (txt.substr(0, 2) == "=+") {
|
|
txt = txt.substr(2);
|
|
}
|
|
else if (txt.substr(0, 1) == "=") {
|
|
txt = txt.substr(1);
|
|
}
|
|
|
|
let funcstack = txt.split("");
|
|
let i = 0,
|
|
str = "",
|
|
function_str = "";
|
|
|
|
let matchConfig = {
|
|
"bracket": 0,
|
|
"comma": 0,
|
|
"squote": 0,
|
|
"dquote": 0,
|
|
"compare": 0,
|
|
"braces": 0
|
|
}
|
|
|
|
//=(sum(b1:c10)+10)*5-100
|
|
|
|
//=MAX(B1:C10,10)*5-100
|
|
|
|
// =(sum(max(B1:C10,10)*5-100,((1+1)*2+5)/2,10)+count(B1:C10,10*5-100))*5-100
|
|
|
|
//=SUM(MAX(B1:C10,10)*5-100,((1+1)*2+5)/2,10)+COUNT(B1:C10,10*5-100)
|
|
|
|
//=SUM(MAX(B1:C10,10)*5-100,((1+1)*2+5)/2,10)
|
|
|
|
//=SUM(10,((1+1)*2+5)/2,10)
|
|
|
|
//=SUM(MAX(B1:C10,10)*5-100)
|
|
|
|
//=IFERROR(IF(ROW()-ROW($G$3)=1,$F4+$D4,SUM($D1:INDEX($D$4:$D$9,1,1),$F1:INDEX($F$4:$F$9,1,1))), "")
|
|
|
|
//=IFERROR(IF(ROW()-ROW($G$3)=1,$F4+$D4,SUM(INDEX($D$4:$D$9,1,1):$D4,INDEX($F$4:$F$9,1,1):$F4)), "")
|
|
|
|
//=SUM(I$4:OFFSET(I10,0,0))
|
|
|
|
//bracket 0为运算符括号、1为函数括号
|
|
let cal1 = [], cal2 = [], bracket = [];
|
|
|
|
while (i < funcstack.length) {
|
|
let s = funcstack[i];
|
|
|
|
if (s == "(" && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
if (str.length > 0 && bracket.length == 0) {
|
|
str = str.toUpperCase();
|
|
if(str.indexOf(":")>-1){
|
|
let funcArray = str.split(":");
|
|
function_str += "luckysheet_getSpecialReference(true,'"+ $.trim(funcArray[0]).replace(/'/g, "\\'") +"', luckysheet_function." + funcArray[1] + ".f(#lucky#";
|
|
}
|
|
else{
|
|
function_str += "luckysheet_function." + str + ".f(";
|
|
}
|
|
bracket.push(1);
|
|
str = "";
|
|
}
|
|
else if(bracket.length == 0) {
|
|
function_str += "(";
|
|
bracket.push(0);
|
|
str = "";
|
|
}
|
|
else{
|
|
bracket.push(0);
|
|
str += s;
|
|
}
|
|
}
|
|
else if (s == ")" && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
let bt = bracket.pop();
|
|
|
|
if(bracket.length == 0){
|
|
let functionS = _this.functionParser(str,cellRangeFunction);
|
|
if(functionS.indexOf("#lucky#")>-1){
|
|
functionS = functionS.replace(/#lucky#/g, "") + ")";
|
|
}
|
|
function_str += functionS + ")";
|
|
str = "";
|
|
}
|
|
else{
|
|
str += s;
|
|
}
|
|
}
|
|
else if(s == "{" && matchConfig.dquote == 0){
|
|
str += '{';
|
|
matchConfig.braces += 1;
|
|
}
|
|
else if(s == "}" && matchConfig.dquote == 0){
|
|
str += '}';
|
|
matchConfig.braces -= 1;
|
|
}
|
|
else if (s == '"') {
|
|
str += '"';
|
|
|
|
if (matchConfig.dquote > 0) {
|
|
matchConfig.dquote -= 1;
|
|
}
|
|
else {
|
|
matchConfig.dquote += 1;
|
|
}
|
|
}
|
|
else if (s == "'") {
|
|
str += "'";
|
|
|
|
if (matchConfig.squote > 0) {
|
|
matchConfig.squote -= 1;
|
|
}
|
|
else {
|
|
matchConfig.squote += 1;
|
|
}
|
|
}
|
|
else if (s == ',' && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
if(bracket.length <= 1){
|
|
let functionS = _this.functionParser(str,cellRangeFunction);
|
|
if(functionS.indexOf("#lucky#")>-1){
|
|
functionS = functionS.replace(/#lucky#/g, "") + ")";
|
|
}
|
|
function_str += functionS + ",";
|
|
str = "";
|
|
}
|
|
else{
|
|
str += ",";
|
|
}
|
|
}
|
|
else if (s in _this.operatorjson && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
let s_next = "";
|
|
let op = _this.operatorPriority;
|
|
|
|
if ((i + 1) < funcstack.length) {
|
|
s_next = funcstack[i + 1];
|
|
}
|
|
|
|
if ((s + s_next) in _this.operatorjson) {
|
|
if(bracket.length == 0){
|
|
if($.trim(str).length > 0){
|
|
cal2.unshift(_this.functionParser($.trim(str),cellRangeFunction));
|
|
}
|
|
else if($.trim(function_str).length > 0){
|
|
cal2.unshift($.trim(function_str));
|
|
}
|
|
|
|
if(cal1[0] in _this.operatorjson){
|
|
let stackCeilPri = op[cal1[0]];
|
|
|
|
while(cal1.length > 0 && stackCeilPri != null){
|
|
cal2.unshift(cal1.shift());
|
|
stackCeilPri = op[cal1[0]];
|
|
}
|
|
}
|
|
|
|
cal1.unshift(s+s_next);
|
|
|
|
function_str= "";
|
|
str = "";
|
|
}
|
|
else {
|
|
str += s + s_next;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
else {
|
|
if(bracket.length == 0){
|
|
if($.trim(str).length > 0){
|
|
cal2.unshift(_this.functionParser($.trim(str),cellRangeFunction));
|
|
}
|
|
else if($.trim(function_str).length > 0){
|
|
cal2.unshift($.trim(function_str));
|
|
}
|
|
|
|
if(cal1[0] in _this.operatorjson){
|
|
let stackCeilPri = op[cal1[0]];
|
|
stackCeilPri = stackCeilPri == null ? 1000 : stackCeilPri;
|
|
|
|
let sPri = op[s];
|
|
sPri = sPri == null ? 1000 : sPri;
|
|
|
|
while(cal1.length > 0 && sPri >= stackCeilPri){
|
|
cal2.unshift(cal1.shift());
|
|
|
|
stackCeilPri = op[cal1[0]];
|
|
stackCeilPri = stackCeilPri == null ? 1000 : stackCeilPri;
|
|
}
|
|
}
|
|
|
|
cal1.unshift(s);
|
|
|
|
function_str= "";
|
|
str = "";
|
|
}
|
|
else{
|
|
str += s;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (matchConfig.dquote == 0 && matchConfig.squote==0) {
|
|
// str += $.trim(s);
|
|
str += s; //Do not use $.trim(s). When obtaining the worksheet name that contains spaces, you should keep the spaces
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
}
|
|
|
|
if (i == funcstack.length - 1) {
|
|
let endstr = "";
|
|
let str_nb = $.trim(str).replace(/'/g, "\\'");
|
|
if (_this.iscelldata(str_nb) && str_nb.substr(0,1)!=":") {
|
|
|
|
endstr = "luckysheet_getcelldata('" +str_nb + "')";
|
|
if(typeof(cellRangeFunction)=="function"){
|
|
cellRangeFunction(str_nb);
|
|
}
|
|
|
|
}
|
|
else if(str_nb.substr(0,1)==":"){
|
|
str_nb = str_nb.substr(1);
|
|
if(_this.iscelldata(str_nb)){
|
|
endstr = "luckysheet_getSpecialReference(false," + function_str +",'"+ str_nb +"')";
|
|
}
|
|
}
|
|
else {
|
|
str = $.trim(str);
|
|
|
|
let regx = /{.*?}/;
|
|
if(regx.test(str) && str.substr(0, 1) != '"' && str.substr(str.length - 1, 1) != '"'){
|
|
let arraytxt = regx.exec(str)[0];
|
|
let arraystart = str.search(regx);
|
|
let alltxt = "";
|
|
|
|
if(arraystart > 0){
|
|
endstr += str.substr(0, arraystart);
|
|
}
|
|
|
|
endstr += "luckysheet_getarraydata('" + arraytxt + "')";
|
|
|
|
if(arraystart + arraytxt.length < str.length){
|
|
endstr += str.substr(arraystart + arraytxt.length, str.length);
|
|
}
|
|
}
|
|
else{
|
|
endstr = str;
|
|
}
|
|
}
|
|
|
|
if(endstr.length > 0){
|
|
cal2.unshift(endstr);
|
|
}
|
|
|
|
if(cal1.length > 0){
|
|
if(function_str.length > 0){
|
|
cal2.unshift(function_str);
|
|
function_str = "";
|
|
}
|
|
|
|
while(cal1.length > 0){
|
|
cal2.unshift(cal1.shift());
|
|
}
|
|
}
|
|
|
|
if(cal2.length > 0){
|
|
function_str = _this.calPostfixExpression(cal2);
|
|
}
|
|
else{
|
|
function_str += endstr;
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
// console.log(function_str);
|
|
return function_str;
|
|
},
|
|
insertUpdateDynamicArray: function(dynamicArrayItem) {
|
|
let r = dynamicArrayItem.r , c = dynamicArrayItem.c, index = dynamicArrayItem.index;
|
|
if (index == null) {
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
|
|
let luckysheetfile = getluckysheetfile();
|
|
let file = luckysheetfile[getSheetIndex(index)];
|
|
|
|
let dynamicArray = file.dynamicArray;
|
|
if (dynamicArray == null) {
|
|
dynamicArray = [];
|
|
}
|
|
|
|
for (let i = 0; i < dynamicArray.length; i++) {
|
|
let calc = dynamicArray[i];
|
|
if (calc.r == r && calc.c == c && calc.index == index) {
|
|
calc.data = dynamicArrayItem.data;
|
|
calc.f = dynamicArrayItem.f;
|
|
return dynamicArray;
|
|
}
|
|
}
|
|
|
|
dynamicArray.push(dynamicArrayItem);
|
|
return dynamicArray
|
|
},
|
|
addFunctionGroup: function(r, c, func, index) {
|
|
if (index == null) {
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
|
|
let luckysheetfile = getluckysheetfile();
|
|
let file = luckysheetfile[getSheetIndex(index)];
|
|
if (file.calcChain == null) {
|
|
file.calcChain = [];
|
|
}
|
|
|
|
let cc = {
|
|
"r": r,
|
|
"c": c,
|
|
"index": index,
|
|
"func": func
|
|
};
|
|
file.calcChain.push(cc);
|
|
|
|
server.saveParam("fc", index, JSON.stringify(cc), {
|
|
"op": "add",
|
|
"pos": file.calcChain.length - 1
|
|
});
|
|
setluckysheetfile(luckysheetfile);
|
|
},
|
|
getAllFunctionGroup: function() {
|
|
let luckysheetfile = getluckysheetfile();
|
|
let ret = [];
|
|
for(let i=0;i<luckysheetfile.length;i++){
|
|
let file = luckysheetfile[i];
|
|
let calcChain = file.calcChain;
|
|
let dynamicArray_compute = file.dynamicArray_compute;
|
|
if(calcChain==null){
|
|
calcChain = [];
|
|
}
|
|
|
|
if(dynamicArray_compute==null){
|
|
dynamicArray_compute = [];
|
|
}
|
|
|
|
ret = ret.concat(calcChain);
|
|
|
|
for(let i=0;i<dynamicArray_compute.length;i++){
|
|
let d = dynamicArray_compute[0];
|
|
ret.push({
|
|
r:d.r,
|
|
c:d.c,
|
|
index:d.index
|
|
});
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
},
|
|
getFunctionGroup: function(index) {
|
|
if (index == null) {
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
|
|
let luckysheetfile = getluckysheetfile();
|
|
let file = luckysheetfile[getSheetIndex(index)];
|
|
|
|
if (file.calcChain == null) {
|
|
return [];
|
|
}
|
|
|
|
return file.calcChain;
|
|
},
|
|
updateFunctionGroup: function(r, c, index) {
|
|
if (index == null) {
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
|
|
let luckysheetfile = getluckysheetfile();
|
|
let file = luckysheetfile[getSheetIndex(index)];
|
|
|
|
let calcChain = file.calcChain;
|
|
if (calcChain != null) {
|
|
for (let i = 0; i < calcChain.length; i++) {
|
|
let calc = calcChain[i];
|
|
if (calc.r == r && calc.c == c && calc.index == index) {
|
|
server.saveParam("fc", index, JSON.stringify(calc), {
|
|
"op": "update",
|
|
"pos": i
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
setluckysheetfile(luckysheetfile);
|
|
},
|
|
insertUpdateFunctionGroup: function(r, c, index) {
|
|
if (index == null) {
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
|
|
// let func = getcellFormula(r, c, index);
|
|
// if (func == null || func.length==0) {
|
|
// this.delFunctionGroup(r, c, index);
|
|
// return;
|
|
// }
|
|
|
|
let luckysheetfile = getluckysheetfile();
|
|
let file = luckysheetfile[getSheetIndex(index)];
|
|
|
|
let calcChain = file.calcChain;
|
|
if (calcChain == null) {
|
|
calcChain = [];
|
|
}
|
|
|
|
for (let i = 0; i < calcChain.length; i++) {
|
|
let calc = calcChain[i];
|
|
if (calc.r == r && calc.c == c && calc.index == index) {
|
|
server.saveParam("fc", index, JSON.stringify(calc), {
|
|
"op": "update",
|
|
"pos": i
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
|
|
let cc = {
|
|
"r": r,
|
|
"c": c,
|
|
"index": index
|
|
};
|
|
calcChain.push(cc);
|
|
file.calcChain = calcChain;
|
|
|
|
server.saveParam("fc", index, JSON.stringify(cc), {
|
|
"op": "add",
|
|
"pos": file.calcChain.length - 1
|
|
});
|
|
setluckysheetfile(luckysheetfile);
|
|
},
|
|
isFunctionRangeSave: false,
|
|
isFunctionRangeSimple:function(txt, r, c, index,dynamicArray_compute){
|
|
if(txt==null || txt.length==0){
|
|
return;
|
|
}
|
|
|
|
let txtArray = txt.split(/==|!=|<>|<=|>=|[,()=+-\/*%&^><]/g);
|
|
if(txtArray.length>0){
|
|
for(let i=0;i<txtArray.length;i++){
|
|
let t = txtArray[i];
|
|
if(t.length<=1){
|
|
continue;
|
|
}
|
|
|
|
if(t.substr(0,1)=='"' && t.substr(t.length-1,1)=='"'){
|
|
continue;
|
|
}
|
|
|
|
this.isFunctionRangeSaveChange(t, r, c, index, dynamicArray_compute);
|
|
}
|
|
}
|
|
},
|
|
isFunctionRangeSimple1: function(txt, r, c, index,dynamicArray_compute) {
|
|
let _this = this;
|
|
|
|
if (_this.operatorjson == null) {
|
|
let arr = _this.operator.split("|"),
|
|
op = {};
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
op[arr[i].toString()] = 1;
|
|
}
|
|
|
|
_this.operatorjson = op;
|
|
}
|
|
|
|
if (txt.substr(0, 1) == "=") {
|
|
txt = txt.substr(1);
|
|
}
|
|
|
|
let funcstack = txt.split("");
|
|
let i = 0,
|
|
str = "",
|
|
function_str = "",
|
|
ispassby = true;
|
|
|
|
let matchConfig = {
|
|
"bracket": 0,
|
|
"comma": 0,
|
|
"squote": 0,
|
|
"dquote": 0
|
|
}
|
|
|
|
let luckysheetfile = getluckysheetfile();
|
|
|
|
|
|
while (i < funcstack.length) {
|
|
let s = funcstack[i];
|
|
|
|
if (s == "(" && matchConfig.dquote == 0) {
|
|
matchConfig.bracket += 1;
|
|
|
|
if (str.length > 0) {
|
|
function_str += "luckysheet_function." + str.toUpperCase() + ".f(";
|
|
}
|
|
else {
|
|
function_str += "(";
|
|
}
|
|
|
|
str = "";
|
|
}
|
|
else if (s == ")" && matchConfig.dquote == 0) {
|
|
matchConfig.bracket -= 1;
|
|
function_str += _this.isFunctionRangeSimple(str, r, c, index,dynamicArray_compute) + ")";
|
|
str = "";
|
|
}
|
|
else if (s == ',' && matchConfig.dquote == 0) {
|
|
//matchConfig.comma += 1;
|
|
function_str += _this.isFunctionRangeSimple(str, r, c, index,dynamicArray_compute) + ',';
|
|
str = "";
|
|
}
|
|
else if (s in _this.operatorjson && matchConfig.dquote == 0) {
|
|
let s_next = "";
|
|
|
|
if ((i + 1) < funcstack.length) {
|
|
s_next = funcstack[i + 1];
|
|
}
|
|
|
|
if ((s + s_next) in _this.operatorjson) {
|
|
if (str.length > 0) {
|
|
function_str += _this.isFunctionRangeSimple(str, r, c, index,dynamicArray_compute) + s + s_next;
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += s + s_next;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
else {
|
|
if (str.length > 0) {
|
|
function_str += _this.isFunctionRangeSimple(str, r, c, index,dynamicArray_compute) + s;
|
|
str = "";
|
|
}
|
|
else {
|
|
function_str += s;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
|
|
if (i == funcstack.length - 1) {
|
|
if (_this.iscelldata($.trim(str))) {
|
|
_this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);
|
|
// if (r != null && c != null) {
|
|
|
|
// let range = _this.getcellrange($.trim(str));
|
|
// let row = range.row,
|
|
// col = range.column;
|
|
|
|
// if ((r + "_" + c) in dynamicArray_compute) {
|
|
// let isd_range = false;
|
|
|
|
// for (let d_r = row[0]; d_r <= row[1]; d_r++) {
|
|
// for (let d_c = col[0]; d_c <= col[1]; d_c++) {
|
|
// if ((d_r + "_" + d_c) in dynamicArray_compute && dynamicArray_compute[d_r + "_" + d_c].r == r && dynamicArray_compute[d_r + "_" + d_c].c == c) {
|
|
// isd_range = true;
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// if (isd_range) {
|
|
// _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;
|
|
// }
|
|
// else {
|
|
// _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
|
|
// }
|
|
// }
|
|
// else {
|
|
// if (r >= row[0] && r <= row[1] && c >= col[0] && c <= col[1]) {
|
|
// _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;
|
|
// }
|
|
// else {
|
|
// _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
|
|
// }
|
|
// }
|
|
// }
|
|
// else {
|
|
// let sheetlen = $.trim(str).split("!");
|
|
|
|
// if (sheetlen.length > 1) {
|
|
// _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;
|
|
// }
|
|
// else {
|
|
// _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
|
|
// }
|
|
// }
|
|
}
|
|
else {
|
|
//console.log(str);
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
//console.log(function_str);
|
|
return function_str;
|
|
},
|
|
isFunctionRangeSelect:function(txt, r, c, index, dynamicArray_compute){
|
|
if(txt==null || txt==""){
|
|
return;
|
|
}
|
|
|
|
if(index==null){
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
if(dynamicArray_compute==null){
|
|
dynamicArray_compute = {};
|
|
}
|
|
let _this = this;
|
|
let txt1 = txt.toUpperCase();
|
|
let isOffsetFunc = txt1.indexOf("INDIRECT(")>-1 || txt1.indexOf("OFFSET(")>-1 || txt1.indexOf("INDEX(")>-1;
|
|
if(txt in this.formulaContainCellList){
|
|
let cellList = this.formulaContainCellList[txt];
|
|
if(isOffsetFunc){
|
|
let isoff = cellList["__LuckyisOff__"];
|
|
if(isoff==true){
|
|
for(let cellStr in cellList){
|
|
if(cellStr=="__LuckyisOff__"){
|
|
continue;
|
|
}
|
|
this.isFunctionRangeSaveChange(cellStr, r, c, index, dynamicArray_compute);
|
|
}
|
|
}
|
|
else{
|
|
this.isFunctionRange(txt, r, c, index,dynamicArray_compute, function(str){
|
|
_this.addToCellList(txt, str);
|
|
});
|
|
cellList["__LuckyisOff__"] = true;
|
|
}
|
|
}
|
|
else{
|
|
|
|
for(let cellStr in cellList){
|
|
if(cellStr=="__LuckyisOff__"){
|
|
continue;
|
|
}
|
|
this.isFunctionRangeSaveChange(cellStr, r, c, index, dynamicArray_compute);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
if(isOffsetFunc){
|
|
this.isFunctionRange(txt, r, c, index,dynamicArray_compute);
|
|
}
|
|
else{
|
|
this.isFunctionRangeSimple(txt, r, c, index,dynamicArray_compute);
|
|
}
|
|
},
|
|
isFunctionRange: function (txt, r, c, index,dynamicArray_compute, cellRangeFunction) {
|
|
let _this = this;
|
|
|
|
if (_this.operatorjson == null) {
|
|
let arr = _this.operator.split("|"),
|
|
op = {};
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
op[arr[i].toString()] = 1;
|
|
}
|
|
|
|
_this.operatorjson = op;
|
|
}
|
|
|
|
if (txt.substr(0, 1) == "=") {
|
|
txt = txt.substr(1);
|
|
}
|
|
|
|
let funcstack = txt.split("");
|
|
let i = 0,
|
|
str = "",
|
|
function_str = "",
|
|
ispassby = true;
|
|
|
|
let matchConfig = {
|
|
"bracket": 0,
|
|
"comma": 0,
|
|
"squote": 0,
|
|
"dquote": 0,
|
|
"compare": 0,
|
|
"braces": 0
|
|
}
|
|
|
|
// let luckysheetfile = getluckysheetfile();
|
|
// let dynamicArray_compute = luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray_compute"] == null ? {} : luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray_compute"];
|
|
|
|
//bracket 0为运算符括号、1为函数括号
|
|
let cal1 = [], cal2 = [], bracket = [];
|
|
|
|
while (i < funcstack.length) {
|
|
let s = funcstack[i];
|
|
|
|
if (s == "(" && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
if (str.length > 0 && bracket.length == 0) {
|
|
str = str.toUpperCase();
|
|
if(str.indexOf(":")>-1){
|
|
let funcArray = str.split(":");
|
|
function_str += "luckysheet_getSpecialReference(true,'"+ $.trim(funcArray[0]).replace(/'/g, "\\'") +"', luckysheet_function." + funcArray[1] + ".f(#lucky#";
|
|
}
|
|
else{
|
|
function_str += "luckysheet_function." + str + ".f(";
|
|
}
|
|
bracket.push(1);
|
|
str = "";
|
|
}
|
|
else if (bracket.length == 0) {
|
|
function_str += "(";
|
|
bracket.push(0);
|
|
str = "";
|
|
}
|
|
else {
|
|
bracket.push(0);
|
|
str += s;
|
|
}
|
|
}
|
|
else if (s == ")" && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
let bt = bracket.pop();
|
|
|
|
if (bracket.length == 0) {
|
|
// function_str += _this.isFunctionRange(str,r,c, index,dynamicArray_compute,cellRangeFunction) + ")";
|
|
// str = "";
|
|
|
|
let functionS = _this.isFunctionRange(str,r,c, index,dynamicArray_compute,cellRangeFunction);
|
|
if(functionS.indexOf("#lucky#")>-1){
|
|
functionS = functionS.replace(/#lucky#/g, "") + ")";
|
|
}
|
|
function_str += functionS + ")";
|
|
str = "";
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
}
|
|
else if (s == "{" && matchConfig.dquote == 0) {
|
|
str += '{';
|
|
matchConfig.braces += 1;
|
|
}
|
|
else if (s == "}" && matchConfig.dquote == 0) {
|
|
str += '}';
|
|
matchConfig.braces -= 1;
|
|
}
|
|
else if (s == '"') {
|
|
str += '"';
|
|
|
|
if (matchConfig.dquote > 0) {
|
|
matchConfig.dquote -= 1;
|
|
}
|
|
else {
|
|
matchConfig.dquote += 1;
|
|
}
|
|
}
|
|
else if (s == "'") {
|
|
str += "'";
|
|
|
|
if (matchConfig.squote > 0) {
|
|
matchConfig.squote -= 1;
|
|
}
|
|
else {
|
|
matchConfig.squote += 1;
|
|
}
|
|
}
|
|
else if (s == ',' && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
if (bracket.length <= 1) {
|
|
// function_str += _this.isFunctionRange(str, r, c, index,dynamicArray_compute,cellRangeFunction) + ",";
|
|
// str = "";
|
|
|
|
let functionS = _this.isFunctionRange(str, r, c, index,dynamicArray_compute,cellRangeFunction);
|
|
if(functionS.indexOf("#lucky#")>-1){
|
|
functionS = functionS.replace(/#lucky#/g, "") + ")";
|
|
}
|
|
function_str += functionS + ",";
|
|
str = "";
|
|
}
|
|
else {
|
|
str += ",";
|
|
}
|
|
}
|
|
else if (s in _this.operatorjson && matchConfig.dquote == 0 && matchConfig.braces == 0) {
|
|
let s_next = "";
|
|
let op = _this.operatorPriority;
|
|
|
|
if ((i + 1) < funcstack.length) {
|
|
s_next = funcstack[i + 1];
|
|
}
|
|
|
|
if ((s + s_next) in _this.operatorjson) {
|
|
if (bracket.length == 0) {
|
|
if ($.trim(str).length > 0) {
|
|
cal2.unshift(_this.isFunctionRange($.trim(str), r, c, index,dynamicArray_compute,cellRangeFunction));
|
|
}
|
|
else if ($.trim(function_str).length > 0) {
|
|
cal2.unshift($.trim(function_str));
|
|
}
|
|
|
|
if (cal1[0] in _this.operatorjson) {
|
|
let stackCeilPri = op[cal1[0]];
|
|
|
|
while (cal1.length > 0 && stackCeilPri != null) {
|
|
cal2.unshift(cal1.shift());
|
|
stackCeilPri = op[cal1[0]];
|
|
}
|
|
}
|
|
|
|
cal1.unshift(s + s_next);
|
|
|
|
function_str = "";
|
|
str = "";
|
|
}
|
|
else {
|
|
str += s + s_next;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
else {
|
|
if (bracket.length == 0) {
|
|
if ($.trim(str).length > 0) {
|
|
cal2.unshift(_this.isFunctionRange($.trim(str), r, c, index,dynamicArray_compute,cellRangeFunction));
|
|
}
|
|
else if ($.trim(function_str).length > 0) {
|
|
cal2.unshift($.trim(function_str));
|
|
}
|
|
|
|
if (cal1[0] in _this.operatorjson) {
|
|
let stackCeilPri = op[cal1[0]];
|
|
stackCeilPri = stackCeilPri == null ? 1000 : stackCeilPri;
|
|
|
|
let sPri = op[s];
|
|
sPri = sPri == null ? 1000 : sPri;
|
|
|
|
while (cal1.length > 0 && sPri >= stackCeilPri) {
|
|
cal2.unshift(cal1.shift());
|
|
|
|
stackCeilPri = op[cal1[0]];
|
|
stackCeilPri = stackCeilPri == null ? 1000 : stackCeilPri;
|
|
}
|
|
}
|
|
|
|
cal1.unshift(s);
|
|
|
|
function_str = "";
|
|
str = "";
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (matchConfig.dquote == 0 && matchConfig.squote==0) {
|
|
|
|
str += $.trim(s);
|
|
}
|
|
else {
|
|
str += s;
|
|
}
|
|
}
|
|
|
|
if (i == funcstack.length - 1) {
|
|
let endstr = "";
|
|
let str_nb = $.trim(str).replace(/'/g, "\\'");
|
|
if (_this.iscelldata(str_nb) && str_nb.substr(0,1)!=":") {
|
|
// endstr = "luckysheet_getcelldata('" + $.trim(str) + "')";
|
|
endstr = "luckysheet_getcelldata('" +str_nb + "')";
|
|
_this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);
|
|
}
|
|
else if(str_nb.substr(0,1)==":"){
|
|
str_nb = str_nb.substr(1);
|
|
if(_this.iscelldata(str_nb)){
|
|
endstr = "luckysheet_getSpecialReference(false," + function_str +",'"+ str_nb +"')";
|
|
}
|
|
}
|
|
else {
|
|
str = $.trim(str);
|
|
|
|
let regx = /{.*?}/;
|
|
if (regx.test(str) && str.substr(0, 1) != '"' && str.substr(str.length - 1, 1) != '"') {
|
|
let arraytxt = regx.exec(str)[0];
|
|
let arraystart = str.search(regx);
|
|
let alltxt = "";
|
|
|
|
if (arraystart > 0) {
|
|
endstr += str.substr(0, arraystart);
|
|
}
|
|
|
|
endstr += "luckysheet_getarraydata('" + arraytxt + "')";
|
|
|
|
if (arraystart + arraytxt.length < str.length) {
|
|
endstr += str.substr(arraystart + arraytxt.length, str.length);
|
|
}
|
|
}
|
|
else {
|
|
endstr = str;
|
|
}
|
|
}
|
|
|
|
if (endstr.length > 0) {
|
|
cal2.unshift(endstr);
|
|
}
|
|
|
|
if (cal1.length > 0) {
|
|
if (function_str.length > 0) {
|
|
cal2.unshift(function_str);
|
|
function_str = "";
|
|
}
|
|
|
|
while (cal1.length > 0) {
|
|
cal2.unshift(cal1.shift());
|
|
}
|
|
}
|
|
|
|
if (cal2.length > 0) {
|
|
function_str = _this.calPostfixExpression(cal2);
|
|
}
|
|
else {
|
|
function_str += endstr;
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
// console.log(function_str);
|
|
_this.checkSpecialFunctionRange(function_str, r, c, index, dynamicArray_compute,cellRangeFunction);
|
|
return function_str;
|
|
},
|
|
isFunctionRangeSaveChange: function (str, r, c, index, dynamicArray_compute) {
|
|
let _this = this;
|
|
if (r != null && c != null) {
|
|
let range = _this.getcellrange($.trim(str), index);
|
|
if(range==null){
|
|
return;
|
|
}
|
|
let row = range.row,
|
|
col = range.column,
|
|
sheetIndex = range.sheetIndex;
|
|
|
|
if ((r + "_" + c) in dynamicArray_compute && (index==sheetIndex || index==null)) {
|
|
let isd_range = false;
|
|
|
|
for (let d_r = row[0]; d_r <= row[1]; d_r++) {
|
|
for (let d_c = col[0]; d_c <= col[1]; d_c++) {
|
|
if ((d_r + "_" + d_c) in dynamicArray_compute && dynamicArray_compute[d_r + "_" + d_c].r == r && dynamicArray_compute[d_r + "_" + d_c].c == c) {
|
|
isd_range = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isd_range) {
|
|
_this.isFunctionRangeSave = _this.isFunctionRangeSave || true;
|
|
}
|
|
else {
|
|
_this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
|
|
}
|
|
}
|
|
else {
|
|
if (r >= row[0] && r <= row[1] && c >= col[0] && c <= col[1] && (index==sheetIndex || index==null)) {
|
|
_this.isFunctionRangeSave = _this.isFunctionRangeSave || true;
|
|
}
|
|
else {
|
|
_this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
|
|
}
|
|
}
|
|
|
|
}
|
|
else {
|
|
_this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
|
|
// let sheetlen = $.trim(str).split("!");
|
|
|
|
// if (sheetlen.length > 1) {
|
|
// _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;//if change sheet, it must be true, but this is very slow
|
|
// }
|
|
// else {
|
|
// _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;
|
|
// }
|
|
}
|
|
},
|
|
checkSpecialFunctionRange: function (function_str, r, c, index, dynamicArray_compute,cellRangeFunction) {
|
|
|
|
if(function_str.substr(0, 30) =="luckysheet_getSpecialReference" || function_str.substr(0, 20) == "luckysheet_function."){
|
|
if(function_str.substr(0, 20) == "luckysheet_function."){
|
|
let funcName = function_str.split(".")[1];
|
|
if (funcName != null) {
|
|
funcName = funcName.toUpperCase();
|
|
if (funcName != "INDIRECT" && funcName != "OFFSET" && funcName != "INDEX") {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
try {
|
|
Store.calculateSheetIndex = index;
|
|
let str = eval(function_str);
|
|
|
|
if(str instanceof Object && str.startCell!=null){
|
|
str = str.startCell;
|
|
}
|
|
let str_nb = $.trim(str);
|
|
// console.log(function_str, tempFunc,str, this.iscelldata(str_nb),this.isFunctionRangeSave,r,c);
|
|
if (this.iscelldata(str_nb)) {
|
|
if(typeof(cellRangeFunction)=="function"){
|
|
cellRangeFunction(str_nb);
|
|
}
|
|
// this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);
|
|
// console.log(function_str, str, this.isFunctionRangeSave,r,c);
|
|
}
|
|
}
|
|
catch{
|
|
|
|
}
|
|
}
|
|
|
|
// if (function_str.substr(0, 20) == "luckysheet_function.") {
|
|
// let funcName = function_str.split(".")[1];
|
|
// if (funcName != null) {
|
|
// funcName = funcName.toUpperCase();
|
|
// if (funcName == "INDIRECT") {
|
|
// let tempFunc = "luckysheet_indirect_check" + function_str.substr(30, function_str.length);
|
|
|
|
// //tempFunc = tempFunc.replace(/luckysheet_getcelldata/g, "luckysheet_indirect_check_return");
|
|
|
|
// try {
|
|
// Store.calculateSheetIndex = index;
|
|
// let str = eval(tempFunc);
|
|
|
|
// if(str instanceof Object && str.data!=null){
|
|
// str = str.data.v;
|
|
// }
|
|
// let str_nb = $.trim(str);
|
|
// // console.log(function_str, tempFunc,str, this.iscelldata(str_nb),this.isFunctionRangeSave,r,c);
|
|
// if (this.iscelldata(str_nb)) {
|
|
// if(typeof(cellRangeFunction)=="function"){
|
|
// cellRangeFunction(str_nb);
|
|
// }
|
|
// this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);
|
|
// // console.log(function_str, str, this.isFunctionRangeSave,r,c);
|
|
// }
|
|
// }
|
|
// catch{
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
// else if (funcName == "OFFSET") {
|
|
// let tempFunc = "luckysheet_offset_check" + function_str.substr(28, function_str.length);
|
|
|
|
// try {
|
|
// Store.calculateSheetIndex = index;
|
|
// let str = eval(tempFunc);
|
|
// if(str instanceof Object && str.data!=null){
|
|
// str = str.data.v;
|
|
// }
|
|
// let str_nb = $.trim(str);
|
|
// if (this.iscelldata(str_nb)) {
|
|
// if(typeof(cellRangeFunction)=="function"){
|
|
// cellRangeFunction(str_nb);
|
|
// }
|
|
// this.isFunctionRangeSaveChange(str, r, c, index,dynamicArray_compute);
|
|
// //console.log(function_str, str, this.isFunctionRangeSave,r,c);
|
|
// }
|
|
// }
|
|
// catch{
|
|
|
|
// }
|
|
// //let result = eval(function_str);
|
|
|
|
// //console.log(function_str, result);
|
|
// }
|
|
// }
|
|
|
|
// }
|
|
},
|
|
execvertex: {},
|
|
execFunctionGroupData: null,
|
|
execFunctionExist: null,
|
|
formulaContainSheetList:{},
|
|
formulaContainCellList:{},
|
|
cellTextToIndexList:{},
|
|
addToCellList:function(formulaTxt, cellstring){
|
|
if(formulaTxt==null || formulaTxt.length==0|| cellstring==null || cellstring.length==0){
|
|
return;
|
|
}
|
|
if(this.formulaContainCellList==null){
|
|
this.formulaContainCellList = {};
|
|
}
|
|
|
|
// formulaTxt = formulaTxt.toUpperCase();
|
|
if(this.formulaContainCellList[formulaTxt]==null){
|
|
this.formulaContainCellList[formulaTxt] = {};
|
|
}
|
|
|
|
this.formulaContainCellList[formulaTxt][cellstring] = 1;
|
|
},
|
|
addToCellIndexList:function(txt, infoObj){
|
|
if(txt==null || txt.length==0|| infoObj==null){
|
|
return;
|
|
}
|
|
if(this.cellTextToIndexList==null){
|
|
this.cellTextToIndexList = {};
|
|
}
|
|
|
|
if(txt.indexOf("!")>-1){
|
|
txt = txt.replace(/\\'/g, "'");
|
|
this.cellTextToIndexList[txt] = infoObj;
|
|
}
|
|
else{
|
|
this.cellTextToIndexList[txt+"_"+infoObj.sheetIndex] = infoObj;
|
|
}
|
|
|
|
// console.log(this.cellTextToIndexList);
|
|
},
|
|
addToSheetIndexList:function(formulaTxt, sheetIndex, obIndex){
|
|
if(formulaTxt==null || formulaTxt.length==0){
|
|
return;
|
|
}
|
|
|
|
if(sheetIndex==null || sheetIndex.length==0){
|
|
sheetIndex = Store.currentSheetIndex;
|
|
}
|
|
|
|
if(obIndex==null || obIndex.length==0){
|
|
obIndex = "";
|
|
}
|
|
|
|
if(this.formulaContainSheetList==null){
|
|
this.formulaContainSheetList = {};
|
|
}
|
|
|
|
if(this.formulaContainSheetList[formulaTxt]==null){
|
|
this.formulaContainSheetList[formulaTxt] = {};
|
|
}
|
|
|
|
this.formulaContainSheetList[formulaTxt][sheetIndex] = obIndex;
|
|
},
|
|
execFunctionGlobalData:{},
|
|
execFunctionGroupForce:function(isForce){
|
|
if(isForce){
|
|
this.execFunctionGroup(undefined, undefined, undefined, undefined, undefined,true);
|
|
}
|
|
else{
|
|
this.execFunctionGroup();
|
|
}
|
|
},
|
|
execFunctionGroup: function(origin_r, origin_c, value, index, data, isForce=false) {
|
|
let _this = this;
|
|
|
|
if (data == null) {
|
|
data = Store.flowdata;
|
|
}
|
|
|
|
if (!window.luckysheet_compareWith) {
|
|
window.luckysheet_compareWith = luckysheet_compareWith;
|
|
window.luckysheet_getarraydata = luckysheet_getarraydata;
|
|
window.luckysheet_getcelldata = luckysheet_getcelldata;
|
|
window.luckysheet_parseData = luckysheet_parseData;
|
|
window.luckysheet_getValue = luckysheet_getValue;
|
|
window.luckysheet_indirect_check = luckysheet_indirect_check;
|
|
window.luckysheet_indirect_check_return = luckysheet_indirect_check_return;
|
|
window.luckysheet_offset_check = luckysheet_offset_check;
|
|
window.luckysheet_calcADPMM = luckysheet_calcADPMM;
|
|
window.luckysheet_getSpecialReference = luckysheet_getSpecialReference;
|
|
}
|
|
|
|
if(_this.execFunctionGlobalData==null){
|
|
_this.execFunctionGlobalData = {};
|
|
}
|
|
// let luckysheetfile = getluckysheetfile();
|
|
// let dynamicArray_compute = luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray_compute"] == null ? {} : luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray_compute"];
|
|
|
|
if (index == null) {
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
|
|
if (value != null) {
|
|
//此处setcellvalue 中this.execFunctionGroupData会保存想要更新的值,本函数结尾不要设为null,以备后续函数使用
|
|
// setcellvalue(origin_r, origin_c, _this.execFunctionGroupData, value);
|
|
let cellCache = [[{v:null}]];
|
|
setcellvalue(0, 0, cellCache, value);
|
|
_this.execFunctionGlobalData[origin_r+"_"+origin_c+"_"+index] = cellCache[0][0];
|
|
|
|
}
|
|
|
|
//{ "r": r, "c": c, "index": index, "func": func}
|
|
let calcChains = _this.getAllFunctionGroup(),
|
|
formulaObjects = {};
|
|
|
|
let sheets = getluckysheetfile();
|
|
let sheetData = {};
|
|
for(let i=0;i<sheets.length;i++){
|
|
let sheet = sheets[i];
|
|
sheetData[sheet.index] = sheet.data;
|
|
}
|
|
|
|
//把修改涉及的单元格存储为对象
|
|
let updateValueOjects = {}, updateValueArray = [];
|
|
if (_this.execFunctionExist == null) {
|
|
let key = "r" + origin_r + "c" + origin_c + "i" + index;
|
|
updateValueOjects[key] = 1;
|
|
}
|
|
else{
|
|
for (let x = 0; x < _this.execFunctionExist.length; x++) {
|
|
let cell = _this.execFunctionExist[x];
|
|
let key = "r" + cell.r + "c" + cell.c + "i" + cell.i;
|
|
updateValueOjects[key] = 1;
|
|
}
|
|
}
|
|
|
|
let arrayMatchCache = {};
|
|
let arrayMatch = function(formulaArray, formulaObjects, updateValueOjects, func){
|
|
for(let a=0;a<formulaArray.length;a++){
|
|
let range = formulaArray[a];
|
|
let cacheKey = "r"+range.row[0]+""+range.row[1]+"c"+range.column[0]+""+range.column[1]+"index"+range.sheetIndex;
|
|
if(cacheKey in arrayMatchCache){
|
|
let amc = arrayMatchCache[cacheKey];
|
|
// console.log(amc);
|
|
amc.forEach((item)=>{
|
|
func(item.key, item.r, item.c, item.sheetIndex);
|
|
});
|
|
}
|
|
else{
|
|
let functionArr = [];
|
|
for(let r=range.row[0];r<=range.row[1];r++){
|
|
for(let c=range.column[0];c<=range.column[1];c++){
|
|
let key = "r" + r + "c" + c + "i" + range.sheetIndex;
|
|
func(key, r, c, range.sheetIndex);
|
|
if((formulaObjects && key in formulaObjects) || (updateValueOjects && key in updateValueOjects) ){
|
|
functionArr.push({
|
|
key:key,
|
|
r:r,
|
|
c:c,
|
|
sheetIndex:range.sheetIndex
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
if(formulaObjects || updateValueOjects){
|
|
arrayMatchCache[cacheKey] = functionArr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let existsChildFormulaMatch = {}, ii=0;
|
|
|
|
//创建公式缓存及其范围的缓存
|
|
// console.time("1");
|
|
for(let i=0;i<calcChains.length;i++){
|
|
let formulaCell = calcChains[i];
|
|
let key = "r" + formulaCell.r + "c" + formulaCell.c + "i" + formulaCell.index;
|
|
let calc_funcStr = getcellFormula(formulaCell.r, formulaCell.c, formulaCell.index);
|
|
if(calc_funcStr==null){
|
|
continue;
|
|
}
|
|
let txt1 = calc_funcStr.toUpperCase();
|
|
let isOffsetFunc = txt1.indexOf("INDIRECT(")>-1 || txt1.indexOf("OFFSET(")>-1 || txt1.indexOf("INDEX(")>-1;
|
|
let formulaArray = [];
|
|
|
|
if(isOffsetFunc){
|
|
this.isFunctionRange(calc_funcStr, null, null, formulaCell.index, null, function(str_nb){
|
|
let range = _this.getcellrange($.trim(str_nb), formulaCell.index);
|
|
if(range!=null){
|
|
formulaArray.push(range);
|
|
}
|
|
});
|
|
}
|
|
else if(!(calc_funcStr.substr(0,2)=='="' && calc_funcStr.substr(calc_funcStr.length-1,1)=='"')){
|
|
let formulaTextArray = calc_funcStr.split(/==|!=|<>|<=|>=|[,()=+-\/*%&^><]/g);
|
|
|
|
for(let i=0;i<formulaTextArray.length;i++){
|
|
let t = formulaTextArray[i];
|
|
if(t.length<=1){
|
|
continue;
|
|
}
|
|
|
|
if(t.substr(0,1)=='"' && t.substr(t.length-1,1)=='"' && !_this.iscelldata(t)){
|
|
continue;
|
|
}
|
|
|
|
let range = _this.getcellrange($.trim(t), formulaCell.index);
|
|
|
|
if(range==null){
|
|
continue;
|
|
}
|
|
|
|
formulaArray.push(range);
|
|
}
|
|
}
|
|
|
|
let item = {
|
|
formulaArray:formulaArray,
|
|
calc_funcStr:calc_funcStr,
|
|
key:key,
|
|
r:formulaCell.r,
|
|
c:formulaCell.c,
|
|
index:formulaCell.index,
|
|
parents:{},
|
|
chidren:{},
|
|
color:"w"
|
|
}
|
|
|
|
formulaObjects[key] = item;
|
|
|
|
|
|
|
|
// if(isForce){
|
|
// updateValueArray.push(item);
|
|
// }
|
|
// else{
|
|
// arrayMatch(formulaArray, null, function(key){
|
|
// if(key in updateValueOjects){
|
|
// updateValueArray.push(item);
|
|
// }
|
|
// });
|
|
// }
|
|
|
|
}
|
|
|
|
// console.timeEnd("1");
|
|
|
|
// console.time("2");
|
|
//形成一个公式之间引用的图结构
|
|
Object.keys(formulaObjects).forEach((key)=>{
|
|
let formulaObject = formulaObjects[key];
|
|
arrayMatch(formulaObject.formulaArray, formulaObjects, updateValueOjects, function(childKey){
|
|
if(childKey in formulaObjects){
|
|
let childFormulaObject = formulaObjects[childKey];
|
|
formulaObject.chidren[childKey] = 1;
|
|
childFormulaObject.parents[key] = 1;
|
|
}
|
|
// console.log(childKey,formulaObject.formulaArray);
|
|
if(!isForce && childKey in updateValueOjects){
|
|
updateValueArray.push(formulaObject);
|
|
}
|
|
});
|
|
|
|
if(isForce){
|
|
updateValueArray.push(formulaObject);
|
|
}
|
|
});
|
|
|
|
// console.log(formulaObjects)
|
|
// console.timeEnd("2");
|
|
|
|
|
|
// console.time("3");
|
|
let formulaRunList = [];
|
|
//计算,采用深度优先遍历公式形成的图结构
|
|
|
|
// updateValueArray.forEach((key)=>{
|
|
// let formulaObject = formulaObjects[key];
|
|
|
|
|
|
// });
|
|
|
|
let stack = updateValueArray, existsFormulaRunList={};
|
|
while(stack.length>0){
|
|
let formulaObject = stack.pop();
|
|
|
|
if(formulaObject==null || formulaObject.key in existsFormulaRunList){
|
|
continue;
|
|
}
|
|
|
|
if(formulaObject.color == "b"){
|
|
formulaRunList.push(formulaObject);
|
|
existsFormulaRunList[formulaObject.key] = 1;
|
|
continue;
|
|
}
|
|
|
|
let cacheStack = [];
|
|
Object.keys(formulaObject.parents).forEach((parentKey)=>{
|
|
let parentFormulaObject = formulaObjects[parentKey];
|
|
if(parentFormulaObject!=null){
|
|
cacheStack.push(parentFormulaObject);
|
|
}
|
|
});
|
|
|
|
|
|
ii++;
|
|
|
|
if(cacheStack.length==0){
|
|
formulaRunList.push(formulaObject);
|
|
existsFormulaRunList[formulaObject.key] = 1;
|
|
}
|
|
else{
|
|
formulaObject.color = "b";
|
|
stack.push(formulaObject);
|
|
stack = stack.concat(cacheStack);
|
|
}
|
|
}
|
|
|
|
formulaRunList.reverse();
|
|
|
|
// console.log(formulaObjects, ii)
|
|
// console.timeEnd("3");
|
|
|
|
// console.time("4");
|
|
for(let i=0;i<formulaRunList.length;i++){
|
|
let formulaCell = formulaRunList[i];
|
|
if(formulaCell.level==Math.max){
|
|
continue;
|
|
}
|
|
|
|
window.luckysheet_getcelldata_cache = null;
|
|
let calc_funcStr = formulaCell.calc_funcStr;
|
|
|
|
let v = _this.execfunction(calc_funcStr, formulaCell.r, formulaCell.c, formulaCell.index);
|
|
|
|
_this.groupValuesRefreshData.push({
|
|
"r": formulaCell.r,
|
|
"c": formulaCell.c,
|
|
"v": v[1],
|
|
"f": v[2],
|
|
"spe":v[3],
|
|
"index": formulaCell.index
|
|
});
|
|
|
|
// _this.execFunctionGroupData[u.r][u.c] = value;
|
|
_this.execFunctionGlobalData[formulaCell.r+"_"+formulaCell.c+"_"+formulaCell.index] = {
|
|
v:v[1],
|
|
f:v[2]
|
|
};
|
|
}
|
|
// console.log(formulaRunList);
|
|
// console.timeEnd("4");
|
|
|
|
_this.execFunctionExist = null;
|
|
},
|
|
// When set origin_r and origin_c, that mean just refresh cell value link to [origin_r,origin_c] cell
|
|
execFunctionGroup1: function(origin_r, origin_c, value, index, data, isForce=false) {
|
|
let _this = this;
|
|
|
|
if (data == null) {
|
|
data = Store.flowdata;
|
|
}
|
|
|
|
if (!window.luckysheet_compareWith) {
|
|
window.luckysheet_compareWith = luckysheet_compareWith;
|
|
window.luckysheet_getarraydata = luckysheet_getarraydata;
|
|
window.luckysheet_getcelldata = luckysheet_getcelldata;
|
|
window.luckysheet_parseData = luckysheet_parseData;
|
|
window.luckysheet_getValue = luckysheet_getValue;
|
|
window.luckysheet_indirect_check = luckysheet_indirect_check;
|
|
window.luckysheet_indirect_check_return = luckysheet_indirect_check_return;
|
|
window.luckysheet_offset_check = luckysheet_offset_check;
|
|
window.luckysheet_calcADPMM = luckysheet_calcADPMM;
|
|
window.luckysheet_getSpecialReference = luckysheet_getSpecialReference;
|
|
}
|
|
|
|
if(_this.execFunctionGlobalData==null){
|
|
_this.execFunctionGlobalData = {};
|
|
}
|
|
let luckysheetfile = getluckysheetfile();
|
|
let dynamicArray_compute = luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray_compute"] == null ? {} : luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray_compute"];
|
|
|
|
if (index == null) {
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
|
|
if (value != null) {
|
|
//此处setcellvalue 中this.execFunctionGroupData会保存想要更新的值,本函数结尾不要设为null,以备后续函数使用
|
|
// setcellvalue(origin_r, origin_c, _this.execFunctionGroupData, value);
|
|
let cellCache = [[{v:null}]];
|
|
setcellvalue(0, 0, cellCache, value);
|
|
_this.execFunctionGlobalData[origin_r+"_"+origin_c+"_"+index] = cellCache[0][0];
|
|
|
|
}
|
|
|
|
|
|
|
|
//{ "r": r, "c": c, "index": index, "func": func}
|
|
let group = _this.getAllFunctionGroup(),
|
|
vertex1 = {},
|
|
stack = [],
|
|
count = 0;
|
|
|
|
_this.execvertex = {};
|
|
if (_this.execFunctionExist == null) {
|
|
for (let i = 0; i < group.length; i++) {
|
|
let item = group[i];
|
|
let file =luckysheetfile[getSheetIndex(item["index"])];
|
|
if(file==null){
|
|
continue;
|
|
}
|
|
let cell = file.data[item.r][item.c];
|
|
let calc_funcStr = getcellFormula(item.r, item.c, item.index);
|
|
if(cell != null && cell.f != null && cell.f == calc_funcStr){
|
|
if(!(item instanceof Object)){
|
|
item = eval('('+ item +')');
|
|
}
|
|
|
|
item.color = "w";
|
|
item.parent = null;
|
|
item.chidren = {};
|
|
item.times = 0;
|
|
|
|
vertex1["r" + item.r + "c" + item.c + "i" + item.index] = item;
|
|
_this.isFunctionRangeSave = false;
|
|
|
|
if(isForce){
|
|
_this.isFunctionRangeSave = true;
|
|
}
|
|
else if (origin_r != null && origin_c != null) {
|
|
_this.isFunctionRangeSelect(calc_funcStr, origin_r, origin_c, index, dynamicArray_compute);
|
|
}
|
|
// else {
|
|
// _this.isFunctionRangeSelect(calc_funcStr, undefined, undefined ,dynamicArray_compute);
|
|
// }
|
|
|
|
if (_this.isFunctionRangeSave) {
|
|
stack.push(item);
|
|
_this.execvertex["r" + item.r + "c" + item.c + "i" + item.index] = item;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (let x = 0; x < _this.execFunctionExist.length; x++) {
|
|
let cell = _this.execFunctionExist[x];
|
|
|
|
if ("r" + cell.r + "c" + cell.c + "i" + cell.i in vertex1) {
|
|
continue;
|
|
}
|
|
|
|
for (let i = 0; i < group.length; i++) {
|
|
let item = group[i];
|
|
let calc_funcStr = getcellFormula(item.r, item.c, item.index);
|
|
item.color = "w";
|
|
item.parent = null;
|
|
item.chidren = {};
|
|
item.times = 0;
|
|
|
|
vertex1["r" + item.r + "c" + item.c + "i"+ item.index] = item;
|
|
_this.isFunctionRangeSave = false;
|
|
if(isForce){
|
|
_this.isFunctionRangeSave = true;
|
|
}
|
|
else{
|
|
_this.isFunctionRangeSelect(calc_funcStr, cell.r, cell.c, cell.i, dynamicArray_compute);
|
|
}
|
|
|
|
if (_this.isFunctionRangeSave) {
|
|
stack.push(item);
|
|
_this.execvertex["r" + item.r + "c" + item.c + "i" + item.index] = item;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// console.time("1");
|
|
// console.log(group.length);
|
|
// let iii = 0, ii=0;
|
|
//先进先出法,构建逆向执行结构树
|
|
while (stack.length > 0) {
|
|
let u = stack.shift();
|
|
let excludeList = {};
|
|
_this.getChildrenVertex(u, vertex1, excludeList);
|
|
// ii++;
|
|
// console.log(JSON.stringify(excludeList));
|
|
for (let name in vertex1) {
|
|
let item = vertex1[name];
|
|
if(item==null){
|
|
continue;
|
|
}
|
|
|
|
let ukey ="r" + u.r + "c" + u.c + "i" + u.index;
|
|
|
|
// if ((u.r == item.r && u.c == item.c && u.index == item.index) ) {
|
|
// continue;
|
|
// }
|
|
|
|
if(name in excludeList){
|
|
continue;
|
|
}
|
|
|
|
_this.isFunctionRangeSave = false;
|
|
|
|
|
|
|
|
let calc_funcStr = getcellFormula(item.r, item.c, item.index);
|
|
_this.isFunctionRangeSelect(calc_funcStr, u.r, u.c, u.index, dynamicArray_compute);
|
|
|
|
// iii++;
|
|
|
|
if (_this.isFunctionRangeSave) {
|
|
if (!(name in _this.execvertex)) {
|
|
// console.log(JSON.stringify(item), JSON.stringify(u), _this.isFunctionRangeSave);
|
|
|
|
stack.push(item);
|
|
_this.execvertex[name] = item;
|
|
}
|
|
|
|
count++;
|
|
_this.execvertex[name].chidren[ukey] = 1;
|
|
}
|
|
}
|
|
}
|
|
// console.log(iii, ii);
|
|
// console.timeEnd("1");
|
|
|
|
// console.time("2");
|
|
_this.groupValuesRefreshData = [];
|
|
let i = 0;
|
|
|
|
while (i < count) {
|
|
for (let name in _this.execvertex) {
|
|
let u = _this.execvertex[name];
|
|
|
|
if (u.color == "w") {
|
|
_this.functionDFS(u);
|
|
}
|
|
else if (u.color == "b") {
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
// console.timeEnd("2");
|
|
|
|
_this.execFunctionExist = null;
|
|
},
|
|
//递归得到引用节点
|
|
getChildrenVertex:function(u, vertex1, obj){
|
|
let ukey ="r" + u.r + "c" + u.c + "i" + u.index;
|
|
obj[ukey] = 1;
|
|
if(u.chidren !=null){
|
|
for(let key in u.chidren){
|
|
if(vertex1[key] && !(key in obj) ){
|
|
this.getChildrenVertex(vertex1[key], vertex1, obj);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
//深度优先算法,处理多级调用函数
|
|
functionDFS: function(u) {
|
|
let _this = this;
|
|
u.color = "g";
|
|
u.times += 1;
|
|
for (let chd in u.chidren) {
|
|
let v = _this.execvertex[chd];
|
|
if (v.color == "w") {
|
|
v.parent = "r" + u.r.toString() + "c" + u.c.toString() + "i" + u.index;
|
|
_this.functionDFS(v);
|
|
}
|
|
}
|
|
|
|
u.color = "b";
|
|
window.luckysheet_getcelldata_cache = null;
|
|
let calc_funcStr = getcellFormula(u.r, u.c, u.index);
|
|
|
|
let v = _this.execfunction(calc_funcStr, u.r, u.c, u.index);
|
|
|
|
// let value = _this.execFunctionGroupData[u.r][u.c];
|
|
// if(value == null){
|
|
// value = {};
|
|
// }
|
|
|
|
// value.v = v[1];
|
|
// value.f = v[2];
|
|
|
|
// let cell = getOrigincell(u.r,u.c,u.index);
|
|
|
|
// let spl;
|
|
// if(v[3]!=null){
|
|
// if(v[3].type=="sparklines"){
|
|
// window.luckysheetCurrentRow = u.r;
|
|
// window.luckysheetCurrentColumn = u.c;
|
|
// window.luckysheetCurrentIndex = u.index;
|
|
// window.luckysheetCurrentFunction = calc_funcStr;
|
|
|
|
// let fp = $.trim(_this.functionParserExe(calc_funcStr));
|
|
// let sparklines = eval(fp);
|
|
// spl = sparklines;
|
|
// }
|
|
// }
|
|
|
|
_this.groupValuesRefreshData.push({
|
|
"r": u.r,
|
|
"c": u.c,
|
|
"v": v[1],
|
|
"f": v[2],
|
|
"spe":v[3],
|
|
"index": u.index
|
|
});
|
|
|
|
// _this.execFunctionGroupData[u.r][u.c] = value;
|
|
_this.execFunctionGlobalData[u.r+"_"+u.c+"_"+u.index] = {
|
|
v:v[1],
|
|
f:v[2]
|
|
};
|
|
},
|
|
groupValuesRefreshData: [],
|
|
groupValuesRefresh: function() {
|
|
let _this = this;
|
|
let luckysheetfile = getluckysheetfile();
|
|
if(_this.groupValuesRefreshData.length > 0){
|
|
for (let i = 0; i < _this.groupValuesRefreshData.length; i++) {
|
|
let item = _this.groupValuesRefreshData[i];
|
|
|
|
// if(item.i != Store.currentSheetIndex){
|
|
// continue;
|
|
// }
|
|
|
|
let file = luckysheetfile[getSheetIndex(item.index)];
|
|
let data = file.data;
|
|
if(data==null){
|
|
continue;
|
|
}
|
|
|
|
let updateValue = {};
|
|
if(item.spe!=null){
|
|
if(item.spe.type=="sparklines"){
|
|
updateValue.spl = item.spe.data;
|
|
}
|
|
else if(item.spe.type=="dynamicArrayItem"){
|
|
file.dynamicArray = _this.insertUpdateDynamicArray(item.spe.data);
|
|
}
|
|
}
|
|
updateValue.v = item.v;
|
|
updateValue.f = item.f;
|
|
setcellvalue(item.r, item.c, data, updateValue);
|
|
server.saveParam("v", item.index, item.v, {
|
|
"r": item.r,
|
|
"c": item.c
|
|
});
|
|
}
|
|
|
|
editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据
|
|
_this.groupValuesRefreshData = [];
|
|
}
|
|
},
|
|
delFunctionGroup: function(r, c, index) {
|
|
if (index == null) {
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
|
|
let luckysheetfile = getluckysheetfile();
|
|
let file = luckysheetfile[getSheetIndex(index)];
|
|
|
|
let calcChain = file.calcChain;
|
|
if (calcChain != null) {
|
|
for (let i = 0; i < calcChain.length; i++) {
|
|
let calc = calcChain[i];
|
|
if (calc.r == r && calc.c == c && calc.index == index) {
|
|
calcChain.splice(i, 1);
|
|
server.saveParam("fc", index, null, {
|
|
"op": "del",
|
|
"pos": i
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
let dynamicArray = file.dynamicArray;
|
|
if (dynamicArray != null) {
|
|
for (let i = 0; i < dynamicArray.length; i++) {
|
|
let calc = dynamicArray[i];
|
|
if (calc.r == r && calc.c == c && (calc.index==null || calc.index == index)) {
|
|
dynamicArray.splice(i, 1);
|
|
server.saveParam("ac", index, null, {
|
|
"op": "del",
|
|
"pos": i
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
setluckysheetfile(luckysheetfile);
|
|
},
|
|
execfunction: function(txt, r, c, index, isrefresh, notInsertFunc) {
|
|
let _this = this;
|
|
|
|
let _locale = locale();
|
|
let locale_formulaMore = _locale.formulaMore;
|
|
// console.log(txt,r,c)
|
|
if(txt.indexOf(_this.error.r) > -1){
|
|
return [false, _this.error.r, txt];
|
|
}
|
|
|
|
if (!_this.checkBracketNum(txt)) {
|
|
txt += ")";
|
|
}
|
|
|
|
if(index==null){
|
|
index = Store.currentSheetIndex;
|
|
}
|
|
|
|
Store.calculateSheetIndex = index;
|
|
|
|
let fp = $.trim(_this.functionParserExe(txt));
|
|
|
|
if ((fp.substr(0, 20) == "luckysheet_function." || fp.substr(0, 22) == "luckysheet_compareWith") ) {
|
|
_this.functionHTMLIndex = 0;
|
|
}
|
|
|
|
if (!_this.testFunction(txt, fp) || fp == "") {
|
|
tooltip.info("",locale_formulaMore.execfunctionError);
|
|
return [false, _this.error.n, txt];
|
|
}
|
|
|
|
|
|
|
|
let result = null;
|
|
window.luckysheetCurrentRow = r;
|
|
window.luckysheetCurrentColumn = c;
|
|
window.luckysheetCurrentIndex = index;
|
|
window.luckysheetCurrentFunction = txt;
|
|
|
|
let sparklines = null;
|
|
|
|
try {
|
|
if(fp.indexOf("luckysheet_getcelldata") > -1){
|
|
let funcg = fp.split("luckysheet_getcelldata('");
|
|
|
|
for(let i = 1; i < funcg.length; i++){
|
|
let funcgStr = funcg[i].split("')")[0];
|
|
let funcgRange = _this.getcellrange(funcgStr);
|
|
|
|
if(funcgRange.row[0] < 0 || funcgRange.column[0] < 0){
|
|
return [true, _this.error.r, txt];
|
|
}
|
|
|
|
if(funcgRange.sheetIndex == Store.calculateSheetIndex && r >= funcgRange.row[0] && r <= funcgRange.row[1] && c >= funcgRange.column[0] && c <= funcgRange.column[1]){
|
|
if(isEditMode()){
|
|
alert(locale_formulaMore.execfunctionSelfError);
|
|
}
|
|
else{
|
|
tooltip.info("", locale_formulaMore.execfunctionSelfErrorResult);
|
|
|
|
}
|
|
|
|
return [false, 0, txt];
|
|
}
|
|
}
|
|
}
|
|
|
|
result = eval(fp);
|
|
|
|
//加入sparklines的参数项目
|
|
if(fp.indexOf("SPLINES") > -1){
|
|
sparklines = result;
|
|
result = "";
|
|
}
|
|
}
|
|
catch (e) {
|
|
let err = e;
|
|
//err错误提示处理
|
|
console.log(e,fp);
|
|
err = _this.errorInfo(err);
|
|
result = [_this.error.n, err];
|
|
}
|
|
|
|
//公式结果是对象,则表示只是选区。如果是单个单元格,则返回其值;如果是多个单元格,则返回 #VALUE!。
|
|
if(getObjType(result) == "object" && result.startCell != null){
|
|
if(getObjType(result.data) == "array"){
|
|
result = _this.error.v;
|
|
}
|
|
else{
|
|
if(getObjType(result.data)=="object" && !isRealNull(result.data.v)){
|
|
result = result.data.v;
|
|
}
|
|
else if(!isRealNull(result.data)){
|
|
result = result.data;
|
|
}
|
|
else {
|
|
result = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
//公式结果是数组,分错误值 和 动态数组 两种情况
|
|
let dynamicArrayItem = null;
|
|
|
|
if(getObjType(result) == "array"){
|
|
let isErr = false;
|
|
|
|
if(getObjType(result[0]) != "array" && result.length == 2){
|
|
isErr = valueIsError(result[0]);
|
|
}
|
|
|
|
if(!isErr){
|
|
if(getObjType(result[0]) == "array" && result.length == 1 && result[0].length == 1){
|
|
result = result[0][0];
|
|
}
|
|
else{
|
|
dynamicArrayItem = {"r": r, "c": c, "f": txt, "index":index,"data": result};
|
|
result = "";
|
|
}
|
|
}
|
|
else{
|
|
result = result[0];
|
|
}
|
|
}
|
|
|
|
window.luckysheetCurrentRow = null;
|
|
window.luckysheetCurrentColumn = null;
|
|
window.luckysheetCurrentIndex = null;
|
|
window.luckysheetCurrentFunction = null;
|
|
|
|
if (r != null && c != null) {
|
|
if (isrefresh) {
|
|
_this.execFunctionGroup(r, c, result, index);
|
|
}
|
|
|
|
if(!notInsertFunc){
|
|
_this.insertUpdateFunctionGroup(r, c, index);
|
|
}
|
|
}
|
|
|
|
if(!!sparklines){
|
|
return [true, result, txt, {type: "sparklines", data: sparklines}];
|
|
}
|
|
|
|
if(!!dynamicArrayItem){
|
|
return [true, result, txt, {type: "dynamicArrayItem", data: dynamicArrayItem}];
|
|
}
|
|
|
|
// console.log(result, txt);
|
|
|
|
return [true, result, txt];
|
|
},
|
|
testFunction: function(txt, fp) {
|
|
if (txt.substr(0, 1) == "=") {
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
},
|
|
functionResizeData: {},
|
|
functionResizeStatus: false,
|
|
functionResizeTimeout: null,
|
|
data_parm_index: 0 //选择公式后参数索引标记
|
|
}
|
|
|
|
export default luckysheetformula;
|