› Sviluppare funzionalita su Microsoft Office con VBA › Cancellare riga
-
AutoreArticoli
-
Ciao ragazzi, avrei un quesito, nel mio file ora è tutto perfettamente funzionante, mi chiedevo se posso aggiungere alla Macro CancellaProduzione che va a sottrarre alcuni valori da un altro foglio un parte di codice che vada a ricerca nel foglio "Elenco Ordini" all'interno della tabella, la riga corrispondente alla produzione ed eliminarla.
I dati da ricercare sarebbero K6 del foglio "Maschera Ricerca" nella colonna F del foglio "Elenco Ordini" e la cella G11 del foglio "Maschera Ricerca" nella colonna C del foglio "Elenco Ordini". Il codice dovrebbe cancellare la prima riga trovata che soddisfa questi 2 parametri, in caso positivo c'è già un messaggio " Produzione Cancellata" in caso di errore dovrebbe uscire un messaggio " Produzione Inesistente " o qualcosa del genere...
Si può fare ?
Allego il file e la Macro che al momento funziona
Sub CancellaProduzione() Dim rng As Range If MsgBox("Vuoi Cancellare La Produzione ?", vbQuestion + vbYesNo, "CANCELLARE LA PRODUZIONE") = vbYes Then With Sheets("PROVA CARICHI") Set rng = .Range("B35:BA35").Find(What:=.Range("B5").Value, LookIn:=xlValues, LookAt:=xlWhole) rng.Offset(1, 0) = rng.Offset(1, 0) - .Range("H2") rng.Offset(5, 0) = rng.Offset(5, 0) - .Range("N2") rng.Offset(8, 0) = rng.Offset(8, 0) - .Range("O2") rng.Offset(11, 0) = rng.Offset(11, 0) - .Range("P2") rng.Offset(14, 0) = rng.Offset(14, 0) - .Range("Q2") End With End If Worksheets("Ordine Rame").Select Range("L2").FormulaR1C1 = "=RC[1]+RC[2]" Range("L2").AutoFill Destination:=Range("L2:L29"), Type:=xlFillDefault Range("K2:K29").Value = Range("L2:L29").Value Range("M2:M29").Value = Range("L2:L29").Value Set r = Range("B35:AZ35").Find(What:=Range("E11").Value, LookIn:=xlValues, LookAt:=xlWhole) If Not r Is Nothing Then For j = 1 To Range("AM2").End(xlDown).Row - 1 Cells(r.Row + j, r.Column) = Cells(r.Row + j, r.Column) - Range("AM" & j + 1) Next j End If Worksheets("MASCHERA RICERCA").Select End SubAllegati:
You must be logged in to view attached files.Ciao @ale.1989
io però vedo che ci sono più codici uguali riportati in righe diverse. Ad esempio i codici PNP090047CE e 2400275 presenti sulla stessa riga sono riportati altre 2 volte.
Può essere che ci sia questo scenario o in questo caso è solo di esempio?
La soluzione piu' approcciabile prevede un ciclo for su una colonna e quando si matcha il primo valore si va subito a controllare se l'altra colonna presenta il secondo valore.
ci sono più codici uguali riportati in righe diverse
Potrebbe essere vero. In tal caso l'OP ha chiarito che
Il codice dovrebbe cancellare la prima riga trovata che soddisfa questi 2 parametri
Ciao ragazzi grazie per le risposte, potrebbero esserci più codici uguali, per essere più precisi potremmo confrontare anche L6 del foglio "Maschera Ricerca" nella colonna E del foglio "Elenco Ordini" e la cella M6 del foglio "Maschera Ricerca" nella colonna H del foglio "Elenco Ordini".
In questo modo le righe che soddisfano tutti i criteri di ricerca saranno meno frequenti nella tabella.
A me interessa che cancelli la prima riga che soddisfa tutti i criteri.
Una soluzione molto carina con Filter.
Function CancellaRiga() As Long Dim x As Variant Dim f As String f = "=IF((LEFT(C1:C10000,30)=""%1"")*(LEFT(F1:F10000,30)=""%2""),ROW(A1:A10000),""x"")" f = Replace(f, "%1", Worksheets("Maschera Ricerca").Range("G11")) f = Replace(f, "%2", Worksheets("Maschera Ricerca").Range("K6")) x = Filter(Application.Transpose(Application.Evaluate(f)), "x", False) If UBound(x) = -1 Then MsgBox "No rows found." CancellaRiga = 0 Else MsgBox "Deleting row " & x(0) CancellaRiga = x(0) End If End FunctionLa Function va richiamata nella sub che ti interessa e restituisce un valore Long che e' diverso da zero indica la riga da eliminare.
Per esempio potresti includere il codice per la sua gestione nella macro Cancellaproduzione:
Worksheets("Elenco Ordini").Select Dim x As Long x = CancellaRiga If x <> 0 Then Rows(x).DeleteCiao, io avevo provato con il metodo Find e FindNext
Sub cancellaCodici() Dim firstAddress As String Dim c As Range Dim zona As Range Dim valore1 As String, valore2 As String, valore3 As String With Worksheets("MASCHERA RICERCA") valore1 = .Range("G11") valore2 = .Range("L6") valore3 = .Range("K6") End With Set rng = Worksheets("Elenco Ordini").ListObjects(1).ListColumns(3).DataBodyRange Set c = zona.Find(What:=valore1, LookIn:=xlValues, LookAt:=xlWhole) If c Is Nothing Then MsgBox "Codice non trovato!", vbExclamation, "Attenzione" Else firstAddress = c.Address Do If (c.Offset(, 2).Value = valore2) And (c.Offset(, 3).Value = valore3) Then Worksheets("Elenco Ordini").ListObjects(1).ListRows(c.Row - 1).Delete Exit Do End If Set c = rng.FindNext(c) Loop While c.Address <> firstAddress End If Set zona = Nothing End Subda incorporare alla tua Sub CancellaProduzione.
Aspettiamo l'opinione di @Vecchio Frac

