Newsgroup: it.comp.appl.access
Titolo: ciclo do until ripetuto più volte fino a una determinata condizione

Ciao a tutti,
 
ho tre record
 
banane kg 2,5
banane kg 1
banane kg 1
 
QT--> QUANTITÀ DA TOGLIERE KG 2 
QR --> QUANTITÀ DEL RECORD
 
ad ogni record devo togliere il 25% della quantità fino a che QT non diventi zero
 
ho scritto questo codice:
 
dim quantita_scarico25 as single
QT = me.differenza ' 2 kg
 
Do Until rs1.EOF ' i tre record delle banane
 
    QR = rs1!quantita  ' 2,5 al primo giro
 
    quantita_scarico25 = (QT * 25 / 100) '  0,5
 
    If QT > quantita_scarico25 Then ' 2 > 0,5
 
    QR =  QR - quantita_scarico25 'tolgo il 25% al primo record - 2,5 - 0,5 = 2
 
    QT = QT - quantita_scarico25  'tolgo il 25% a QT  2 - 0,5 = 1,5
 
    rs1.Edit
    rs1!quantita = QR ' 2
    rs1.Update
 
    End If
 
    If QT <= quantita_scarico25 Then 
    QR = QR - quantita_scarico25
 
         rs1.Edit
         rs1!quantita = QR 
         rs1.Update
         Exit Do
         Exit Sub
 
    End If
 
    rs1.MoveNext
    Loop
 
Il  guaio è che dopo i tre cicli ho ancora una rimanenza in QT
come posso continuare il ciclo?
grazie

[...]
 
È una questione matamatica: se a un valore togli una percentuale
inferiore al 100% il suo azzeramento è impossibile!!!
 
Bruno


Mi spiego con parole più concrete
i tre record rappresentano le banane ordinate e sono 4,5 kg. 
Da questi 4,5 kg devo togliere 2 kg però spalmati sui tre record in percentuale.
Charo che se al primo record tolgo 250 grammi al secondo record la quantità
da togliere parte da 1,750 kg.
Al secodo record tolgo 250 gr, la quantita rimanente è 1,5 kg.
e così via fino al punto che non vi è nulla da togliere perché la quantità rimanente diventa zero.
 
il mio problema è che finito il ciclo sui 3 record rimane ancora quantità da togliere, come faccio a ripetere il ciclo? (ovviamente senza rilanciare la routine)

Se hai un numero finito di records l'ultimo tiene il rimanente e di fatto va a zero.
 
TOT=Parz1+Parz2+Parz3+Parz4 (4 records)
 
Questo significa che Se scali dal totale i primi 3 parziali conosciuti il Parz4 è il rimanente...
 
Almeno dal tuo esempio io ho capito questo.
@Alex


provo a girarla così:
 
banane kg 2,5
banane kg 1
banane kg 1 
 
ad ogni ciclo tolgo il 25% del record (al primo giro sono 500 gr)
quindi:
 
banane kg 2
banane kg 0,5
banane kg 0,5
 
ma mi rimangono ancora 500 grammi da togliere e non posso più
ripetere il ciclo tra i tre record 
 
nel mio esempio ho fatto un errorino di trascrittura delle variabili nel post
quantita_scarico25 = (QR * 25 / 100) '  0,5 
 

     quantita_scarico25 = (QR* 25 / 100) '  0,5


Il giorno domenica 17 novembre 2019 08:39:22 UTC+1, @Alex ha scritto:

Alex, spiegami una cosa,
 
se nella variabile ho una rimanenza di quantità
come faccio a rilanciare la routine che contiene  do until da codice?
senza cliccare sul pulsante di comando
grazie

 QT--> QUANTITÀ DA TOGLIERE KG 2
 
 
se ho capito bene...
hai uno stock di 2 kg
lo vuoi spalmare su tutti gli ordini fino ad azzeramento dello stock
è così?
 
