亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何實現前端表格自動計算

發布時間:2021-05-20 09:56:56 來源:億速云 閱讀:963 作者:小新 欄目:移動開發

這篇文章將為大家詳細講解有關如何實現前端表格自動計算,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

序言

當我的團隊進行稅務系統模塊開發的時候,我發現他們需要花費80%的時間去解決計算問題,尤其體現在表格(Grid)中的計算,這些時間花在:

  • 寫前臺js代碼(因為用戶在表格中的輸入會影響其他單元格,所以需要即時將運算后的新值呈現給用戶看)

  • 寫后臺代碼(因為用戶對表格數據的更改會影響其他表格,所以要在用戶點擊保存時更新受影響表格的數據)

  • 實施修改計算方法,導致開發者需要修改代碼

于是我調研了稅務其他模塊的功能,發現稅務系統大量使用表格控件,而其中或多或少都會涉及到計算問題。而處理計算的方法,都是采用硬編碼。

計算,這個習以為常的編碼動作,其實很容易讓人聯想到Excel中的公式,更何況需求文檔本身就是以Excel的形式提供的。當我們在使用Excel的時候,可以在單元格中設置公式,通過改變源頭單元格的值,Excel將自動計算單元格公式,將結果值賦予目標單元格。那么,我們是否可以參考這種模式,開發者不再需要寫復雜難懂的計算邏輯,只需要根據實施提供的公式,將它們轉成某種格式的語句,再調用某種計算引擎產出結果,將結果呈現給用戶看或者持久化到數據庫?答案是肯定的,而這一切的核心就是自動計算引擎——AutoCalculate。

作用

AutoCalculate是表格復雜運算的解決方案,可以讓你省掉成百上千行的計算邏輯代碼,從此寫代碼就像寫Excel公式一般簡單。

適用范圍

前臺:

適用于ElementUI表格、EasyUI Grid控件、ParamQuery Grid等所有js表格控件中帶有公式的復雜運算

后臺:

適用,需要V8引擎

前臺用法

AutoCalculate由兩部分組成,分別是公式和計算引擎,公式是就是根據特定語法編寫的字符串,如:[Month22,1]#3 = [Month21,1] * 10,計算引擎即是AutoCalculate.js,負責解析公式。以下開始介紹如何書寫公式。

單元格

假設有這樣的場景,單元格①=單元格②+單元格③,對應的公式是:

[Month2,1] = [Month2,2] + [Month2,3]

如何實現前端表格自動計算

先來看看[Month2,1]代表什么,首先,中括號[ ]代表一個單元格,Month2即“1月”對應的列名,緊接著是一個逗號,,后面的1代表RowNo = 1,以此類推,

[Month2,2]代表列為“1月”且RowNo = 2的單元格

[Month2,3]代表列為“1月”且RowNo = 3的單元格

所以我們可以用[y,x]來代表一個單元格,y即列名,也稱作縱坐標, x即RowNo的值,也稱作橫坐標

如果表格沒有RowNo列怎么辦?如想尋找答案,請繼續往下閱讀

讓公式生效

//首先引入AutoCalculate.js
import AutoCalculate from '../components/AutoCalculate';
...

//定義一個AutoCalculate實例,formulas為公式數組
let autoCal = new AutoCalculate(formulas);

/* 調用cal方法
 * gridDatas(必填):表格數據
 * refField(必填):參考字段,即單元格[y,x]中x是哪個字段的值
 */
autoCal.cal(gridDatas, refField);

區域公式

實際上,除了1月,2月,3月……10月也存在類似的公式,即:

[Month2,1] = [Month2,2] + [Month2,3]

[Month3,1] = [Month3,2] + [Month3,3]

[Month4,1] = [Month4,2] + [Month4,3]

……
……
……

[Month20,1] = [Month20,2] + [Month20,3]

也就是說我們需要寫10條這樣的公式,對于簡單的場景來說,這不成問題,但是對于某些包含大量公式的表格,這種寫法存在一些弊端,比如容易寫錯,還有,公式長的時候也需要花費較多時間才能寫完。所以,便有了區域公式。

觀察上面的公式可以發現,其實每條公式都可以用一條公式來代替,例如以下公式:

[@,1] = [@,2] + [@,3]

