Skipping a field if there is a word “FALSE” in it box or 0

TBC

Registered User.
Local time
Today, 15:09
Joined
Dec 6, 2010
Messages
145
I’m trying to get the Standard Deviations but in order for me to do this I need to skip over months that have a “false” or “zero” in the cell. I’m using a VBA Script to get my Standard Deviation, but if there is a better way, please let me know that also.

The script I’m using takes 6 months into account. Then calculates the Standard Deviation.

I’m hoping someone can help me fix the code below to skip fields that have “false” or a “zero”

VBA Script I’m using:
Code:
 Public Function GetXLStDev(No1 As Double, No2 As Double, No3 As Double, No4 As Double, No5 As Double, No6 As Double) As Double
   Dim objExcel As Object
   Set objExcel = CreateObject("Excel.Application")
   
     
   Let GetXLStDev = objExcel.StDev(No1, No2, No3, No4, No5, No6)
   
   objExcel.Quit
   Set objExcel = Nothing
End Function
 
Public Function Pause(PauseSeconds As Double)
 
Dim Start
Start = Timer
Do While Timer < Start + PauseSeconds
DoEvents
Loop
 
End Function

Thanks for taking the time to help me
TCB
 
Last edited:
You can calculate the standard deviation on a table column using the domain aggregate "StDev()" function ...
Code:
SELECT SomeField, StDev(Amount) AS StDevOfAmount
FROM Table
GROUP BY SomeField;
 
You can calculate the standard deviation on a table column using the domain aggregate "StDev()" function ...
Code:
SELECT SomeField, StDev(Amount) AS StDevOfAmount
FROM Table
GROUP BY SomeField;

While this does work In MS Access, it looks like the OP is asking about implementing a standard deviation Function using VB in Excel.
 
Thanks lagbolt can you help me understand why am I not able to get this to run?

SELECT OMNI#, May_Pull_Thru, June_Pull_Thru, July_Pull_Thru, Aug_Pull_Thru, Sept_Pull_Thru, Oct_Pull_Thru, StDev(Amount) AS StDevOfAmount
FROM Master_Join_tbl
GROUP BY SomeField;

Thank you
 
@ Rookie, the OP seems to me to pose the question "is there a better way" than using Excel.
@ TBC, what I posted is an example. StDev() is a function you can use on fields that actually exist in your table, but it works on fields, not columns. It looks suspicious to me that you have a field called May and June and July. That info should be data in a field.
What I would expect to see is something more like ...
Code:
SELECT StDev(Amount) 
FROM YourTable
WHERE Month(Date) >= 5 AND Month(Date) <= 10
See how in a database it is so much easier to execute a function or a calculation of a bunch of rows. Doing this on a bunch of columns is always much more difficult.
Cheers,
 
Last edited:
I think from a previous post from TBC he wanted to perform a row-wise StDev() which obviously isn't possible unless you use a function to perform the standard dev. I think this is the reason why he chose the Excel option. In my opinion, this isn't the best approach.
 
Thanks guys, what information can I provide to help, and how do I do a row-wise StDev() ?
 
TBC, you need a row-wise StdDev function because of a design flaw in your tables. In a database it would be far more efficient if one Omni number was linked to multiple records in a related table with a new row for every dated set of values. Your design has a new column for every value, and in a database this is a structure that is, as you are finding out, very very difficult to work with. Consider tables like this...
Code:
[FONT="Verdana"][B]tOmni[/B]
[COLOR="Green"]'parent record, the one side of a one-to-many relationship...[/COLOR]
OmniID (PK)
Correspondent
Exec
Active
etc...

[B]tOmniDetail[/B]
[COLOR="Green"]'Dated data here, a new record for every month for every Omni#
'Notice how in your Omni table this structure is repeated for each month.
'That repetition is your problem.[/COLOR]
OmniDetailID (PK)
OmniID (FK)
Locked
Fund
PullThrough
Month
Year[/FONT]
And then StDev() for Omni# 1071, Q3 2010, PullThrough is calulated as simply as ...
Code:
SELECT StDev(PullThrough) as StDevPT
FROM tOmniDetail
WHERE OmniID = 1071
  AND Year = 2010
  AND Month >= 7 AND Month <= 9
If you intend to work in Access I strongly recommend you research principles of normalization. The one to many relationship is extremely powerful in modelling data, and if you get how it works then jobs like what you're working on here will suddenly become much, much simpler.
 
Thanks lagbolt, I agree with you 100%, and when I get these database working, I'm going to take some time to learn about Normalization. Thank you for taking the time to recommend the steps I need to take
 
Thanks lagbolt, I agree with you 100%, and when I get these database working, I'm going to take some time to learn about Normalization. Thank you for taking the time to recommend the steps I need to take

For what it is worth, you might want to consider taking lagbolt's advice concerning normalization FIRST, since taking that advice could actually make it easier to get your database working. Best of luck in your project, and please feel free to get back with any further questions.
 
For what it is worth, you might want to consider taking lagbolt's advice concerning normalization FIRST, since taking that advice could actually make it easier to get your database working. Best of luck in your project, and please feel free to get back with any further questions.
... and at the current stage of your project it will be much easier to implement now than when it has been completed. Although, performing a row-wise standard deviation is possible with a user-defined function, you really need to sort our table structure to achieve this more easily with the built-in StDev().
 
vbaInet, /MSAccessRookie /lagbolt,

