Newsgroup: it.comp.appl.access
Titolo: 2^ domanda su prestazioni...

Salve a tutti,
mettiamo il caso di dover elaborare una tabella con
circa 50.000 record con circa 40 campi......
siccome devo fare moltissimi controlli secondo voi
č meglio fare un solo ciclo do until (con i controlli innestati)
oppure per migliorare le prestazioni č meglio
eseguire piů cicli do until (con controlli innestati semplificati)?
grazie!
ringo



prova a fare un test su un piccolo gruppo di record e vedi i tempi
rilevati
Saluti.
Emanuele.

 ha scritto nel messaggio
news:b0lj2c$sj9$1...@serv1.albacom.net...

Con i recordset secondo me impatta lo spostamento e il salvataggio dei
record, non tanto l'elaborazione (in linea di massima) quindi ti conviene
limitare gli spostamenti facendo tutti i calcoli necessari su un record
prima di passare al successivo
Antonio

 ha scritto nel messaggio
news:KGvX9.33323$YG2.9...@twister1.libero.it...

Verissimo, fai un ciclo solo con tutti i controlli.

 ha scritto nel messaggio

che tipo di controlli devi fare?
a volte e' piu' conveniente fare delle query.
Sib


hai centrato in pieno una cosa che stavo
vedendo.... ovvero:
io dovevo fare un programma per calcolare
le provvigioni multilivello e parametriche con tangenti provvigionali
variabili (complesse! ve lo assicuro) e inizialmente
riuscivo a raggiungere l'obiettivo con due query sql innestate:
query1:
SELECT Polcli.comp, " " AS separatore, 1 AS pezzi, Polcli.sub,
Subagenti.descri, Polcli.ramo, titcli.imponrat AS impann, rami.descrizione,
[cognome1] & " " & [nome1] AS nominativo, Polcli.pol, Polcli.scad,
titcli.imponrat AS IMPONIBILE_RATA, titcli.effinc AS DAT_EFFETTIVO_INCASSO,
titcli.rata AS dat_rata, [dat_effettivo_incasso]-[dat_rata] AS dif_data,
provvigione.IMPORTO_PROVVIGIONI, provvigione.IMPORTO_PROVVIGIONI AS
provvage, Polcli.codoper, Month([dat_rata]) AS mese, Year([dat_rata]) AS
anno, "01" & "/" & [mese] & "/" & [anno] AS rata, DateAdd("d",60,[rata]) AS
data_ctrl, Polcli.rescin, Polcli.fraz, Polcli.decorr, titcli.decorr AS
DAT_INIZIO_COPERTURA, titcli.DAT_CONTABILE,
[dat_inizio_copertura]-[polcli].[decorr] AS rateo_pol,
provvigione.TIPO_PROVVIGIONI, Polcli.categ, subagenti_prov.tipo_prov,
titcli.titolo AS COD_TITOLO, titcli.stato AS COD_STATO_TITOLO
FROM (titcli RIGHT JOIN (Anacli RIGHT JOIN (((Polcli LEFT JOIN rami ON
Polcli.ramo = rami.Ramo) LEFT JOIN Subagenti ON Polcli.sub =
Subagenti.codice) LEFT JOIN subagenti_prov ON Polcli.sub =
subagenti_prov.codice) ON Anacli.npc = Polcli.npc) ON titcli.pol =
Polcli.pol) LEFT JOIN provvigione ON titcli.PROG_TITOLO =
provvigione.PROG_TITOLO
WHERE (((titcli.DAT_CONTABILE) Between
[forms]![Scheda_agente_provvigioni]![decor_inizio] And
[forms]![Scheda_agente_provvigioni]![decor_fine]) AND ((Polcli.sub) Like
IIf([forms]![scheda_agente_provvigioni]![select_agente]="*","*",[forms]![sch
eda_agente_provvigioni]![select_agente])) AND ((Polcli.ramo) Like
IIf([forms]![scheda_agente_provvigioni]![select_ramo]="*","*",[forms]![sched
a_agente_provvigioni]![select_ramo])))
GROUP BY Polcli.comp, " ", 1, Polcli.sub, Subagenti.descri, Polcli.ramo,
titcli.imponrat, rami.descrizione, [cognome1] & " " & [nome1], Polcli.pol,
Polcli.scad, titcli.imponrat, titcli.effinc, titcli.rata,
provvigione.IMPORTO_PROVVIGIONI, provvigione.IMPORTO_PROVVIGIONI,
Polcli.codoper, Month([dat_rata]), Year([dat_rata]), Polcli.rescin,
Polcli.fraz, Polcli.decorr, titcli.decorr, titcli.DAT_CONTABILE,
provvigione.TIPO_PROVVIGIONI, Polcli.categ, subagenti_prov.tipo_prov,
titcli.titolo, titcli.stato
HAVING (((titcli.titolo) Like
IIf([forms]![scheda_agente_provvigioni]![cod_titolo]="*","*",[forms]![scheda
_agente_provvigioni]![cod_titolo])) AND ((titcli.stato) Like
IIf([forms]![scheda_agente_provvigioni]![select_titolo]="*","*",[forms]![sch
eda_agente_provvigioni]![select_titolo])))
ORDER BY Polcli.sub;
query2:
SELECT provvigioni_dett_step1.dat_rata, provvigioni_dett_step1.separatore,
provvigioni_dett_step1.TIPO_PROVVIGIONI, provvigioni_dett_step1.ramo,
provvigioni_dett_step1.descri, provvigioni_dett_step1.dat_rata,
provvigioni_dett_step1.pol, provvigioni_dett_step1.scad,
provvigioni_dett_step1.descrizione, provvigioni_dett_step1.nominativo,
provvigioni_dett_step1.provvage, provvigioni_dett_step1.codoper,
provvigioni_dett_step1.COD_STATO_TITOLO, provvigioni_dett_step1.fraz,
provvigioni_dett_step1.COD_TITOLO, provvigioni_dett_step1.rescin,
provvigioni_dett_step1.rateo_pol, provvigioni_dett_step1.impann,
provvigioni_dett_step1.IMPORTO_PROVVIGIONI, IIf(([TIPO_PROVVIGIONI]="R") And
(([polcli].[ramo]="014") And ([categ] Between "700" And "799") Or
([polcli].[ramo]="016" And ([categ]="400" Or [categ]="401")) Or
([polcli].[ramo]="006") Or ([polcli].[ramo]="007") Or
([polcli].[ramo]="003")),"R","No") AS ERRE, IIf(([cod_titolo]="1") Or
([cod_titolo]="3") Or ([rescin] Is Not Null) Or (([rateo_pol]<365) And
([fraz]<>"A")) Or ([ERRE]="R"),IIf(([polcli].[ramo]="013") Or
([polcli].[ramo]="031") Or
([polcli].[ramo]="032"),[impann]*0.05,[importo_provvigioni]*0.5),0) AS
prov_A_1, IIf([prov_a_1]=0,(IIf(([polcli].[ramo]<>"081") And
([polcli].[ramo]<>"085") And ([polcli].[ramo]<>"086") And
([polcli].[ramo]<>"090"),[impann]*0.04,0)),0) AS prov_A_2,
IIf([prov_A_1]>0,[prov_A_1],[prov_A_2]) AS prov_sub_calc_A,
IIf(([cod_titolo]="1") Or ([cod_titolo]="3") Or ([rescin] Is Not Null) Or
(([rateo_pol]<365) And ([fraz]<>"A")) Or
([ERRE]="R"),IIf(([polcli].[ramo]="013") Or ([polcli].[ramo]="031") Or
([polcli].[ramo]="032"),[impann]*0.05,[importo_provvigioni]*0.5),0) AS
prov_sub_calc_B, IIf(([cod_titolo]="1") Or ([cod_titolo]="3") Or ([rescin]
Is Not Null) Or (([rateo_pol]<365) And ([fraz]<>"A")) Or
([ERRE]="R"),IIf(([polcli].[ramo]="013") Or ([polcli].[ramo]="031") Or
([polcli].[ramo]="032"),[impann]*0.03,[importo_provvigioni]*0.25),0) AS
prov_sub_calc_C, IIf(([cod_titolo]="1") Or ([cod_titolo]="3") Or
(([rateo_pol]<365) And ([fraz]<>"A")),IIf(([polcli].[ramo]="013") Or
([polcli].[ramo]="031") Or
([polcli].[ramo]="032"),[impann]*0.05,IIf(([polcli].[ramo]="085") Or
([polcli].[ramo]="086") Or ([polcli].[ramo]="081") Or ([ERRE]="R") Or
([rescin] Is Not
Null),[importo_provvigioni]*0.5,[importo_provvigioni]*0.6)),0) AS prov_D_1,
IIf([prov_D_1]=0,(IIf(([polcli].[ramo]<>"081") And ([polcli].[ramo]<>"085")
And ([polcli].[ramo]<>"086") And
([polcli].[ramo]<>"090"),[impann]*0.05,0)),0) AS prov_D_2,
IIf([prov_D_1]>0,[prov_D_1],[prov_D_2]) AS prov_sub_calc_D,
IIf([tipo_prov]="A",[prov_sub_calc_A],IIf([tipo_prov]="B",[prov_sub_calc_B],
IIf([tipo_prov]="D",[prov_sub_calc_D],IIf([tipo_prov]="Z",0,IIf([tipo_prov]=
"C",[prov_sub_calc_C],[prov_sub_calc_E]))))) AS prov_sub_calc_tp,
provvigioni_dett_step1.tipo_prov,
IIf([cod_titolo]="8",[importo_provvigioni]/2,IIf([importo_provvigioni]=0,0,[
prov_sub_calc_tp])) AS prov_sub_calc,
provvigioni_dett_step1.DAT_EFFETTIVO_INCASSO,
provvigioni_dett_step1.data_ctrl, provvigioni_dett_step1.DAT_CONTABILE,
IIf(([cod_titolo]="1") Or ([rescin] Is Not Null) Or (([rateo_pol]<365) And
([fraz]<>"A")) Or ([ERRE]="R"),IIf(([polcli].[ramo]="013") Or
([polcli].[ramo]="031") Or
([polcli].[ramo]="032"),[impann]*0.02,[importo_provvigioni]*0.1),0) AS
prov_E_1, IIf([prov_a_1]=0,(IIf(([polcli].[ramo]<>"081") And
([polcli].[ramo]<>"085") And ([polcli].[ramo]<>"086") And
([polcli].[ramo]<>"090"),[impann]*0.02,0)),0) AS prov_E_2,
IIf([prov_E_1]>0,[prov_E_1],[prov_E_2]) AS prov_sub_calc_E
FROM provvigioni_dett_step1
GROUP BY provvigioni_dett_step1.dat_rata, provvigioni_dett_step1.separatore,
provvigioni_dett_step1.TIPO_PROVVIGIONI, provvigioni_dett_step1.ramo,
provvigioni_dett_step1.descri, provvigioni_dett_step1.dat_rata,
provvigioni_dett_step1.pol, provvigioni_dett_step1.scad,
provvigioni_dett_step1.descrizione, provvigioni_dett_step1.nominativo,
provvigioni_dett_step1.provvage, provvigioni_dett_step1.codoper,
provvigioni_dett_step1.COD_STATO_TITOLO, provvigioni_dett_step1.fraz,
provvigioni_dett_step1.COD_TITOLO, provvigioni_dett_step1.rescin,
provvigioni_dett_step1.rateo_pol, provvigioni_dett_step1.impann,
provvigioni_dett_step1.IMPORTO_PROVVIGIONI, IIf(([TIPO_PROVVIGIONI]="R") And
(([polcli].[ramo]="014") And ([categ] Between "700" And "799") Or
([polcli].[ramo]="016" And ([categ]="400" Or [categ]="401")) Or
([polcli].[ramo]="006") Or ([polcli].[ramo]="007") Or
([polcli].[ramo]="003")),"R","No"), provvigioni_dett_step1.tipo_prov,
provvigioni_dett_step1.DAT_EFFETTIVO_INCASSO,
provvigioni_dett_step1.data_ctrl, provvigioni_dett_step1.DAT_CONTABILE;
la velocità era moooolto accettabile però gestire delle modifiche su
delle stringhe così complesse è DA PANICO!! ve lo assicuro!! provare per
credere!
quindi ho pensato a gestire la cosa creandomi una tabella base di comodo
ed agire su di essa con VBA/recordset per calcolare le provvigioni; ho quasi
finito la procedura di calcolo però noto con mia triste sorpresa che
le prestazioni sono peggiorate rispetto alla soluzione delle query....
cmq la gestione risulta più snella e dinamica!
Volete mettere la strutturazione del codice in questo modo:
'*** CALCOLO PROVVIGIONI ****
Dim qdfTemp As QueryDef
Dim pol, dec As Variant
Dim rst As DAO.Recordset
Dim dbs As Database
Dim Fld As Variant
Dim txt, txt2, ERRE As String
Response = acDataErrAdded
    Set dbs = CurrentDb
    txt = "SELECT * from provvigioni_mlevel"
    Set rst = dbs.OpenRecordset(txt, dbOpenDynaset)
    rst.FindFirst "pol <> ''"
        Do Until rst.NoMatch
            ' Lettura tipo provvigione (tipo_prov)
            tipo_provvigione = rst!tipo_prov
            txt2 = "select * from tab_prov where tipo_prov like '" &
