产品一张表luckysheet前端代码库
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

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;