ovviamente non è la strada giusta per fate questo,
dovresti leggere tutti i record e memorizzare le quantità
in un array e poi calcolare quanto stock assegnare a ciacuno
in base alla quantità ordinata fino ad esaurimento dello stock.
 


ho vagamente capito cosa vuoi dire, ma vagamente....
ho pensato di di dividere lo stock per il numero dei record. Mi spiego
 
DEVO TOGLIERE 2 KG
I RECORD SONO 7 QUINDI 2 /7 FA 0,286
quindi ad ogni record sottraggo 0,286 kg
chiaro che dopo il primo record sottraggo 0,286 allo stock iniziale
e poi passo al secondo record..............ecc ecc ecc
non è logico il processo?


il processo è tuo, quindi la logica la decidi tu...
io farei diversamente,
tu assegni una quota fissa ad ogni record,
io darei una quota proporzionale alla quantità del record.
ma!
in entrambi i casi è necessario sapere quanti sono i record,
quindi andrei a leggere tutti i record e memorizzerei le
quantità in un array e alla fine sapendo che il numero di
elementi nell'array corrisponde al numero dei record letti...
farei i calcoli.
 
 
 
 


Il numero di Elementi dell'Array è sicuramente quello dei Record... ma come ripetti la Corrispondenza Biunivoca ElementoArray<--->Record per la riassegnazione...? (ti basta cambiare l'ordinamento per fare confusione)
 
Converrebbe usare una collection(io la preferisco in questi casi), oppure un Array di Type
 
Private Type mType
  Valore
  IndicePK
End Type
 
Private mArray()  As mType
In questo modo assegno Valore e PK  per il recupero del valore.
 
Se i records sono pochi non vi è differenza tra i 2 metodi se si supera il centinaio su cicli frequenti... credo sarebbe da preferire una Collection in quanto la KEY è la PK del Record e, in una sola richiesta recupero la corrispondenza da passare al Record.
Con gli Array devi Ciclare sempre ed il tempo è dipendente dall'indice.
 
Saluti
@Alex

 Converrebbe usare una collection ...
 
probabilmente si,
ma al momento il suo problema è spalmare QT su tutti
i record fino ad azzeramento di QT, forse gli basta
un output del tipo
 
QR1 - parte-di-QT = nuovo_QR1
QR2 - parte-di-QT = nuovo_QR2
QR3 - parte-di-QT = nuovo_QR3
...
QRn - parte-di-QT = nuovo_QRn
 
 


posto il codice reale:
 
sngDifferenza = -Me.Differenza ' la qantità che devo sottrarre ai record 
 
set rs1 = CurrentDb().OpenRecordset("SELECT filtro le banane")
 
rs1.MoveLast
intDividendo = rs1.RecordCount
Q_divisa = Round(sngDifferenza / intDividendo, 2) 'ottengo la media da togliere 
 
rs1.MoveFirst
 
     Do Until rs1.EOF
    quantita_scarico = rs1!quantita 'le banane nel record 
 
  If Q_divisa < quantita_scarico Then
 
    quantita_scarico = quantita_scarico - Q_divisa
    rs1.Edit
    rs1!quantita = Round(quantita_scarico, 2)
    rs1.Update
    End If
 
If Q_divisa >= quantita_scarico Then   
 
    rs1.Delete 'elimino record perché negativo o pari a zero se gli tolgo Q_divisa 
 
    End If   
    rs1.MoveNext
    Loop
 
sia che tolgo la percentuale 25% sia che tolgo la media
in certi casi mi rimane una giacenza
 
non funziona il modello!
 
 
 

>>>>  
http://www.bb2002.it
 :)  <<<<<
........... [ al lavoro ] ...........


non sempre funziona (credo)
poni il caso di avere
 
banane 2,5
banane 1
banane 0,3
 
2/3,8 % = 52,63
 
2.5 - 52,63% = 2.5 - 1.315 = 1.185
1.0 - 52,63% = 1.0 - 0.526 = 0.474
0.3 - 52,63% = 0,3 - 0.158 = 0.142
 
