Newsgroup: it.comp.appl.access
Titolo: Mediana con access come?

Mi servirebbe calcolare la mediana (non la media) da una serie di dati,
vorrei che la stessa venisse visualizzata mediante una casella di testo in
una maschera. La tabella si chiama "lavoratori" e i dati di cui vorrei
calcolare la mediana sono nella colonna "JD".
In internet ho trovato questo:
Per creare una routine, che determina la mediana statistica di un
insieme di numeri:
1. Creare un nuovo modulo e digitare la seguente riga nella sezione
&lt;B&gt;Dichiarazioni&lt;/B&gt; se non è già presente:Option Explicit
2. Digitare la seguente routine:
NOTA: Nel seguente codice di esempio, un segno di sottolineatura (_) al
fine di una riga si utilizza come un carattere di continuazione della
riga. Rimuovere il carattere quando si ricrea questo codice in Access
Basic.
Function Median (tName$, fldName$) As Single
Dim MedianDB As Database
Dim ssMedian As Recordset
Dim RCount%, i%, x%, y%, OffSet%
Set MedianDB = CurrentDB()
Set ssMedian = MedianDB.Openrecordset("SELECT [" & fldName$ & _
"] FROM [" & tName$ & "] WHERE [" & fldName$ & "] IS _
NOT NULL ORDER BY [" & fldName$ & "];")
'NOTE: To include nulls when calculating the median value, omit
'WHERE [" & fldName$ & "] IS NOT NULL from the example.
ssMedian.MoveLast
RCount% = ssMedian.RecordCount
x% = RCount% Mod 2
If x% <> 0 Then
OffSet% = ((RCount% + 1) / 2) - 2
For i% = 0 To OffSet%
ssMedian.MovePrevious
Next i
Median = ssMedian(fldName$)
Else
OffSet% = (RCount% / 2) - 2
For i% = 0 To OffSet%
ssMedian.MovePrevious
Next i
x% = ssMedian(fldName$)
ssMedian.MovePrevious
y% = ssMedian(fldName$)
Median = (x% + y%) / 2
End If
ssMedian.Close
MedianDB.Close
End Function
Scusate l'ignoranza ma il primo punto proprio non sò risolverlo...per il 
secondo immagino che devo cambiare i campi tName e fldName..
Qualcuno mi può aiutare a correggere questo codice in modo da darmi una
mano?
Grazie.

 calcolare la mediana sono nella colonna "JD".
cut
Ti ritrovi con questa definizione di Mediana data in Excel?:
"La mediana è il numero che occupa la posizione centrale di un insieme di 
numeri, vale a dire che una metà dei numeri ha un valore superiore rispetto 
alla mediana, mentre l'altra metà ha un valore inferiore."
Esempio: =Mediana(A1:A12)
Ciao, Carlo 

 ha scritto nel messaggionews:45d0b04f$0$20808$5fc...@news.tiscali.it...> Mi servirebbe calcolare la mediana (non la media) da una serie di dati,

Io ho pasticciato con un paio di funzioni, vedi se riesci ad adattarle
alla tua esigenze:
scusa l'eccesso di commenti ma al momento non sono a casa ed in
ufficio ho solo qualche esempio di prova su questo problema.
ciao
Function DMedian(FieldName As String, TableName As String, _
    Optional WhereClause As String = "") As Single
Dim dbMedian As DAO.Database
Dim rsMedian As DAO.Recordset
Dim lngLoop As Long
Dim lngOffSet As Long
Dim lngRecCount As Long
Dim dblTemp1 As Double
Dim dblTemp2 As Double
Dim strSQL As String
    Set dbMedian = CurrentDb()
    strSQL = "SELECT [" & FieldName & "] FROM [" & TableName & "] "
' NOTE: To ignore nulls when calculating the median value, use
' the following 4 lines:
'    strSQL = strSQL & "WHERE [" & FieldName & "] IS NOT NULL "
'    If Len(WhereClause) > 0 Then
'        strSQL = strSQL & "AND (" & WhereClause & ") "
'    End If
' NOTE: The following 3 lines will include nulls. Remove them
' (and use the 4 lines above) if you want to ignore nulls.
    If Len(WhereClause) > 0 Then
        strSQL = strSQL & "WHERE " & WhereClause & " "
    End If
    strSQL = strSQL & "ORDER BY [" & FieldName & "]"
    Set rsMedian = dbMedian.OpenRecordset(strSQL)
    If rsMedian.EOF = False Then
        rsMedian.MoveLast
        lngRecCount = rsMedian.RecordCount
        If lngRecCount Mod 2 <> 0 Then
            lngOffSet = ((lngRecCount + 1) / 2) - 2
            For lngLoop = 0 To lngOffSet
                rsMedian.MovePrevious
            Next lngLoop
            DMedian = rsMedian(FieldName)
        Else
            lngOffSet = (lngRecCount / 2) - 2
            For lngLoop = 0 To lngOffSet
                rsMedian.MovePrevious
            Next lngLoop
            dblTemp1 = rsMedian(FieldName)
            rsMedian.MovePrevious
            dblTemp2 = rsMedian(FieldName)
            DMedian = (dblTemp1 + dblTemp2) / 2
        End If
    End If
End_DMedian:
On Error Resume Next
    rsMedian.Close
    dbMedian.Close
    Set dbMedian = Nothing
    Exit Function
Err_DMedian:
    Err.Raise Err.Number, "DMedian", Err.Description
    Resume End_DMedian
End Function
secondo esempio:
Public Function fctnMedian5(strTable As String, strField As String) As
Variant
'Code sample from Accessory 
http://www22.brinkster.com/accessory
    Dim dbs As DAO.Database, rst As DAO.Recordset, booEven As Boolean
'You must add a reference to the DAO Object Library too
    Set dbs = DBEngine(0)(0)
   'commento la seguente riga funzionante
    'Set rst = dbs.OpenRecordset("SELECT * FROM " & strTable & " ORDER
BY " & strField)
'    Set rst = Forms("nome_maschera").Form.recorsetclone
    Dim strFormName As String, criterio_maschera As String,
criterio_questionario As String
    Dim parametro_campo
    parametro_campo = "numero_questionario"
    parametro_campo = "numero_intervista"
    Dim intTipoCorrente As Integer
    Dim strNomeCorrente As String
    intTipoCorrente = Application.CurrentObjectType
    strNomeCorrente = Application.CurrentObjectName
    If intTipoCorrente = acReport Then
    criterio_maschera = Reports(strNomeCorrente)!numero_questionario
    Else
    criterio_maschera = Forms(strNomeCorrente)!numero_questionario
    End If
'    If CurrentProject.AllForms(strFormName).IsLoaded = True Then
'    'quando sei in maschera interviste ci riferiamo sempre alla
sottomaschera
'
'    'parametro_campo = "numero_intervista"
'    parametro_campo = "numero_questionario"
'   ' criterio_maschera = Forms!Frm05_Interviste!
Frm01_Risposte.Form.numero_intervista
'    criterio_maschera = Forms!Frm05_Interviste!
Frm01_Risposte.Form.numero_questionario
'
'    Else
'    'criterio_maschera = Forms!Frm01_Risposte!numero_intervista
'    criterio_maschera = Forms!Frm01_Risposte!numero_questionario
'    'parametro_campo = "numero_intervista"
'    parametro_campo = "numero_questionario"
'
'    End If
     parametro_campo = "numero_questionario"
   ' query su intervista
   ' Set rst = dbs.OpenRecordset("SELECT * FROM " & strTable & " where
numero_intervista='" & criterio_maschera & "' ORDER BY " & strField)
    ' query su questionario o su intervista
    Set rst = dbs.OpenRecordset("SELECT * FROM " & strTable & " where
" & parametro_campo & "='" & criterio_maschera & "' ORDER BY " &
strField)
    Set rst = dbs.OpenRecordset("SELECT * FROM Qry_Mediana where " & _
    " numero_questionario = '" & Reports("Report1__")!
numero_questionario & "'" & _
    " and categoria = '" & Reports("Report1__")!categoria & "'" & _
    " ORDER BY " & strField)
    'la query richiamata su mediana dell'intervista è Qry_mediana
    'Set rst = dbs.OpenRecordset("SELECT * FROM " & strTable & " ORDER
BY " & strField)
    'Set rst = dbs.OpenRecordset("SELECT * FROM Risposta1 ORDER BY " &
strField)
    If rst.EOF = False Then
        rst.MoveLast
        booEven = (rst.RecordCount Mod 2 = 0) 'Is there an even number
