>>* ParseNums.prg >>* Accepts a simple mathematical expression that may be a combination of addition and subtraction, as well as >>* straight numbers and percentages, and calculates the math. Returns the result. Returns a .NULL. >>* if an error is encountered. >>* May use parentheses to designate what should be done first. >>* If .T. is passed as the second parameters, error messages will not be shown >>Lparameters pNumString, pHideErrMess >>Local lLoc1, lLoc2, lCurLoc, lRetValue, lCurString, lWorkingStr, laSize, lSign, lStartingSign, lCurSign >> >>if type('pHideErrMess') <> 'L' >> return .null. >>endif >> >>if type('pNumString') <> 'C' >> if not pHideErrMess >> messagebox('Mathematical expression must be a string!',48,'Error') >> return .null. >> endif >>endif >> >>lRetValue = 0 >>lCurString = pNumString >> >>* As we work on sections of the string, we'll remove them from lCurString >>do while len(lCurString) > 0 >> lLoc1 = rat('(',lCurString) >> if lLoc1 <> 0 >> lLoc2 = rat(')',lCurString) >> if lLoc2 = 0 >> if not pHideErrMess >> mesagebox('Unbalanced parentheses in expression',48,'Error') >> endif >> lRetValue = .null. >> exit >> endif >> >> * lWorkingStr will be the section of the lCurString we are working on >> lWorkingStr = substr(lCurString,lLoc1+1,lLoc2-lLoc1-1) >> if lLoc1-1 <= 0 >> lStartingSign = '+' >> else >> lStartingSign = substr(lCurString,lLoc1-1,1) >> endif >> lCurString = stuff(lCurString,lLoc1-1,lLoc2-lLoc1+2,'') >> else >> lWorkingStr = lCurString >> lCurString = '' >> lStartingSign = '+' >> endif >> >> do while len(lWorkingStr) > 0 >> * We'll store the components of lWorking in an array in reverse order >> * of how we'll do the operation. >> * The array has 3 columns: >> * Column 1 = the number to be used in the calculation >> * Column 2 = the operation to be done on that number (+ or -) >> * Column 3 = .T. if the number is a percent >> >> * Populate the array >> lLoc1 = rat('+',lWorkingStr) >> lLoc2 = rat('-',lWorkingStr) >> do case >> case lLoc1 > lLoc2 >> lSign = '+' >> lCurLoc = lLoc1 >> case lLoc2 > lLoc1 >> lSign = '-' >> lCurLoc = lLoc2 >> otherwise >> lSign = '' >> lCurLoc = '' >> endcase >> >> if type('aPieces[1]') = 'U' >> laSize = 1 >> else >> laSize = alen(aPieces,1)+1 >> endif >> dimension aPieces[laSize,3] >> >> if not empty(lSign) >> aPieces[laSize,2] = lSign >> if right(alltrim(lWorkingStr),1) = '%' >> aPieces[laSize,3] = .T. >> lWorkingStr = left(lWorkingStr,len(lWorkingStr)-1) >> endif >> aPieces[laSize,1] = val(right(lWorkingStr,len(lWorkingStr)-lCurLoc)) >> lWorkingStr = left(lWorkingStr,lCurLoc-1) >> else >> aPieces[laSize,2] = '' >> if right(alltrim(lWorkingStr),1) = '%' >> aPieces[laSize,3] = .T. >> lWorkingStr = left(lWorkingStr,len(lWorkingStr)-1) >> endif >> aPieces[laSize,1] = val(lWorkingStr) >> lWorkingStr = '' >> endif >> enddo len(lWorkingStr) > 0 >> >> * Perform the calculation on this section >> for lI = laSize to 1 step -1 >> if empty(aPieces[lI,2]) >> lCurSign = lStartingSign >> else >> lCurSign = aPieces[lI,2] >> endif >> if aPieces[lI,3] >> lRetValue = lRetValue&lCurSign.(lRetValue*aPieces[lI,1]/100) >> else >> lRetValue = lRetValue&lCurSign.aPieces[lI,1] >> endif >> endfor >> release aPieces >>enddo len(lCurString) > 0 >> >>return lRetValue >>