這里沒有明確的列名,只是用了一個占位符@,但它足以代表以上10條公式。這個時候,我們只需要在適當的位置補上列名就可以了,所以,最終的公式就是:

{Month2, Month3, Month4, Month5, Month6, Month7, Month7, Month8, Month9, Month20}[@,1] = [@,2] + [@,3]

你需要將列名用,隔開,并放置在大括號{ }內,如此,1條公式便相當于10條公式。

占位符不僅僅可以用于縱坐標,還可用于橫坐標,如以下公式:

//公式1:
[YearTotal,3] = [Month2,3] + [Month3,3] + [Month4,3] + [Month5,3] + [Month6,3] + [Month7,3] + [Month7,3] + [Month8,3] + [Month9,3] + [Month20,3]

//公式2:
[YearTotal,4] = [Month2,4] + [Month3,4] + [Month4,4] + [Month5,4] + [Month6,4] + [Month7,4] + [Month7,4] + [Month8,4] + [Month9,4] + [Month20,4]

//公式3:
[YearTotal,5] = [Month2,5] + [Month3,5] + [Month4,5] + [Month5,5] + [Month6,5] + [Month7,5] + [Month7,5] + [Month8,5] + [Month9,5] + [Month20,5]

//公式4:
[YearTotal,6] = [Month2,6] + [Month3,6] + [Month4,6] + [Month5,6] + [Month6,6] + [Month7,6] + [Month7,6] + [Month8,6] + [Month9,6] + [Month20,6]

//公式5:
[YearTotal,2] = [Month2,2] + [Month3,2] + [Month4,2] + [Month5,2] + [Month6,2] + [Month7,2] + [Month7,2] + [Month8,2] + [Month9,2] + [Month20,2]

//公式6:
[YearTotal,7] = [Month2,7] + [Month3,7] + [Month4,7] + [Month5,7] + [Month6,7] + [Month7,7] + [Month7,7] + [Month8,7] + [Month9,7] + [Month20,7]

//公式7:
[YearTotal,9] = [Month2,9] + [Month3,9] + [Month4,9] + [Month5,9] + [Month6,9] + [Month7,9] + [Month7,9] + [Month8,9] + [Month9,9] + [Month20,9]

//公式8:
[YearTotal,12] = [Month2,12] + [Month3,12] + [Month4,12] + [Month5,12] + [Month6,12] + [Month7,12] + [Month7,12] + [Month8,12] + [Month9,12] + [Month20,12]

//公式9:
[YearTotal,13] = [Month2,13] + [Month3,13] + [Month4,13] + [Month5,13] + [Month6,13] + [Month7,13] + [Month7,13] + [Month8,13] + [Month9,13] + [Month20,13]

使用區域公式,可以寫成:

{2, 3, 4, 5, 6, 7, 9, 12, 13}[YearTotal,@] = [Month2,@] + [Month3,@] + [Month4,@] + [Month5,@] + [Month6,@] + [Month7,@] + [Month7,@] + [Month8,@] + [Month9,@] + [Month20,@]

由此可見,區域公式為公式的書寫帶來了極大的便利。

支持js語法

在實際場景中,我們經常會碰到一些復雜的公式,如下圖,單元格公式使用了Excel自帶的Max函數,對于這樣的公式,我們可以這樣寫:

[Month2,9] = ([Month2,6] - [Month2,7] - [Month2,8] > 0 ? [Month2,6] - [Month2,7] - [Month2,8] : 0) + [Month2,5]

如何實現前端表格自動計算

如你所見,公式支持js語法,你可以在公式等號右邊放入一個js變量,甚至js函數,只要是js解析引擎認識的語法,都被支持。

這里有個需要注意的地方,就是不可以將數組元素放入公式中,因為js的數組元素通常帶有“[ ]”符號,這與公式當中的單元格表示符”[ ]”產生沖突,所以數組元素被禁止使用,請留意這一點。

[y]公式

接下來,帶大家看一看另外一種場景,如圖,存在這樣的關系:

單元格① = 單元格② - 單元格③

你可能很快就寫出了以下公式:

[column3,1] = [column2,1] - [column1,1]
[column3,2] = [column2,2] - [column1,2]

如何實現前端表格自動計算