of records in the recordset?
        rst.PercentPosition = 50 'Rounds down if there is an even
number of records...
        fctnMedian5 = rst.Fields(strField)
        If booEven Then
            rst.MoveNext
            fctnMedian5 = (fctnMedian5 + rst.Fields(strField)) / 2
'...so take the average of the this and the next value up
        End If
    End If
    rst.Close
    Set rst = Nothing
    Set dbs = Nothing
End Function


Se hai preso la funzione dall'help di Microsoft ti bastava passare alla 
versione inglese.
Questo il link corretto:
http://support.microsoft.com/kb/95918/en-us
Questa la funzione corretta:
Public Function Median(tName$, fldName$) As Single
      Dim MedianDB As Database
      Dim ssMedian As Recordset
      Dim RCount%, i%, x%, y%, OffSet%
      Set MedianDB = CurrentDb()
      Set ssMedian = MedianDB.OpenRecordset("SELECT [" & fldName$ & "] FROM 
[" & tName$ & "] WHERE [" & fldName$ & "] IS NOT NULL ORDER BY [" & fldName$ 


Per il suo uso, come dici, in un controllo casella di testo:
Me.MiaCasellaDiTesto = Median("Lavoratori", "JD")
Ciao, Carlo 

 2. Digitare la seguente routine:
A me non piace scrivere codice quando ne posso fare a meno.
Consideriamo le seguenti query:
select min([Me1]) from (SELECT TOP 50 PERCENT Campo as Me1 FROM tabella 
ORDER BY Campo DESC)
select 10000-min([Me2]) from   (SELECT TOP 50 PERCENT 10000-Campo as Me2 
FROM Tabella ORDER BY Campo ASC)
La mediana è la semisomma dei due valori restituiti dalle due query.