Aspettiamo l'opinione di @Vecchio Frac
Ci sono quasi sempre molteplici soluzioni, l'importante e' capirle
cosi' dovrebbe funzionare al pari del ciclo for di cui parlavo prima. La soluzione di Filter e' poco usuale e mi sembrava utile proporla come alternativa. In pratica costruisce un array di valori "x" se le condizioni sono soddisfatte. Il primo elemento dell'array e' il numero di riga in cui compaiono i criteri abbinati.Sub CancellaProduzione() Dim rng As Range If MsgBox("Vuoi Cancellare La Produzione ?", vbQuestion + vbYesNo, "CANCELLARE LA PRODUZIONE") = vbYes Then With Sheets("PROVA CARICHI") Set rng = .Range("B35:BA35").Find(What:=.Range("B5").Value, LookIn:=xlValues, LookAt:=xlWhole) rng.Offset(1, 0) = rng.Offset(1, 0) - .Range("H2") rng.Offset(5, 0) = rng.Offset(5, 0) - .Range("N2") rng.Offset(8, 0) = rng.Offset(8, 0) - .Range("O2") rng.Offset(11, 0) = rng.Offset(11, 0) - .Range("P2") rng.Offset(14, 0) = rng.Offset(14, 0) - .Range("Q2") End With End If Worksheets("Ordine Rame").Select Range("L2").FormulaR1C1 = "=RC[1]+RC[2]" Range("L2").AutoFill Destination:=Range("L2:L29"), Type:=xlFillDefault Range("K2:K29").Value = Range("L2:L29").Value Range("M2:M29").Value = Range("L2:L29").Value Set r = Range("B35:AZ35").Find(What:=Range("E11").Value, LookIn:=xlValues, LookAt:=xlWhole) If Not r Is Nothing Then For j = 1 To Range("AM2").End(xlDown).Row - 1 Cells(r.Row + j, r.Column) = Cells(r.Row + j, r.Column) - Range("AM" & j + 1) Next j End If Call cancellaCodici Worksheets("MASCHERA RICERCA").Select End Sub Sub cancellaCodici() Dim firstAddress As String Dim c As Range Dim zona As Range Dim valore1 As String, valore2 As String, valore3 As String With Worksheets("MASCHERA RICERCA") valore1 = .Range("G11") valore2 = .Range("L6") valore3 = .Range("K6") End With Set rng = Worksheets("Elenco Ordini").ListObjects(1).ListColumns(3).DataBodyRange Set c = zona.Find(What:=valore1, LookIn:=xlValues, LookAt:=xlWhole) If c Is Nothing Then MsgBox "Codice non trovato!", vbExclamation, "Attenzione" Else firstAddress = c.Address Do If (c.Offset(, 2).Value = valore2) And (c.Offset(, 3).Value = valore3) Then Worksheets("Elenco Ordini").ListObjects(1).ListRows(c.Row - 1).Delete Exit Do End If Set c = rng.FindNext(c) Loop While c.Address <> firstAddress End If Set zona = Nothing End SubCiao ragazzi, la soluzione di Alex, ho provato ad incollarla dopo la mia macro, richiamandola con un call ma non funziona, in particolare va in debugga sulla stringa
Set c = zona.Find(What:=valore1, LookIn:=xlValues, LookAt:=xlWhole)
Non so cosa possa essere...
Set rng = Worksheets("Elenco Ordini").ListObjects(1).ListColumns(3).DataBodyRange
Si scusa...modifica Set rng con Set zona
Perfetto, funziona.
Ho modificato
anche questa linea con zone
Set c = rng.FindNext(c)Però in caso non trovi la produzione non esce nessun messaggio, probabilmente la prima parte della macro continua a lavorare in quanto non ci sono condizioni.
Per risolvere dovrei mettere delle condizioni nella prima macro così tutte e due lavorano solo se vengono soddisfatti tutti i parametri...
Però per il resto fa tutto quello che deve fare.
-
AutoreArticoli
