Newsgroup: it.comp.appl.access
Titolo: Funzione generica di somma campi parametrica

Premessa: non ho praticamente mai programmato in VBA ;)
Sto cercando di realizzare per un amico una funzione utilizzabile in una 
query; questa funzione dovrebbe sommare n campi (dove n è un parametro) 
di qualsiasi tabella.
Ovviamente i nomi dei campi devono avere un formato fisso, del tipo C01, 
C02, C03.....
Ho quindi pensato di strutturare la funzione facendomi passare il nome 
della tabella, il prototipo dei campi (mettendo § dove dovrebbero 
esserci i numeri progressivi), il numero iniziale e quello finale.
In poche parole, se in "Tabella1" ho:
C01	C02	C03	C04
5	4	2	8
avrei che:
SommaCampi("Tabella1", "C§", 1, 3) = 11
SommaCampi("Tabella1", "C§", 3, 4) = 10
Sono quasi riuscito nell'intento con questa funzione:
Public Function SommaCampi(sTabella As String, sCampo As String, _
                             iMese1 As Integer, iMese2 As Integer) As Double
     SommaCampi = 0
     For i = iMese1 To iMese2
         sCampoX = Replace(sCampo, "§", Format(i, "00"))
         SommaCampi = SommaCampi + DLookup(sCampoX, sTabella)
     Next i
End Function
Mi sono poi accorto che la funzione DLookup, senza criteri, processa 
semplicemente il primo record della tabella, quindi la mia funzione così 
com'è fa la somma sempre degli stessi valori.
Ora, per ovviare al problema ho capito che dovrei specificare anche il 
criterio per selezionare il record corrente, ma questo vuol dire farmi 
passare anche il nome e il valore del campo chiave, pregiudicando 
l'usabilità della funzione.
Secondo voi ci sono altre vie più semplici?
-- 
Jax

Jax ha scritto:

Dlookup come tutte le sue sorelle funzioni di aggregazione sono comode
ma molto poco efficienti...!
Conviene sempre usare un Recordset ReadOnly.
Altra osservazione è che devi passare la ChiavePrimaria che ti serve
per individuare il Record
sul quale vuoi la somma....!
Nel tuo caso si potrebbe fare così:
Public Function SommaCampi(sTabella As String, sCampo As String,
PrimaryKey as variant_
                              iMese1 As Integer, iMese2 As Integer) As
Double
      SommaCampi = 0
      Dim rs as DAO.Recordset
      Dim CampoCalcolato as string
      Dim sSQL as string
      For i = iMese1 To iMese2
          sCampoX = Replace(sCampo, "§", Format(i, "00"))
          CampoCalcolato = CampoCalcolato & sCampoX & "+"
      Next i
      CampoCalcolato = Mid$(CampoCalcolato, Len(CampoCalcolato)-1)
      sSQL="SELECT *, (" & CampoCalcolato & ") AS SommaCampi FROM T1
WHERE NomePK=" & primaryKey
      set rs=CurrentDb.OpenRecordset(sSQL,dbreadOnly)
      SommaCampi = rs!SommaCampi
      rs.close
      set rs=nothing
End Function
Chiamala come dicevi...:
Msgbox SommaCampi("Tabella1", "C§", 1, 3, "NomeCampoPK")
Saluti
@Alex

 ma molto poco efficienti...!
Per poco efficiente intendi che è lenta?
Io avevo ovviato al problema facendomi passare nome e valore del campo 
chiave, e mi sembra che anche nel tuo caso ci sia da fare così... 
immagino che non ci sia modo per ovviare a questo "problema".
Questa è la mia versione:
= SommaCampi("[Tabella1]","[C§]",3,6,"[ID]=" & [ID]);
Public Function SommaCampi(sTabella As String, sCampo As String, _
                             iMese1 As Integer, iMese2 As Integer, _
                             sCriteri As String) As Double
     SommaCampi = 0
     For i = iMese1 To iMese2
         sCampoX = Replace(sCampo, "§", Format(i, "00"))
         SommaCampi = SommaCampi + DLookup(sCampoX, sTabella, sCriteri)
     Next i
End Function
-- 
Jax

 Jax
Forse ti sfugge che tu stai eseguendo tanti DlookUp quanti sono gli
intervalli da sommare, io ho fatto tutto in un solo comando....!!!!
Valuta bene le ottimizzazioni, per quanto riguarda l'uso del campo
chiave ID è ovvio che è l'unica soluzione, non c'è nulla da
inventarsi.
Fai un calcolo prestazionale se vuoi, ma nel tuo caso vedrai calare
drasticamente le prestazioni già da subito per come l'hai
scritta(anche con 1 solo Record in tabella)
@Alex

 inventarsi.
Ok, grazie ancora.
-- 
Jax