1.185 + 0.474 + 0.142 = 1.801
rimane qualcosa perche banane 0,3 è troppo basso o sbaglio?
 
so che mi risponderai, 
ne approfitto per chiederti una altra cosa
 Ma come si fa a ripetere un ciclo do until rs.EOF
 
rimanendo nella stessa routine?
 
 
 

 
 
non devi sommare i residui :(
 
devi sommare le quantità tolte:
1.315 + 0.526 + 0.158 = 2 precisi precisi


 
ahhh si scusa. Giusto giusto grazie



grandioso funziona....ma in cosa sei laureato, ehehehe. 
per il piacere ecco il codice dal vero
 
sngDifferenza = -Me.Differenza       ' trasformo in positivo (0,4) per semplicità calcoli
stock_scarico = Me.Scarico_quantità
 
Set rs1 = CurrentDb().OpenRecordset("SELECT filtro sulle banane")
Do Until rs1.EOF
 
quantitaX100 = Round((sngDifferenza * 100 / stock_scarico), 2)
 
    quantita_scarico = rs1!quantita
    quantita_scarico = Round((quantita_scarico - (quantita_scarico * quantitaX100 / 100)), 2) 
    rs1.Edit
    rs1!quantita = Round(quantita_scarico, 2)
    rs1.Update
 
    rs1.MoveNext
    Loop
 
Me.Requery
 
ti chiedo ancora un aiutino
 
come posso fare con le unità intere?
 
es. nello scarico ho 12 barattoli im più record
 
facciamo che ne devo togliere 4
 
se applico la percentuale ottengo delle virgole, non posso scaricare 1,2 bar di capperi perché l'unità è indivisibile.
 
che mi consigli?
 
 
 

Int(numero)...?
 
@Alex

 grandioso funziona....ma in cosa sei laureato, ehehehe.
 
Non per essere petulante ma per essere petulante
E' aritmetica diciamo di media inferiore.
Devi dividere una torta e poi a ciascun pezzo devi mettere un pezzettino
di ciliegina in funzione di quanto e' grande il pezzo ;-)
 
 
 
-- 
ac y-1=x

 
 
togli sempre il pezzo intero superiore (1.825 -> 2)
mal (ben) che vada sull'ultimo (sugli ultimi) lotto potresti anche non 
scaricare nulla (portati appresso il totale progressivo di quelli che hai 
scaricato ed esci dal loop se lo raggiungi prima di aver finito)
se li riordini dal più grande al più piccolo in fase di elaborazione questo 
può succedere
se li ordini al contrario potresti trovarti coi lotti piccoli a zero e 
quelli grandi non toccati
se sono random... cambia il codice e ordinali ;)


 
 
se sono candite inserisci l'opzione di lasciarle tutte alla fetta 
successiva alla mia (a meno che siano in un cannolo)



Do Until rs.EOF
    ' esegui qui ciò che deve essere ripetuto, per esempio:
    If rs![Cognome] = "" Then
        i = i + 1
        Msgbox rs![ID_Cliente] & vbCrLf & _
               rs![Nome] & " [cognome assente]"
    End If
    MoveNext
Loop
 
Il Do...Loop parte dal record attivo di rs.
Se non sei certo di ciò premetti:
   rs.MoveFirst
 
Eseguito il Loop in rs non vi è alcun record attivo,
il recordset si trova nella condizione end of file (EOF).
Se devi eseguire nella stessa routine un altro Loop
su rs, esegui rs.MoveNext ovvero ripeti Set rs = ...
 
Bruno

 Bruno


si è vero ripentendo set recordset il loop riparte
grazie


che ne dici se opero così:
conto tutte le quantità nel rs
se il numero è intero ( If  CInt(Numero) Then )
procedo a togliere una unità per record
altrimenti procedo con il codice frazionato di prima
 
ciao 
grazie