組合公式為 "((r1c1+r1c2)/r1c3)"
??????? 1. 組合的公式是一個字符串.
??????? 2. 字符串元素包括"rc0123456789+-*/()"
??????? 3. r1c1=7,r1c2=2,r1c3=4
??????? 4. 求組合成的公式的值是多少.

解決思路:
??????? 1.對公式進行字符合法性檢查.
??????? 2.對公式中出現的變量進行取值替換.
??????? 3.檢查語句的合法性.(組合規則)
??????? 4.檢查運算的合法性.(除數為0的情況)
????????5.求值.


具體解決方法:
??????? str1 = "(r1c1+r1c2)/r1c3)"
??????? str1 = replace(str1," ","")? '去除公式中間出現的空格
??????? 1.? 對公式進行字符合法性檢查.

????????????? bool1 = getDataOperationCharCheck(str1)

????????????? if bool1 = false then
????????????????????? Response.write "公式不合法.有異常字符出現.<br>"
????????????? else
????????????????????? Response.write "公式檢查通過!<br>"
????????????? end if

??????? 2.對公式中出現的變量進行取值替換

??????????????? RCstr = getdataoperation(str1)

??????? 3.檢查語句的合法性.(組合規則)

??????????????? bool2 = getDataOperationSyntaxCheck(RCstr)

????????????????????? if bool2 = false then
???????????????????????????????? Response.write "運算公式語法不合法,有組合異常字符出現.<br>"
??????????????????????else
???????????????????????????????? Response.Write "運算公式語法檢查通過!<br>"
????????????????????? end if

??????????4.檢查運算的合法性.(除數為0的情況)

?????????????????? bool3 = getDataOperationRunCheck(RCstr)

??????????????????????? if bool3 = false then
??????????????????????????????? Response.write "運算公式運算不合法,有除數為0出現.<br>"
??????????????????????? else
??????????????????????????????? Response.write "運算公式運算合法性檢查通過!<br>"??
??????????????????????? end if

?????????? 5.求值.
?
??????????????????????? intValue = getRunSearch(RCstr)

?????????? 6.運算結果:

??????????????????????? (((7*1.0)+(2*1.0))/(4*1.0)) = 2.25

'1.=============================================================

'對原始公式進行字符檢查,是否有不合法的字符

function getDataOperationCharCheck(datastr)
?????? datastr = replace(datastr," ","")
??????? sumchar = "rc0123456789+-*/()"
????????strlen = len(datastr)
????????strreturn = true
????????for i = 1 to strlen
????????????????singlechar = mid(datastr,i,1)
????????????????if instr(sumchar,singlechar) = 0 then
????????????????????????strreturn = false
????????????????????????exit for
????????????????end if
????????next
????????getDataOperationCharCheck = strreturn
end function

'2.==============================================================

'對原始計劃公式進行取值替換.
'實現方法:對原始字符串進行單個字符檢查,
'在出現 "+-*/()" 中的任何一個字符時,對已經組合生成的變量進行取值.
'在取到值的同時對其進行 double 轉換 ,實現方法是 (intvalue * 1.0)

function getdataoperation(datastr)
??????? strlen = len(datastr)??
????????sunstr = ""
????????strID = ""
????????intvalue = 0
????????singlechar = ""
????????operationstr="()+-*/"
????????for i=1 to strlen
????????????????'Response.write mid(datastr,i,1) & "<br>"?
????????????????singlechar = mid(datastr,i,1)
????????????????if instr(operationstr,singlechar) > 0 then
???
????????????????????????if strID <> "" then
????????????????????????????????intvalue = getValue(strID)
????????????????????????????????sunstr = sunstr & "(" & intvalue & "*1.0)"?? '(1)?????
????????????????????????????????intvalue = 0
????????????????????????????????strID = ""??????????
????????????????????????end if
????????????????????????sunstr = sunstr & singlechar
????????????????????????singlechar = ""
????????????????else
????????????????????????strID = strID & singlechar
????????????????end if?????
????????next
????????getdataoperation = sunstr
end function

'變量取值函數.
'下列數據是為測試使用.
'
function getValue(strRC)
??????? select case strRC
????????????????case "r1c1"
????????????????????????getValue = 2
????????????????case "r1c2"
????????????????????????getValue = 7
????????????????case "r1c3"
????????????????????????getValue = 2
???????????????end select
end function

'3.==============================================================

'對公式進行語法合法性檢查.
'eg.檢查 (),--,++,**,//,(/,*) 等 是否成對出現.
'檢查是否有