這樣寫本身沒有錯,但是我得提醒你,這里的行是不固定的,也就是說表格有多少行完全取決于當時的數據庫情況,有可能今天只有3行數據,明天會有5行,后天會有50行。我們不可能隨著行數增多而增加公式,所以對于這種行數不確定的表格,我們有一種新的寫法,我將它稱為[y]公式,因為跟普通公式相比,它沒有橫坐標:

[column3] = [column2] - [column1]

只需要一行公式,AutoCalculate便會將公式應用于指定列名下的所有行。

合計列與小數位數

有時候,我們需要求某一列的和,雖然求某一列的和可能不是我們的最終目的,但卻是我們完成計算的必要步驟,如存在以下關系:

單元格③ = 單元格① / 單元格②

單元格②是GroupApprovedTotal列的合計值,我們用<列名>來表示,即:<GroupApprovedTotal>。加上這里的行不固定,需要用到[y]公式,所以公式應該寫成:

[GroupApprovedTotalPercent] = [GroupApprovedTotal] / <GroupApprovedTotal>

如何實現前端表格自動計算

我們知道,在除法中,除數是不可以為0的,所以正確的寫法應該是:

[GroupApprovedTotalPercent] = <GroupApprovedTotal> === 0 ? 0 : [GroupApprovedTotal] / <GroupApprovedTotal>

當你將這條公式放你的代碼,并啟動程序后,聰明的你應該很快發現,你得到的值不夠精確,如上面單元格③顯示的數值是66.91%,如果你的單元格①和單元格②跟上圖的數值相同,你的單元格③很可能是67%,這是為什么呢?

默認的,AutoCalculate會將計算結果保留2位小數,67%,即0.67,如果想得到66.91%,即0.6691,那就是需要保留4位小數,這時,你需要告訴AutoCalculate,你需要保留4位小數,所以,完整的寫法應該是:

[GroupApprovedTotalPercent]#4 = <GroupApprovedTotal> === 0 ? 0 : [GroupApprovedTotal] / <GroupApprovedTotal>

在公式的等號左邊,被賦值單元格的右邊,加“#”號,緊跟著寫上小數位數,注意,“#”和小數位數之間不能有空格,前后可以有空格。

沒有RowNo的表格

終于到了回答這個問題的時候,我想問問大家,我們是如何在一個平面找到一個點的?答案就是需要這個點的橫坐標和縱坐標,同樣的,在一個表中,如何找到一個單元格?首先我們可以確定縱坐標,因為所有的列名都是已知的,關鍵就在于橫坐標的確定。采用RowNo來定位,大家一定會覺得似曾相識,因為它跟Excel左側的序號很像,但不代表只有數字才能作為橫坐標。只要值具有唯一性,即不重復,就可以作為橫坐標。

舉個例子,假設以下的表格是固定兩行,沒有RowNo,但是可以看出公司編號(BuCode)具有唯一性,那么BuCode就可以作為參考字段,BuCode的值就是橫坐標,那么公式就可以寫成:

[SumDiffMonth2,F1136] = [GroupApprovalMonth2,F1136] - [Month2,F1136]
[SumDiffMonth2,F2056] = [GroupApprovalMonth2,F2056] - [Month2,F2056]

如果有RowNo,用RowNo做參考字段時這樣寫:

[SumDiffMonth2,2] = [GroupApprovalMonth2,2] - [Month2,2]
[SumDiffMonth2,3] = [GroupApprovalMonth2,3] - [Month2,3]

如何實現前端表格自動計算

跨數據源計算

何為跨數據源計算?用過Excel公式的朋友應該能看懂下面這個單元格的公式代表的意思。很明顯這個單元格的值是其他Sheet的數據經過運算后的值,跨數據源計算就是專門處理這樣的場景。

如何實現前端表格自動計算

我們很少甚至不會在前臺做跨數據源計算,這里是想告訴大家如何書寫公式及調用AutoCalculate的方法,以便在“后臺用法”這一章節真正使用到它。

首先,為了取得其他數據源單元格的數據,我們需要拓展一下單元格,之前,我們的單元格是這樣的:[y,x],暫且稱為二元單元格吧,還有這樣的單元格:[y],成為一元單元格,現在,你會看到這樣的單元格:[外部數據源,y,x],即三元單元格,三元單元格的出現令到AutoCalculate定位單元格的能力從二維拓展到三維,即不管你有多少表,AutoCalculate都能找到你要的數據。

