Actually, if you are interested, here is the code I'm using to calculate these significant figures. I'm sure it could be improved.
Function AnalyzeFormatAnalysisResult(row As Integer, chan As Integer, avalue As Single, analysis As TypeAnalysis, sample() As TypeSample) As String
' Format the value based on UseAutomaticFormatForResultsType (0=maximum decimals, 1=significant decimals)
ierror = False
On Error GoTo AnalyzeFormatAnalysisResultError
Dim percenterror As Single, detectionlimit As Single, wtscalratio As Single
' Format for maximum number of decimals
If UseAutomaticFormatForResultsType% = 0 Then
AnalyzeFormatAnalysisResult$ = MiscAutoFormatA$(avalue!)
End If
' Format for significant number of digits, based on counting statistics
If UseAutomaticFormatForResultsType% = 1 And (row% <> 0 And chan% <> 0) Then
percenterror! = ConvertAnalyticalSensitivity2!(row%, chan%, sample())
If ierror Then Exit Function
detectionlimit! = ConvertDetectionLimits2!(row%, chan%, RowUnkZAFCors!(), RowStdAssignsCounts!(), analysis, sample())
If ierror Then Exit Function
wtscalratio! = 1#
If analysis.CalData!(row%, chan%) <> 0# Then
wtscalratio! = analysis.WtsData!(row%, chan%) / analysis.CalData!(row%, chan%) ' for oxide/atomic scaling
If chan% <= sample(1).LastElm% And sample(1).AtomicNums%(chan%) = 8 And sample(1).HydrogenStoichiometryFlag Then wtscalratio! = 1# ' turn off scaling for hydrogen stoichiometry on excess oxygen
detectionlimit! = detectionlimit! / wtscalratio!
End If
AnalyzeFormatAnalysisResult$ = MiscAutoFormatQ$(percenterror!, detectionlimit!, avalue!)
' Save precision and detection limits (to module level arrays) for calculation of total (sum) statistics
tPrecision!(chan%) = Abs(percenterror!)
tDetection!(chan%) = detectionlimit!
' Save maximum precision and detection limits (to module level arrays) for calculation of average statistics
If Abs(percenterror!) < aPrecision!(chan%) Or aPrecision!(chan%) = 0# Then aPrecision!(chan%) = Abs(percenterror!)
If detectionlimit! < aDetection!(chan%) Or aDetection!(chan%) = 0# Then aDetection!(chan%) = detectionlimit!
End If
' Cannot format for significant digits, just do normal format
If UseAutomaticFormatForResultsType% = 1 And (row% = 0 Or chan% = 0) Then
AnalyzeFormatAnalysisResult$ = Format$(Format$(avalue!, f83$), a80$)
End If
Exit Function
' Errors
AnalyzeFormatAnalysisResultError:
MsgBox Error$, vbOKOnly + vbCritical, "AnalyzeFormatAnalysisResult"
ierror = True
Exit Function
End Function
Function MiscAutoFormatQ(precision As Single, detectionlimit As Single, treal As Single) As String
' Function to return an automatically formatted real number (based on passed percent precision and detection limit)
ierror = False
On Error GoTo MiscAutoFormatQError
Dim negative As Boolean
Dim nchar As Integer, i As Integer, j As Integer, k As Integer
Dim m As Integer, n As Integer
Dim temp As Single
Dim astring As String, bstring As String
' Check for zero precision or detection limit
If precision! = 0# Or detectionlimit! = 0# Then
MiscAutoFormatQ$ = Format$(Format$(treal!, f83$), a80$)
Exit Function
End If
' Determine number significant digits to save
nchar% = 1
If Abs(precision!) <= 10# Then nchar% = 2
If Abs(precision!) <= 1# Then nchar% = 3
If Abs(precision!) <= 0.1 Then nchar% = 4
If Abs(precision!) <= 0.01 Then nchar% = 5
If Abs(precision!) <= 0.001 Then nchar% = 6
If Abs(precision!) <= 0.0001 Then nchar% = 7
' Add one digit if greater than or equal to 100
If treal! >= 100# Then nchar% = nchar% + 1
' Round the value based on the percent precision
temp! = MiscAutoFormatZ!(precision!, treal!)
If ierror Then Exit Function
' Check greater or less than zero
If temp! < 0 Then negative = True
' Convert to decimal string
astring$ = CStr(temp!)
' Remove leading zero
If Left$(astring$, 1) = "0" Then astring$ = Mid$(astring$, 2)
' Find the decimal point
m% = InStr(astring$, ".")
If m% = 0 Then
astring$ = astring$ & ".000000"
m% = InStr(astring$, ".")
Else
astring$ = astring$ & "000000"
End If
' Find the first significant digit
n% = 1
For i% = 1 To Len(astring$)
If IsNumeric(Mid$(astring$, i%, 1)) Then
If Val(Mid$(astring$, i%, 1)) > 0 Then
n% = i%
Exit For
End If
End If
Next i%
' Set start of string
If m% < n% Then
j% = m%
Else
j% = n%
End If
' Load string starting with decimal point or first significant digit
k% = 0
bstring$ = vbNullString
For i% = j% To Len(astring$)
bstring$ = bstring$ & Mid$(astring$, i%, 1)
If IsNumeric(Mid$(astring$, i%, 1)) Then
If i% >= n% Then k% = k% + 1 ' count number of significant digits loaded
If k% >= nchar% And k% >= m% Then Exit For
End If
Next i%
' Prefix with sign if necessary
If negative Then bstring$ = "-" & bstring$
' Set to "n.d.", if less than detection limit (scaled to data type)
If treal! < detectionlimit! Then bstring$ = "n.d."
' Format number
MiscAutoFormatQ$ = Format$(bstring$, a80$)
Exit Function
' Errors
MiscAutoFormatQError:
MsgBox Error$, vbOKOnly + vbCritical, "MiscAutoFormatQ"
ierror = True
Exit Function
End Function
Function MiscAutoFormatZ(precision As Single, treal As Single) As Single
' Function to return an automatically rounded real number (based on passed percent error)
ierror = False
On Error GoTo MiscAutoFormatZError
Dim nchar As Integer, exponent As Integer
Dim ntemp As Long
Dim mantissa As Single, temp As Single
Dim astring As String
' Check for zero
If treal! = 0# Then Exit Function
' Determine number significant digits to save
nchar% = 1
If Abs(precision!) <= 100# Then nchar% = 1
If Abs(precision!) <= 10# Then nchar% = 2
If Abs(precision!) <= 1# Then nchar% = 3
If Abs(precision!) <= 0.1 Then nchar% = 4
If Abs(precision!) <= 0.01 Then nchar% = 5
If Abs(precision!) <= 0.001 Then nchar% = 6
If Abs(precision!) <= 0.0001 Then nchar% = 7
If treal! >= 100# Then nchar% = nchar% + 1
' Convert number to normalized format between 0 and 1
astring$ = Format$(treal!, e137$) ' note: e137$ = "+.0000000e+00;-.0000000e+00"
mantissa! = Mid$(astring$, 1, 9)
exponent% = Mid$(astring$, 11, 3)
' Calculate as integer based on number of significant digits
temp! = mantissa! * 10 ^ nchar%
' Round to nearest integer and truncate (positive and negative numbers)
temp! = temp! + 0.5
ntemp& = Int(temp!)
temp! = ntemp&
' Calculate back from integer significant digits
temp! = temp! / 10 ^ nchar%
' Apply saved exponent from normalization to recover
temp! = temp! * 10 ^ exponent
' Format number
MiscAutoFormatZ! = temp!
Exit Function
' Errors
MiscAutoFormatZError:
MsgBox Error$, vbOKOnly + vbCritical, "MiscAutoFormatZ"
ierror = True
Exit Function
End Function