tipo_provvigione & "'"
            Set rst2 = dbs.OpenRecordset(txt2, dbOpenDynaset)
            ' Gestione LOG
            rst.Edit
                rst!Log = rst!Log & rst2!tipo_prov & " "
            rst.Update
            '*** Se il collaboratore è di tipo Z si esce dal ciclo e si
processa il recordset successivo ***
            If Trim(rst2!tipo_prov) = "Z" Then
                rst.Edit
                rst!prov_sub = 0
                GoTo prossimo_record
                 rst.Update
            End If
            '*** Se il titolo = 8 si divide le provvage e si esce dal ciclo
e si processa il recordset successivo ***
            If (rst!cod_titolo = 8) Then
                rst.Edit
                rst!prov_sub = rst!IMPORTO_PROVVIGIONI / 2
                rst!Log = rst!Log & " tit.8 prov/2 "
                rst.Update
                GoTo prossimo_record
            End If
            '*** Se la provvage = 0 si azzera la provsub e si esce dal ciclo
e si processa il recordset successivo ***
            If (rst!IMPORTO_PROVVIGIONI = 0) Then
                rst.Edit
                rst!prov_sub = 0
                rst!Log = rst!Log & " provvage = 0 "
                rst.Update
                GoTo prossimo_record
            End If
            ' *** Inizio calcolo effettivo della provvigione ***
            ' Utilizzo campo di testo ERRE
            stringa_tip_prov = Trim(rst!TIPO_PROVVIGIONI)
            If (stringa_tip_prov = "R") And ((rst!ramo = "014") And
(rst!categ >= "100" And rst!categ <= "200") Or (rst!ramo = "016" And
(rst!categ = "400" Or rst!categ = "401")) Or (rst!ramo = "006") Or (rst!ramo
= "007") Or (rst!ramo = "003")) Then
                ERRE = "SI"
                rst.Edit
                rst!Log = rst!Log & " ERRE "
                rst.Update
                Else
                ERRE = "NO"
            End If
            ' Gestione titoli 1 o chi per esso...
            If (rst!cod_titolo = 1) Or (rst!cod_titolo = 3) Or (rst!rescin
<> Null) Or ((rst!rateo_pol < 365) And (rst!fraz <> "A")) Or (ERRE = "SI")
Then
                ' *** Gestione LOG ***
                Select Case rst!cod_titolo
                Case 1
                    rst.Edit
                    rst!Log = rst!Log & " tit.1 "
                    rst.Update
                Case 2
                    rst.Edit
                    rst!Log = rst!Log & " tit.2 "
                    rst.Update
                Case 3
                    rst.Edit
                    rst!Log = rst!Log & " tit.3 "
                    rst.Update
                End Select
                If rst!rescin <> Null Then
                    rst.Edit
                    rst!Log = rst!Log & " rescin "
                    rst.Update
                End If
                If ((rst!rateo_pol < 365) And (rst!fraz <> "A")) Then
                    rst.Edit
                    rst!Log = rst!Log & " rateo<365 e fraz <>A "
                    rst.Update
                End If
                ' Fine gestione LOG
                    rst.Edit
                        If (rst!ramo = 13) Or (rst!ramo = 31) Or (rst!ramo =
32) Then
                                ' AUTO
                                rst!prov_sub = (rst!IMPONIBILE_RATA *
rst2!prod_auto) / 100
                                rst!Log = rst!Log & " auto prod "
                                rst.Update
                         Else
                            If (rst!ramo = 81) Or (rst!ramo = 85) Or
