E cosa vuoi che succeda in quel caso?
Se per esempio il cliente indica cinque prelievi e due di quelli sono sbagliati bisogna bloccare tutto il trasferimento nel registro finché non corregge i due sbagliati o si devono bloccare solo quei due? Oppure preferisci che la quantità prelevata venga forzata al valore della giacenza che così andrebbe a zero? O ti basta una semplice segnalazione? Oppure vuoi che la giacenza negativa venga colorata? O magari che venga colorata anche la riga del registro? O cos'altro?
Insomma quando si fa un programma bisogna avere le idee chiare altrimenti come si fa a spiegare al computer cosa si vuole?
Visto che la richiesta era "sai aiutarmi?" ho scelto io fra le varie alternative quella che mi sembra migliore, spero che ti vada bene o che tu riesca ad adattarla.
La scelta che ho fatto è di esaminare preventivamente tutte le quantità richieste e le rispettive giacenze (solo però se il titolare è indicato perché solo in quel caso viene fatto il trasferimento) e se c'è anche un solo errore di impedire tutto il trasferimento. Mi è sembrata la soluzione più pulita perché cosi si evita di lasciare elaborazioni a metà. Il cliente quindi dopo aver indicato i prelievi clicca sul pulsante e riceve un "Fatto" se tutto è andato bene oppure una segnalazione di cosa c'è che non va. Corregge gli errori e riclicca. Può anche correggere un errore alla volta tanto finché non è tutto a posto non vengono fatti i trasferimenti da un foglio all'altro.
Questo è il codice (sostituiscilo a quello vecchio):
codice:
Errori = ""
For Each Casella In Range("E4:E1000")
If Casella.Value <> "" And Casella.Offset(0, 1).Value > Casella.Offset(0, -1).Value Then
Errori = Errori & vbCrLf & Casella.Row & " - " & Casella.Offset(0, -4).Value & " Giacenza:" & CInt(Casella.Offset(0, -1).Value) & " Richiesto:" & CInt(Casella.Offset(0, 1).Value)
End If
Next
If Errori <> "" Then
MsgBox "Quantità errate nelle seguenti righe:" & vbCrLf & Errori
Else
Worksheets(2).[A1] = "Registro"
Worksheets(2).[A2] = "-----------"
For Each Casella In Worksheets(1).Range("E4:E1000")
If Casella.Value <> "" Then
Ultima = Worksheets(2).Range("A:A").End(xlDown).Row
Casella.Offset(0, -4).Copy Destination:=Worksheets(2).Cells((Ultima + 1), 1)
Casella.Copy Destination:=Worksheets(2).Cells((Ultima + 1), 2)
Casella.Offset(0, 1).Copy Destination:=Worksheets(2).Cells((Ultima + 1), 3)
Casella.Offset(0, 2).Copy Destination:=Worksheets(2).Cells((Ultima + 1), 4)
Casella.Offset(0, -1) = Casella.Offset(0, -1) - Casella.Offset(0, 1)
Casella.Value = ""
Casella.Offset(0, 1).Value = ""
Casella.Offset(0, 2).Value = ""
End If
Next
MsgBox "Fatto"
End If
Intanto subito una precisazione: ho corretto l'intervallo E3-E1000 in E4-E1000 perché mi sono accorto che nella tua immagine i dati partono dalla riga 4.
Come ti dicevo ho aggiunto un ciclo di esame preventivo della colonna E analogo all'altro, una For Each (con la sua brava Next di chiusura) che individua le righe che hanno il titolare impostato e la quantità maggiore della giacenza. Quando ne trova una accoda ad una stringa che si chiama "Errori" i dati della riga in esame cioè della riga che contiene l'errore.
In questo modo costruisco la variabile Errori con tutte le righe che contengono errori.
Come vedi i dati che indico sono il numero di riga in esame, un trattino, l'articolo, la parola Giacenza, la giacenza ecc...
Il carattere & serve a concatenare tutti i pezzi della stringa.
La costante vbCrLf serve ad andare a capo.
I valori numerici come la giacenza e la quantità li trasformo in numeri interi con la funzione Cint in modo che le celle vuote compaiano come zero.
La variabile Errori è stata inizializzata con la stringa vuota prima di cominciare il ciclo e alla fine del ciclo mi chiedo se è ancora vuota.
Se non è vuota vuol dire che è stato trovato qualche errore quindi visualizzo un messaggio (con msgbox) composto da una frase fissa e la lista di errori, altrimenti (else) non sono stati trovati errori quindi si può procedere con l'elaborazione (che è la stessa di prima).
Ciao