這是一條使用了三元單元格的公式:

[Month2,4] = [OutputTax,Month2,7]

其中OutputTax是某個數據源的名稱,你可以任意取名,越簡潔越好,否則復雜的公式會被寫得很長,難以閱讀。

下面這條公式會從兩個數據源OutputTax和TaxRate取值:

[Month2,5] = [OutputTax,Month2,10] * (1 + [TaxRate,Month2,1] / 100)

我相信通過閱讀前面章節的內容,你已經能夠看懂下面公式的意思,其中前三行公式使用了外部數據源,并結合了區域公式的寫法。

如何實現前端表格自動計算

是時候調用我們的計算方法了,為了演示效果,我添加了一個按鈕,并將方法寫在按鈕事件中

如何實現前端表格自動計算

看看我們做了什么:

① 取得某個外部數據源outputTaxDatas

② 取得當前表格的數據源payableTaxDatas

③ 從數據庫獲取另一個外部數據源taxRateDatas

④ 這里是重點,先來看看AutoCalculate 的構造函數,這里有兩個參數:

如何實現前端表格自動計算

formulas:公式,一個數組

options:可選參數,一個object對象

options有個屬性externalDatas,表示外部數據源,是一個數組,因為數據可能有多個,每個數組元素都是一個對象,有3個屬性:

name:外部數據源名稱,這里取什么名稱,對應公式中的外部數據源名稱

refField:參考字段

datas:數據源

實例化AutoCalculate后,這里調用了一個新的方法calculate,它有2個參數:

如何實現前端表格自動計算

gridDatas:需要重新計算的表格數據,是一個數組

refField:參考字段

AutoCalculate之所有支持所有的js表格控件以及能被后臺調用,就是借助于這個方法,因為不論是哪種js表格控件,都能夠提取出表格數據(純數據),數據通常是數組形式,只要將這個數組傳進來就可以了。

⑤ 調用calculate后,payableTaxDatas的值已經是運算過的最新值,現在將它綁定到當前的表格即可。

運行程序后的界面:

如何實現前端表格自動計算

點擊獲取數據后:

如何實現前端表格自動計算

后臺用法

后臺調用AutoCalculate,我們需要用到V8引擎,還有一點很重要,后臺調用AutoCalculate也需要用到公式,我們之前的做法是將所有公式放在Extjs的Controller文件中,如下圖:

如何實現前端表格自動計算

為了方便后臺調用,我們將公式提取出來作為一個單獨的文件

如何實現前端表格自動計算

項目中對AutoCalculate后臺調用進行了封裝,使用非常簡單。

如何實現前端表格自動計算

調用方法如圖:

如何實現前端表格自動計算

還是分步解析:

① 保存當前表格的數據

② 獲取公式所在js文件的目錄

③ 獲取兩個外部數據源

④ 調用封裝后的后臺方法,使用了第②步和第③步獲取的數據,其中FormulaExpression是公式表達式,即通過這個表達是來找到你提供的js文件中的公式

⑤ 上一步返回的newDatas已經是經過運算的最新數據,現在將這些數據保存到數據庫

注意事項

書寫公式時有兩點需要注意:

單元格中不允許出現空格

/正確寫法:
[Month22,1] = [Month21,1] * 10

//錯誤寫法:
[Month22,1 ] = [ Month21, 1] * 10

小數位數標記與小數位數之前不能有空格

//正確寫法:
[Month22,1] #3 = [Month21,1] * 10

//錯誤寫法:
[Month22,1] # 3 = [Month21,1] * 10

關于“如何實現前端表格自動計算”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

广宁县| 岳池县| 和硕县| 灵武市| 萨嘎县| 都兰县| 富裕县| 建昌县| 巢湖市| 鄂伦春自治旗| 黄陵县| 浏阳市| 三门县| 泾川县| 枣阳市| 通渭县| 黑龙江省| 定安县| 临邑县| 镇雄县| 河北区| 辽宁省| 庆安县| 济源市| 长寿区| 海兴县| 新平| 长岛县| 湖北省| 甘泉县| 开阳县| 安塞县| 会泽县| 大姚县| 梓潼县| 茶陵县| 呼和浩特市| 阿鲁科尔沁旗| 喀什市| 双峰县| 偃师市|