(rst!ramo = 86) Then
                                ' VITA
                                rst!prov_sub = (rst!IMPORTO_PROVVIGIONI *
rst2!prod_vita) / 100
                                rst!Log = rst!Log & " vita prod "
                                rst.Update
                                Else
                                ' DANNI
                                ' Se la provvigione è di tipo ERRE
ricorrente viene utilizzato un coefficiente differente
                                    If ERRE = "SI" Then
                                       ' provvigione DANNI RICORRENTE
                                       rst!prov_sub =
(rst!IMPORTO_PROVVIGIONI * rst2!ricorrenti_danni) / 100
                                       rst!Log = rst!Log & " danni ricorr. "
                                       rst.Update
                                    Else
                                       ' provvigione DANNI
                                       rst!prov_sub =
(rst!IMPORTO_PROVVIGIONI * rst2!prod_resto) / 100
                                       rst!Log = rst!Log & " danni prod "
                                       rst.Update
                                    End If
                            End If
                        End If
                ' Else per gestire le provvigioni di INCASSO
                Else
                     rst.Edit
                        If (rst!ramo = 13) Or (rst!ramo = 31) Or (rst!ramo =
32) Then
                                ' AUTO
                                rst!prov_sub = (rst!IMPONIBILE_RATA *
rst2!inc_auto) / 100
                                rst!Log = rst!Log & " auto inc. "
                                rst.Update
                         Else
                            If (rst!ramo = 81) Or (rst!ramo = 85) Or