function getDataOperationSyntaxCheck(datastr)
??????? strreturn = true
????????datastr = replace(datastr," ","")? '去除所有的空格
????????strlen = len(datastr)
????????num1 = 0?????????????????????????? '記錄 括號的 個數? 采用 有 (? 加1, 有 ) 減1
????????upsinglechar = ""????????????????? '相對本次的字符的上一個字符
????????singlechar = ""
????????operationstr1="()+-*/"
????????operationstr2="(+-*/"????????????? '相對 在 (? 左邊出現的運的符號是正確的.
?
????????for i = 1 to strlen
????????????????singlechar = mid(datastr,i,1)
????????????????select case singlechar
????????????????????????case "("
????????????????????????????????num1 = num1 + 1
????????????????????????????????if upsinglechar <> "" then
????????????????????????????????????????if instr(operationstr2,upsinglechar) = 0 then?? '在左括號的左邊若不為空,必需出現 "(+-*/" 中的一個.
??????????????????????????????????????????????? strreturn = false
??????????????????????????????????????????????? exit for
??????????????????????????????????????? end if
??????????????????????????????? end if
???
????????????????????????case ")"
????????????????????????????????num1 = num1 - 1
????????????????????????????????if num1 < 0 then
????????????????????????????????????????strreturn = false
????????????????????????????????????????exit for
????????????????????????????????end if
????????????????????????????????if instr(operationstr2,upsinglechar) > 0 then?????? '在右括號的左邊若不為空,必需不能出現 "(+-*/" 中的一個
????????????????????????????????????????strreturn = false
????????????????????????????????????????exit for
????????????????????????????????end if
???
????????????????????????case "+"
????????????????????????????????if instr(operationstr2,upsinglechar) > 0 then?????? '在加號的左邊若不空,必需不能出現 "(+-*/" 中的一個
????????????????????????????????????????strreturn = false
????????????????????????????????????????exit for
????????????????????????????????end if
???
????????????????????????case "-"
???????????????????????????????? if instr(operationstr2,upsinglechar) > 0 then????? '在減號的左邊若不空,必需不能出現 "(+-*/" 中的一個
????????????????????????????????????????strreturn = false
????????????????????????????????????????exit for
????????????????????????????????end if
????????????????????????case "*"
???????????????????????????????? if instr(operationstr2,upsinglechar) > 0 then????? '在乘號的左邊若不空,必需不能出現 "(+-*/" 中的一個
????????????????????????????????????????strreturn = false
????????????????????????????????????????exit for
????????????????????????????????end if
????????????????????????case "/"
???????????????????????????????? if instr(operationstr2,upsinglechar) > 0 then????? '在除號的左邊若不空,必需不能出現 "(+-*/" 中的一個
????????????????????????????????????????strreturn = false
????????????????????????????????????????exit for
????????????????????????????????end if
????????????????end select
????????????????upsinglechar = singlechar??
????????????????singlechar = ""
????????next
????????getDataOperationSyntaxCheck = strreturn
end function

'4.==============================================================
?
'對組合公式進行運算合法性的檢查
'首選查找有沒有 "/0"出現.
'其次查找類似 "/(****)" = /0 出現

function getDataOperationRunCheck(datastr)
??????? strreturn = true
????????if instr(datastr,"/")>0 then
??????????????? if instr(datastr,"/0") > 0 then????
????????????????????????strreturn = false
????????????????else

????????????????????????'對/ 后面出現的()內的數據進行運算,取值是否會有0出現.
????????????????????????'首先計算 "/" 出現的次數
????????????????????????'再次判斷 "/(" 出現的次數
????????????????????????'若 "/(" 出現的次為0 則安全.

????????????????????????intnum1 = getInstrNum(datastr,"/")
????????????????????????intnum2 = getInstrNum(datastr,"/(")
????????????????????????if intnum2 > 0 then
????????????????????????????????for j = intnum2 to 1 step -1
????????????????????????????????????????intpoint1 = getInstrPoint(datastr,"/(",j)
????????????????????????????????????????if intpoint1 > 0 then
????????????????????????????????????????????????sumpoint = getRunCheck(datastr,intpoint1)
????????????????????????????????????????????????if? CDbl(sumpoint) = CDbl(0) then
????????????????????????????????????????????????????????strreturn = false
????????????????????????????????????????????????????????exit for
????????????????????????????????????????????????end if
????????????????????????????????????????end if
????????????????????????????????next?????
????????????????????????end if
????????????????end if??
????????end if
????????getDataOperationRunCheck= strreturn
end function


'檢查字符運行的合法性.
'主要是對/()出現的字公式進行計算是否會等于0

function getRunCheck(datastr,intpoint1)
??????? strlen = len(datastr)
????????intpoint = intpoint1 + 1
????????intnum = 0
????????singlechar = ""
????????rcsearch = ""
????????intreturn = 0
????????for m = intpoint to strlen
????????????????singlechar = mid(datastr,m,1)
????????????????if singlechar = "(" then
????????????????????????intnum = intnum + 1
????????????????end if
????????????????if singlechar = ")" then
????????????????????????intnum = intnum - 1
????????????????end if
????????????????rcsearch = rcsearch & singlechar
????????????????if intnum = 0 then????
????????????????????????intreturn? = getRunSearch(rcsearch)
????????????????????????exit for
????????????????end if???
????????next
????????getRunCheck = intreturn
end function

'5.==============================================================

'求值.
function getRunSearch(strrcsearch)
???????? sql = "select " & strrcsearch & " as rcvalue "
?????????Set rs = conn.execute(sql)
?????????'Response.write "<br>" & strrcsearch & "=" & rs("rcvalue") & "<br>"
?????????getRunSearch = rs("rcvalue")
end function

'公共函數==============================================================

'返回substr? 在 str1 中出現的次數

function getInstrNum(str1,substr)
??????? strlen = len(str1)
????????substrlen = len(substr)
????????singlechar = ""
????????intreturn = 0
????????for i = 1 to strlen
????????????????singlechar = mid(str1,i,substrlen)
????????????????if singlechar = substr then
????????????????????????intreturn = intreturn + 1
????????????????end if
????????next
????????getInstrNum = intreturn
end function

'返回substr 在 str1 中 第 intnum 次出現的位置
'intnum 必需是大于0的正整數

function getInstrPoint(str1,substr,intnum)
????????intreturn = 0
????????strlen = len(str1)
????????substrlen = len(substr)
????????singlechar = ""
????????intcount = 0
????????for i = 1 to strlen
????????????????singlechar = mid(str1,i,substrlen)
????????????????if singlechar = substr then
????????????????????????intcount = intcount + 1
????????????????end if
????????????????if intcount = intnum then
????????????????????????intreturn = i
????????????????????????exit for
????????????????end if
????????next
????????getInstrPoint = intreturn
end function