czardas Posted September 17, 2016 Posted September 17, 2016 (edited) Much work still needs to be done on my current project, but design concepts often benefit more from early criticism. Although there may be nothing particularly innovative about this project, user experience is everything. I would like you to look at the behaviour of the controls on this GUI. Unless you type something really awful, it allows you to finish typing the formula before testing the input. When typing into an edit control, pressing the enter key activates the okay button. The program itself, mainly consists of a listview control, which you can't see - just imagine it looks like a stone age version of Excel with a nice paint job, but no bells or whistles. What Row Sum (Σ) is intended to do is loop through all the rows, calculate a sum and print the output in a newly created column. The user is prompted to type a formula into the following GUI. Please try to figure it out, and break it any way you can. expandcollapse popup#include <GUIConstants.au3> #include <GuiEdit.au3> #include <Misc.au3> Global $g_iAvailableCols = 24 ; arbitary dev variable [column count will eventually be read from a listview control] ; missing several thousand lines of code... Formula() ; caution about including columns containing empty fields in the formula ; empty fields are treated as zero ; with addition and subtraction there is never any problem ; multiplication by an empty field (or by zero) returns zero ; division by an empty field (or by zero) returns an empty field [unless - see exception] ; use of the power operator is limited to rows in which all referenced fields contain numbers ; imaginary roots of negative numbers return an empty field [unless - see exception] ; exception: infinity (or an imaginary number) to the power of zero returns a meaningless number Func FormulaSyntax() MsgBox(BitOR(64, 8192), "Row Sum (" & ChrW(0x03A3) & ") : Syntax To Use", _ ; $MB_ICONINFORMATION, $MB_TASKMODAL " mathematical operators :" & @TAB & "+ - * / ^" & @CRLF & _ " column numbers :" & @TAB & @TAB & "c1, c2, c3 etc..." & @CRLF & _ " decimal digits :" & @TAB & @TAB & "0 to 9 and ." & @CRLF & _ " parenthesis :" & @TAB & @TAB & "( )" & @CRLF & _ " minus sign :" & @TAB & @TAB & "-1, -c2, -(c3) etc..." & @CRLF & _ " example :" & @TAB & @TAB & @TAB & "c1 +c2 -c3") EndFunc ;==> FormulaSyntax Func Formula() ; ($hParent, $idListView, $hListView) ; [missing parent window] Local $sTitle = "Row Sum (" & ChrW(0x03A3) & ")", _ $iStyle = BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU), _ $iExStyle = BitOR($WS_EX_MDICHILD, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST) Local $hChild = GUICreate($sTitle, 334 +25, 105 +1, Default + 100, Default + 100); , $iStyle, $iExStyle, $hParent) Local $hLabel = GUICtrlCreateLabel("Formula :", 8, 8, 55, 18) GUICtrlSetFont(-1, 10) Local $hSyntax = GUICtrlCreateButton("???", 72, 7, 40, 20) Local $hLabel = GUICtrlCreateLabel("Header :", 127, 8, 49, 18) GUICtrlSetFont(-1, 10) Local $hHeader = GUICtrlCreateInput("", 182, 7, 170, 20) GUICtrlSetFont(-1, 10) Local $hInput = GUICtrlCreateInput("", 7, 33, 320 +25, 40, BitOR($WS_TABSTOP, $ES_MULTILINE)) GUICtrlSetFont(-1, 10) Local $hCheckBox = GUICtrlCreateCheckbox(" Round to", 7, 79, 75, 20) GUICtrlSetFont(-1, 10) Local $hPlaces = GUICtrlCreateInput("2", 86, 79 +1, 20, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER)) GUICtrlCreateLabel("decimal places", 114 -2, 79 +2, 92, 18) GUICtrlSetFont(-1, 10) Local $hCancel = GUICtrlCreateButton("Cancel", 210, 79 +1, 66, 20) Local $hOkay = GUICtrlCreateButton("OK", 285, 79 +1, 66, 20) GUISetState(@SW_SHOW) Local $sInput = "", $aArray, $iError = 0, $iCols = $g_iAvailableCols ; $iCols = _GUICtrlListView_GetColumnCount($hListView), _ ; >>> CHANGE THIS LATER ;$iRows = _GUICtrlListView_GetItemCount($hListView), $aColOrder = _GUICtrlListView_GetColumnOrderArray($hListView) Local $vTemp, $msg2, $iPlaces = '2' While 1 $msg2 = GUIGetMsg() If $msg2 = $hCancel Or $msg2 = $GUI_EVENT_CLOSE Then ExitLoop If $msg2 = $hSyntax Then FormulaSyntax() ContinueLoop EndIf $vTemp = GUICtrlRead($hPlaces) If $vTemp <> $iPlaces Then If $vTemp > 14 Then GUICtrlSetData($hPlaces, 14) $iPlaces = 14 _GUICtrlEdit_SetSel($hPlaces, 0, -1) ElseIf Not $vTemp Then GUICtrlSetData($hPlaces ,'0') $iPlaces = '0' _GUICtrlEdit_SetSel($hPlaces, 0, -1) EndIf EndIf If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED _ And BitAND(GUICtrlGetState($hPlaces), $GUI_DISABLE) == $GUI_DISABLE Then GUICtrlSetState($hPlaces, $GUI_ENABLE) ElseIf BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) <> $GUI_CHECKED _ And BitAND(GUICtrlGetState($hPlaces), $GUI_ENABLE) == $GUI_ENABLE Then GUICtrlSetState($hPlaces, $GUI_DISABLE) EndIf $sFormula = GUICtrlRead($hInput) If $sFormula <> $sInput Then If StringRegExp($sFormula, '[^ ]') Then ; spaces between components are ignored If Not ValidSyntax($sFormula, $iCols) Then If @extended < 5 Then If $iError = 0 Then GUICtrlSetBkColor($hInput, 0xFFA090) $iError = 1 ElseIf $iError Then GUICtrlSetBkColor($hInput, 0xFFFFFF) $iError = 0 EndIf ElseIf $iError Then GUICtrlSetBkColor($hInput, 0xFFFFFF) $iError = 0 EndIf ElseIf $iError Then GUICtrlSetBkColor($hInput, 0xFFFFFF) $iError = 0 EndIf $sInput = $sFormula EndIf ; BitAND(WinGetState($hChild), $WIN_STATE_ACTIVE) = 8 If $msg2 = $hOkay Or (_IsPressed("0D") And BitAND(WinGetState($hChild), 8) = 8 And (ControlGetFocus($hChild) = "Edit2" Or ControlGetFocus($hChild) = "Edit1")) Then $sFormula = GUICtrlRead($hInput) ; If StringRegExp($sFormula, '[^ ]') And ValidSyntax($sFormula, $iCols) Then ; missing formula execution code MsgBox(0, "VALID SYNTAX", "Well done, your formula can safely be executed, but" & @CRLF & "can't find parent window.") ExitLoop Else Switch @extended Case 1 $vTemp = "The formula contains illegal characters." Case 2 $vTemp = "No such column exists." Case 3 $vTemp = "The formula contains a syntax error." Case 4 $vTemp = "The formula is missing opening parenthesis." Case 5 $vTemp = "The formula is unterminated" case 6 $vTemp = "The formula is missing closing parenthesis." EndSwitch MsgBox(262160, "uh-uh!", StringRegExp($sFormula, '[^ ]') ? $vTemp : "Please enter a formula.") While _IsPressed("0D") Sleep(50) WEnd ;$iError = 1 EndIf EndIf WEnd GUIDelete($hChild) EndFunc ; formula Func ValidSyntax($sFormula, $iMax) ; [currently requires external check that string <> ""] ; quick test for accepted characters If StringRegExp($sFormula, '(?i)[^c \d\.\+\-\*/\^\(\)]') Then Return SetExtended(1, False) ; illegal characters If StringRegExp($sFormula, '(?i)\.\D|c[0\D]|\d\s+[\.\d]') Then Return SetExtended(3, False) ; syntax $sFormula = StringStripWS($sFormula, 8) ; strip all spaces ; split to separate formula components Local $aFormula = StringRegExp($sFormula, '(?i)\-?c\d+|\-?c|\-?\d*\.\d*|\-?\d+|\-\(|[\+\-\*/\^\(\)]|.+', 3), _ ; create array [ADDED] ==> |.+ $iLast, $sTest, $sExpect = '(?i)\-?\(|\-?c\d+|\-?c|\-?\d*\.\d*|\-?\d+|\-', _ ; valid first component $iBracket = 0, $bSyntax = False, $bNoSuch = False, $bTermination = False ; error tracking variables For $i = 0 To UBound($aFormula) -1 If Not StringRegExp($aFormula[$i], $sExpect) Then ; unexpected code sequence $bSyntax = True ExitLoop EndIf If StringRegExp($aFormula[$i], '(?i)\-?c\d+') Then ; column number $sTest = StringRegExpReplace($aFormula[$i], '(?i)[\-c]+', '') If $sTest > $iMax Or $sTest == 0 Then ; no such column exists $bNoSuch = True ExitLoop EndIf $sExpect = '[\+\-\*/\^\)]' ; operators / closing brackets ElseIf StringRegExp($aFormula[$i], '\-?\d*\.\d*') Then ; decimal If $aFormula[$i] == '.' Or $aFormula[$i] == '-.' Then If $i = UBound($aFormula) -1 Then $bTermination = True ExitLoop EndIf $bSyntax = True ; badly formated decimal ExitLoop EndIf $sExpect = '[\+\-\*/\^\)]' ; as above ElseIf StringRegExp($aFormula[$i], '\-?\d+') Then ; integer $sExpect = '[\+\-\*/\^\)]' ElseIf StringRegExp($aFormula[$i], '\A[\+\-\*/\^]\z') Then ; operator $iLast = UBound($aFormula) -1 If $i = $iLast Or ($i = $iLast -1 And $aFormula[$iLast] == '-') Then $bTermination = True ExitLoop EndIf $sExpect = '(?i)\-?\(|\-?c\d+|\-?c|\-?\d*\.\d*|\-?\d+' ElseIf $aFormula[$i] == '(' Or $aFormula[$i] == '-(' Then ; opening bracket $iBracket += 1 $sExpect = '(?i)\-?\(|\-?c\d+|\-?c|\-?\d*\.\d*|\-?\d+|\-' ElseIf $aFormula[$i] == ')' Then ; closing bracket $iBracket -= 1 $sExpect = '[\+\-\*/\^\)]' ElseIf $aFormula[$i] = 'c' Or $aFormula[$i] = '-c' Then ; unterminated column number If $i = UBound($aFormula) -1 Then $bTermination = True Else $bSyntax = True ExitLoop EndIf Else ; unexpected exception [this should never happen] $bSyntax = True ExitLoop EndIf If $iBracket < 0 Then ExitLoop ; closing (unopened) parenthesis error ; [formula looks okay so far] Next ; better to be a bit wordy [for clarity] If $bNoSuch Then Return SetExtended(2, False) ; no such column exists If $bSyntax Then Return SetExtended(3, False) ; syntax error If $iBracket < 0 Then Return SetExtended(4, False) ; missing opening parenthesis If $bTermination Then Return SetExtended(5, False) ; formula may not terminate with operator or c If $iBracket > 0 Then Return SetExtended(6, False) ; missing closing parenthesis ; ConsoleWrite('valid' & @LF) Return True ; formula is correct EndFunc ;==> ValidSyntax Edited September 23, 2016 by czardas operator64 ArrayWorkshop
water Posted September 17, 2016 Posted September 17, 2016 Just did a quick test. You stated that "user experience is everything". I, as a user, would like to see the general error message "The formula you entered contains errors." replaced by helpful error messages like "no such column exists" etc. czardas 1 My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
czardas Posted September 17, 2016 Author Posted September 17, 2016 Thanks water , how very true. I should have added that part: all the information is returned by ValidSyntax() with the @extended flag. I was just too lazy to add the final code (or distracted by other concerns). I was more wondering if I might have missed something while testing formula syntax. operator64 ArrayWorkshop
water Posted September 17, 2016 Posted September 17, 2016 Just noticed that there is a limit of 24 columns. Would be fine to have this described in the help function My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
czardas Posted September 17, 2016 Author Posted September 17, 2016 (edited) The limit is a temporary measure. You can change it to any number you like > 0. Modify this line: Global $g_iAvailableCols = 24 ; arbitary dev variable [column count will eventually be read from a listview control] Edited September 17, 2016 by czardas operator64 ArrayWorkshop
water Posted September 17, 2016 Posted September 17, 2016 I mean: Modify the help page to " column numbers :" & @TAB & @TAB & "c1, c2, c3 etc. maximum is c" & $g_iAvailableCols & @CRLF & _ My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
water Posted September 17, 2016 Posted September 17, 2016 If the # of decimal places exceeds 14 then it is set to the # of allowed columns (now 24). Is this intended by you? My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
czardas Posted September 17, 2016 Author Posted September 17, 2016 Maybe, I get what you are saying. There will be a help menu topic. I wanted to know if it is possible to figure out what's going on without the need to refer to help topics. There has to be a quick syntax reference though. I'm just about to update the first post to include a more detailed error report. operator64 ArrayWorkshop
czardas Posted September 17, 2016 Author Posted September 17, 2016 (edited) Oops, I missed your last question about decimal places (post #7): an error crept in on my first edit which I have now fixed. I also notice that the final error message doesn't entirely like the enter key when an edit control has focus. It's an easy fix. Edit: The enter key issue has also been fixed now. Edited September 17, 2016 by czardas operator64 ArrayWorkshop
czardas Posted September 18, 2016 Author Posted September 18, 2016 (edited) Another validation bugfix, although you probably won't notice any difference. In theory it should be easy to quickly learn how to type a formula with just the information available. How easy do you think this is? Does the colour change assist you or annoy you? Edited September 18, 2016 by czardas operator64 ArrayWorkshop
water Posted September 18, 2016 Posted September 18, 2016 I like the colour change because it immediately tells me that the last letter/number I entered was wrong. czardas 1 My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
czardas Posted September 18, 2016 Author Posted September 18, 2016 @water I couldn't ask for a better critic after all the work you have done creating the Excel UDF. I really appreciate you taking the time to try it. operator64 ArrayWorkshop
water Posted September 18, 2016 Posted September 18, 2016 Thanks My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
czardas Posted September 22, 2016 Author Posted September 22, 2016 (edited) I've made some small improvements to the code in first post. I may change it to allow rounding up to 15 decimal places. Once I implement this code, it may become unrecognizable. While this may not be the most exciting topic of discussion, I'm also posting the code I've just written for rounding and formatting the executed formula, since it is part of the same module: it might also be of inspiration to someone. It is currently intended that the formula will return a double. The following code runs with all the safeties turned off (potentially returning up to 17 significant digits along with a load of zeros). The user will be advised (not forced) to remain within 15 significant figures when rounding. Trailing zero padding is added by default. expandcollapse popupMsgBox(0, "", DecimalPlaces(Execute('0.30000000000000099'), 15)) MsgBox(0, "", DecimalPlaces(Execute('2/-3'), 15)) MsgBox(0, "", DecimalPlaces(Execute('-0.000000000000011 *3'), 15)) MsgBox(0, "", DecimalPlaces(Execute('10000000000000.01000000000000000'), 15)) MsgBox(0, "", DecimalPlaces(Execute('-123456789012345.6199123458989'), 3)) MsgBox(0, "", DecimalPlaces(1.8734176520787252e+004, 12)) ; lucky number! MsgBox(0, "", DecimalPlaces(Execute('-000222222222222222922222222222222222222200.888888888888888*2'), 14)) ; accepts doubles Func DecimalPlaces($fNumber, $iPlaces = 2) ;, $bTrailingZeros = True) ; [add this option later along with program settings] ; error checks [magnitude maybe] $iPlaces = Int($iPlaces) ; max = 15 $fNumber = Number($fNumber, 3) ; convert to double (just in case) [more complex routines could also be written: BigNum etc...] Local $bNeg = False If StringLeft($fNumber, 1) == '-' Then $bNeg = True $fNumber = Abs($fNumber) EndIf $fNumber = Round($fNumber, $iPlaces) Local $nDigits, $iExponent, $nOutput, $iLen, $iDot = StringInStr($fNumber, '.') If StringInStr($fNumber, 'e') Then $nDigits = StringReplace(StringRegExpReplace($fNumber, 'e[\+\-]\d+\z', ''), '.', '') $iLen = StringLen($nDigits) $iExponent = StringRight($fNumber, 4) If $iLen = 15 Then ; [uh-uh - rounding had no discernible effect on length] $iLen = $iExponent + $iPlaces +1 $nDigits = __FloatToDigits($fNumber, (($iLen < 16) ? $iLen : 16)) ; return all 17 digits of the rounded double [it makes sense] $iExponent = @extended $iLen = StringLen($nDigits) Else $iExponent += (1 -$iLen) EndIf ElseIf $iDot And StringLen($fNumber) < 16 Then $nOutput = StringLeft($fNumber & '000000000000000', $iDot + $iPlaces) If $bNeg Then $nOutput = '-' & $nOutput Return $nOutput Else $iLen = ($iDot ? $iDot : StringLen($fNumber)) + $iPlaces $nDigits = __FloatToDigits($fNumber, (($iLen < 16) ? $iLen : 16)) $iExponent = @extended $iLen = StringLen($nDigits) EndIf Local $sZeros = '000000000000000' If $iExponent < 0 Then Local $iGap = $iLen + $iExponent If $iGap < 1 Then $nOutput = '0.' & StringLeft($sZeros, Abs($iGap)) & $nDigits Else $nOutput = StringLeft($nDigits, $iGap) & '.' & StringRight($nDigits, $iLen -$iGap) EndIf $iGap = $iLen -$iGap If $iGap < $iPlaces Then $nOutput &= StringLeft($sZeros, $iPlaces -$iGap) ElseIf $iGap > $iPlaces Then ; this one slipped through the net Local $bAddOne = (StringMid($nOutput, StringInStr($nOutput, '.') +$iPlaces +1, 1) >= 5) ? True : False ; round up $nOutput = StringTrimRight($nOutput, $iGap -$iPlaces) If $bAddOne Then ; when all else fails, use the old fashioned method Local $vNext, $nRound For $i = StringLen($nOutput) To 1 Step -1 $vNext = StringMid($nOutput, $i, 1) If $vNext = '.' Then $nRound &= '.' Else $vNext += 1 If $vNext < 10 Then $nRound &= $vNext $nOutput = StringLeft($nOutput, $i -1) & StringReverse($nRound) $bAddOne = False ExitLoop ; this should happen on the first run [does this loop ever actually repeat?] EndIf $nRound &= '0' EndIf Next If $bAddOne Then $nOutput = '1' & StringReverse($nRound) EndIf EndIf Else While StringLen($sZeros) < $iExponent $sZeros &= '000000000000000' WEnd $nOutput = $nDigits & StringLeft($sZeros, $iExponent) & '.' & StringLeft('000000000000000', $iPlaces) EndIf If $iPlaces = 0 Then $nOutput = StringReplace($nOutput, '.', '') If $bNeg And StringRegExp($nOutput, '[1-9]') Then $nOutput = '-' & $nOutput Return $nOutput EndFunc ;==> DecimalPlaces ; function taken from : Fraction.au3 ; #INTERNAL_USE_ONLY# ========================================================================================================== ; Name...........: __FloatToDigits ; Description ...: Extracts a specified number of digits from a float. ; Syntax.........: __FloatToDigits($fFloat, $iDigits) ; Parameters.....; $fFloat - The float to extract the digits from. ; $iDigits - The number of digits to extract after the floating point (exponential representation). ; Return values .: Success - Returns a 32-bit or 64-bit signed integer. ; Sets @extended to the decimal exponent. ==> $fFloat = return value * 10 ^ exponent ; Failure sets @error to 1 if the input is not a float or undefined. ; Author ........: czardas ; ============================================================================================================================== Func __FloatToDigits($fFloat, $iDigits = 14) If VarGetType($fFloat) <> 'Double' Or StringInStr($fFloat, '#') Then Return SetError(1) Local $iSign = ($fFloat < 0) ? -1 : 1 ; machine epsilon = 5 × 10^-15, so the final two digits (16 and 17) could be highly innacurate $fFloat = StringFormat('%.' & $iDigits & 'e', $fFloat) ; rounds to the specified number of decimal places Local $aFloat = StringSplit($fFloat, "e", 2) ; zero-based array If $iSign < 0 Then $aFloat[0] = StringTrimLeft($aFloat[0], 1) ; remove the minus sign ; remove the decimal point and trailing zeros $aFloat[0] = StringLeft($aFloat[0], 1) & StringRegExpReplace(StringRight($aFloat[0], $iDigits), '(0+\z)', '') $aFloat[1] += 1 - StringLen($aFloat[0]) ; adjust the exponent to accommodate changes Return SetExtended($aFloat[1], Int($aFloat[0]) * $iSign) ; add back the minus sign EndFunc ;==> __FloatToDigits There may yet be some superfluous (and therefore dubious) lines of code in the above example. I'll try removing them later, and see if it breaks anything. Which is worse, broken code or fuzzy human logic? Edited September 23, 2016 by czardas code tidying operator64 ArrayWorkshop
czardas Posted September 23, 2016 Author Posted September 23, 2016 Oh my! The worst is broken code with fuzzy human logic. I'm sure there must be a trick I can use like adding '.0' and just throwing the value into some engine designed by someone who can read the mind of the user. operator64 ArrayWorkshop
czardas Posted September 24, 2016 Author Posted September 24, 2016 (edited) The above code has now been implemented and seems to work like a charm. I was also thinking of adding a column ratio feature, but I'm not sure how useful it might be. Here someone asks how to do this: http://stackoverflow.com/questions/472989/how-do-i-display-a-ratio-in-excel-in-the-format-ab , and I want to know why. Can you think of any practical applications? Edited September 24, 2016 by czardas operator64 ArrayWorkshop
water Posted September 24, 2016 Posted September 24, 2016 No, not really czardas 1 My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
czardas Posted September 24, 2016 Author Posted September 24, 2016 I suppose application may be limited, but I think it looks nice. It can be useful in music theory or calculating betting odds, or if you just want to annoy people on stackoverflow. operator64 ArrayWorkshop
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now