(rst!ramo = 86) Then
                                ' VITA
                                ' Se frazionamento M provvigione di incasso
vita = 0
                                If rst!fraz <> "M" Then
                                    rst!prov_sub = (rst!IMPONIBILE_RATA *
rst2!inc_vita) / 100
                                    rst!Log = rst!Log & " vita inc. "
                                    rst.Update
                                    Else
                                    rst!prov_sub = 0
                                    rst!Log = rst!Log & " vita inc. fraz M "
                                    rst.Update
                                End If
                                Else
                                   'DANNI
                                   rst!prov_sub = (rst!IMPONIBILE_RATA *
rst2!inc_resto) / 100
                                   rst!Log = rst!Log & " danni inc. "
                                   rst.Update
                             End If
                        End If
            End If
            ' Detrazione MORA
prossimo_record:
            rst.FindNext "pol <> ''"
        Loop
End Sub
bye
ringo

 (([polcli].[ramo]="014") And ([categ] Between "700" And "799") Or
cut
Non avrai pensato che avrei letto tutto! ;-)
comunque secondo me puoi usare le query, ma non come hai fatto tu.
dovresti creare una tabella Rami che colleghi al campo ramo e li mettere le
varie percentuali e condizioni.
aggiungi cio' che serve e vedrai che la query diventa molto liu' semplice e
soprattutto senza tutti quegli iif nidificati.
Sib

 > > > eseguire più cicli do until (con controlli innestati semplificati)?

