2015-11-28 22 views
8

Come posso trovare l'ultima riga in un intervallo di celle che contiene una formula, in cui il risultato della formula è un valore effettivo e non vuoto?Trova l'ultima riga non vuota in un intervallo di celle con una formula

Dire in modo semplificato che l'intervallo di celle ("E1:E10") contiene una formula che fa riferimento alle celle da A1 a A10 come seguito =IF("A1"="","","A1"). Ma solo le celle da A1 a A6 hanno un valore inserito, quindi il risultato della formula per le celle da E7 a E10 sarà vuoto.

Cercando di farlo con:

lastRow = ActiveSheet.Range("E" & Rows.Count).End(xlUp).Row 

risultati in lastRow che ha il valore di 10. Quello che voglio è che il valore di lastRow sia 6 in questo esempio.

Il codice effettivo è molto più complesso di così non posso semplicemente controllare l'ultima riga compilata della colonna A, poiché le formule si riferiscono a singole celle su fogli diversi e vengono aggiunte dinamicamente.

risposta

6

penso che modo più elegante di quanto è stato fornito dal @D_Bester è quello di utilizzare find() opzione senza scorrendo l'intervallo di celle:

Sub test() 
    Dim cl As Range, i& 
    Set cl = Range("E1:E" & Cells(Rows.Count, "E").End(xlUp).Row) 
    i = cl.Find("*", , xlValues, , xlByRows, xlPrevious).Row 
    Debug.Print "Last row with data: " & i 
End Sub 

prova

enter image description here

Inoltre, più corta la versione del codice che è stata fornita sopra è:

Sub test2() 
    Debug.Print [E:E].Find("*", , xlValues, , xlByRows, xlPrevious).Row 
End Sub 
+2

sì, questo è molto elegante! Grazie a @Visily – Rosetta

+0

Funziona alla grande ed è stato più quello che stavo cercando. Ho solo una domanda, qual è il significato della e commerciale '&' nella dichiarazione della variabile 'i'? (Poiché sembra funzionare allo stesso modo senza la e commerciale) – Pascale

+2

@Pascale significa 'Dim i as Long', se si rimuoverà' & 'allora' i' sarà dichiarato 'come Variant'. È solo un metodo di codifica abbreviata, ad es. '%' è 'Integer',' & 'è' Long', '$' è 'String',' @ 'è' Currency', '!' è 'Single',' # 'è' Double', se non lo è specificato quindi 'Variant' – Vasily

2

Questo dovrebbe aiutare a determinare l'ultima riga contenente una formula (nella colonna A su sheet1 Sheet1):

lastRow = Split(Split(Sheet1.Range("A:A").SpecialCells(xlCellTypeFormulas).Address, ",")(UBound(Split(Sheet1.Range("A:A").SpecialCells(xlCellTypeFormulas).Address, ","))), "$")(2) 

SpecialCells viene utilizzato per determinare il campo di tutte le celle che contengono una formula. Questo intervallo viene quindi analizzato utilizzando Split. Con Ubound viene recuperata l'ultima di queste celle. Il risultato viene diviso nuovamente per estrarre il numero di riga.

+0

Ho provato ad applicare il codice ma restituisce la prima riga contenente una formula. (L'intervallo nel mio foglio va dalla riga 3 alla riga 26 e l'ultimoRow restituisce 3: quando lo stampo con MsgBox, quando mi aspettavo che fosse 21) Non sono sicuro di cosa ho bisogno di regolare o anche se questo è un buon approccio .Dici "Questo dovrebbe aiutarti a determinare l'ultima riga contenente una formula" ma ho bisogno dell'ultima riga contenente una formula in cui il risultato di tale formula non è "" (stringa vuota). Scusa se ho frainteso la tua risposta, ma non ho alcuna esperienza con Vba, quindi mi affido totalmente a ciò che trovo su StackOverflow. – Pascale

+2

@Ralph La proprietà Address è limitata a una stringa di 255 caratteri e pertanto potrebbe non includere tutte le aree contenenti formule. – shg

5

Si desidera trovare l'ultima cella in una colonna che non è vuota E non è una stringa vuota ("").

Basta seguire il comando LastRow con un controllo del ciclo per una cella non vuota.

lastrow = ActiveSheet.Range("E" & ActiveSheet.Rows.Count).End(xlUp).Row 
Do 
    If ActiveSheet.Cells(lastrow, 5).Value <> "" Then 
     Exit Do 
    End If 
    lastrow = lastrow - 1 
Loop While lastrow > 0 

If lastrow > 0 Then 
    Debug.Print "Last row with data: " & lastrow 
Else 
    Debug.Print "No data in the column" 
End If 

Si noti che il proprio Rows.count non specifica quale foglio. Ciò significa che utilizzerà il foglio attivo. Ovviamente ActiveSheet.Range() si trova anche sul foglio attivo. Ma è una cattiva pratica mescolare Range o Rows con .Range o .Rows. Indica un uso sconsiderato che potrebbe morderti se hai modificato lo ActiveSheet ma non hai modificato il riferimento non specificato.

+0

Avevo già pensato di farli scorrere all'indietro come suggerisci tu, ma speravo in un modo più elegante per raggiungerlo. – Pascale

+0

Grazie per la risposta e grazie per aver spiegato come migliorare l'utilizzo di Rows.Count e ActiveSheet. – Pascale

+3

Penso che ci sia, prova ad usare l'approccio "divide et impera". Come '2^20' è uguale a 1048576. Questo è il valore di' Rows.Count'. Ciò detto che il tuo "Do ... Loop" non si ripeterà più di 20 volte per raggiungere il "lastrow". – Rosetta