I was able to get the VBA code to work!!!! Thank you all so much for staying with my and helping me get this code to work. This is awesome. I hope you all know how much you’ve help me and everyone else that needs help in this form, you guys ROCK!!!.

Thank you, thank you, and thank you
TCB
 
Happy we could assist.

Just out of interest, how did you approach this?
 
Changed settings In VBE:
Tools
Options
General (Tab)
set to "Break on unhandled errors"

Then used this code,

Code:
Public Function getSTDev(ParamArray varVals() As Variant) As Variant
  Dim varVal As Variant
  Dim intcount As Integer
  Dim Arr() As Variant
  For Each varVal In varVals
    If IsNumeric(varVal) Then
      Arr = AddElement(Arr, varVal)
    End If
  Next varVal
  getSTDev = StdDev(Arr)
End Function
Function StdDev(Arr() As Variant) As Variant
     Dim i As Integer
     Dim avg As Single, SumSq As Single
     Dim k As Integer
     If Not HasDimension(Arr) Then Exit Function
     If Not UBound(Arr) = LBound(Arr) Then
       avg = Mean(Arr)
       For i = LBound(Arr) To UBound(Arr)
          SumSq = SumSq + (Arr(i) - avg) ^ 2
          k = k + 1
        Next i
        If k > 1 Then
          StdDev = Sqr(SumSq / (k - 1))
        End If
     End If
End Function
Public Function AddElement(ByVal vArray As Variant, ByVal vElem As Variant) As Variant
      ' This function adds an element to a Variant array
      ' and returns an array with the element added to it.
      Dim vRet As Variant ' To be returned
      If IsEmpty(vArray) Or Not IsDimensioned(vArray) Then
          ' First time through, create an array of size 1.
          vRet = Array(vElem)
      Else
          vRet = vArray
          ' From then on, ReDim Preserve will work.
          ReDim Preserve vRet(UBound(vArray) + 1)
          vRet(UBound(vRet)) = vElem
      End If
      AddElement = vRet
  End Function
Public Function IsDimensioned(ByRef TheArray) As Boolean
      If IsArray(TheArray) Then ' we need to test it! otherwise will return false if not an array!
                      ' If you put extensive use to this function then you might modify
                      ' it a lil' bit so it "takes in" specific array type & you can skip IsArray
                      ' (currently you can pass any variable).
        On Error Resume Next
            IsDimensioned = ((UBound(TheArray) - LBound(TheArray)) >= 0)
        On Error GoTo 0
    Else
        'IsDimensioned = False ' is already false by default
        Call Err.Raise(5, "IsDimensioned", "Invalid procedure call or argument. Argument is not an array!")
    End If
End Function
Public Function HasDimension(ByRef TheArray, Optional ByRef Dimension As Long = 1) As Boolean
    Dim isDim As Boolean
    Dim ErrNumb As Long
    Dim LB As Long
    Dim errDesc As String
    'HasDimension = False
    
    If (Dimension > 60) Or (Dimension < 1) Then
        Call Err.Raise(9, "HasDimension", "Subscript out of range. ""Dimension"" parameter is not in its legal borders (1 to 60)! Passed dimension value is: " & Dimension)
        Exit Function
    End If
    
    On Error Resume Next
        isDim = IsDimensioned(TheArray) 'IsArray & IsDimensioned in one call. If Err 5 will be generated if not Array
        ErrNumb = Err.Number
        If ErrNumb <> 0 Then
            errDesc = Err.Description
        End If
    On Error GoTo 0
    
    Select Case ErrNumb
        Case 0
            If isDim Then
                On Error Resume Next
                    LB = LBound(TheArray, Dimension) 'just try to retrive Lbound
                    HasDimension = (Err.Number = 0)
                On Error GoTo 0
            End If
        Case 5
            Call Err.Raise(5, "HasDimension", "Invalid procedure call or argument. Argument is not an array!")
        Case Else
            Call Err.Raise(vbObjectError + 1, "HasDimension", _
                "This is unexpected error, caused when calling ""IsDimensioned"" function!" & vbCrLf & _
                "Original error: " & ErrNumb & vbCrLf & _
                "Description:" & errDesc)
    End Select
End Function
Function Mean(Arr() As Variant)
     Dim Sum As Single
     Dim i As Integer
     Dim k As Integer
     Sum = 0
     For i = LBound(Arr) To UBound(Arr)
         k = k + 1
         Sum = Sum + Arr(i)
     Next i
     Mean = Sum / k
     'MsgBox Mean
End Function

Public Sub testSDEV()
  MsgBox getSTDev(Null, 3, 2, Null)
End Sub
 
So you're not going down the normalization route?

That's a pretty long function for StDev()

I will post one later.
 
Here it is:
Code:
Public Function RowStDev(ParamArray fldVals())
    Dim i As Integer, tot As Integer, numVals() As Long, lngMean As Long, sumDev As Long
    
    ReDim numVals(UBound(fldVals))
    
    For i = LBound(fldVals) To UBound(fldVals)
        If IsNumeric(fldVals(i)) Then
            numVals(i) = fldVals(i)
            lngMean = lngMean + fldVals(i)
            tot = tot + 1
        End If
    Next
    
    If tot = 0 Then
        Exit Function
    End If
    
    lngMean = lngMean / tot
    
    For i = LBound(numVals) To tot - 1
        sumDev = sumDev + Abs((numVals(i) - lngMean) ^ 2)
    Next
    
    RowStDev = Round(Sqr(sumDev / (tot - 1)), 5)
End Function
 

Users who are viewing this thread

Back
Top Bottom