eh il problema è che non hai letto tutto....;-)
avevo fatto il tutto con le query ma quando c'è
da modificare qualcosa si rischia di surriscaldare l'H2O
del cervello...
il codice VBA è più chiaro e gestibile...
bye
ringo

 il codice VBA č piů chiaro e gestibile...
certamente, ma le query sono piu' efficienti.
perche' non pensi a una soluzione come quella che ti prospetto, che olter
tutto rende piu' gestibili gli interventi su percentuali e competenze?
Sib


ti invio sulla tua e-mail spiegazioni della cosa....
è giusto confrontarsi per capire se si può migliorarsi
o per migliorare il lavoro degli altri... o no?...;-)
bye
ringo

 > certamente, ma le query sono piu' efficienti.
questo dove lo hai letto ?
metti in join 2 o tre tabelle di una certa sostanza,
magari senza gli indici appropriati
ed invece prova con due o tre cursori (recordset) sincronizzati
e poi ce lo sapremo aridi'
e per favore ogni tanto oltre alle if nidificate fai anche
qualche [cut]
--
a.cara 
Togli qualcosa dall'email

 ha scritto nel messaggio
news:3E2FE0AE...@blunet.it...

scusa mi spieghi cosa sono i cursori
e a che cosa possono servire?
grazie!
ringo

 e a che cosa possono servire?
a far si che invece di generare un prodotto cartesiano di 1.000.000 di
record
(per averlo basta una selfjoin su un tabella di mille righe (1000 *
1000=1.000.000))
se sei furbo basta leggere 2.000 record 
ovviamente il tentativio di spiegazione e' semplificato; in fondo quando
l'sql
fa "tablescan" (cioe' non usa gli indici di accesso) le tabelle non sono
altro
che dei vecchi e squallidi file sequenziali (quelli che normalmente
hanno 
estensione .txt)
