› Sviluppare funzionalita su Microsoft Office con VBA › data obbligatoria
-
AutoreArticoli
-
Ho fatto una modifica per aumentare il range a Set rng = Sh.Range("B7:P5000") e non funziona esatto.
Ehhh...direi che ha ragione VBA (come sempre del resto)
Scusa tu hai scritto:
If Sh.CodeName = "Foglio6" And Sh.CodeName = "Foglio7" And _ Sh.CodeName = "Foglio8" And Sh.CodeName = "Foglio9" And _ Sh.CodeName = "Foglio10" And Sh.CodeName = "Foglio11" And _ Sh.CodeName = "Foglio12" And Sh.CodeName = "Foglio13" Then Exit Sub 'esclude dal controllo il Foglio1sei sicuro che sia giusto così con quegli "And"? Io proverei con "Or": Se codice Foglio = "Foglio6" o codice Foglio = "Foglio7" o .....e così via...allora esci dalla Sub
Poi perché istanzi 2 volte la variabile rng? Hai scritto:
...... ...... Set rng = Sh.Range("B7:P5000") Set rng = Sh.Range("B7:P5000") ...... ......Quindi fallo solo una volta.
Infine, sai a cosa serve questa parte di codice?:
Set ur = rng.Find(What:="*", _ After:=rng.Cells(1), _ LookAt:=xlPart, _ LookIn:=xlFormulas, _ SearchOrder:=xlByRows, _ SearchDirection:=xlPrevious, _ MatchCase:=False)Te la traduco così arrivi alla soluzione:
"Cerca nel rng l'ultima cella piena"....e quando tu scrivi Set rng = Sh.Range("B7:P5000") a questo punto qual è il range in cui va a cercare l'ultima cella piena?
Secondo me se fai le dovute modifiche raggiungi il tuo obiettivo.
Poi giusto per una fattore puramente estetico prova a sostituire rispettivamente queste 2 linee di codice:
sostituisci questa:
MsgBox "Attenzione...per ora puoi selezionare solo la cella < " & ur.Row + 1 & " >", vbCritical, "Attenzione..."con questa:
MsgBox "Attenzione...per ora puoi selezionare solo la cella < " & Replace(Sh.Cells(ur.Row + 1, "B").Address, "$", "") & " >", vbCritical, "Attenzione..."Poi questa:
MsgBox "Attenzione...per ora puoi selezionare solo la cella < " & ur.Row & " >", vbCritical, "Attenzione..."con questa:
MsgBox "Attenzione...per ora puoi selezionare solo la cella < " & Replace(Sh.Cells(ur.Row, "B").Address, "$", "") & " >", vbCritical, "Attenzione..."in pratica nelle MsgBox facciamo comparire il riferimento alla cella ("< B7 >"; "< B8 >"; "< B9 >"; ecc...)
ma internamente i due eventi sono distinti. Anche se producono all'atto pratico il medesimo effetto (in questo caso).
Ho capito, intendi che premere invio sulla cella attiva (ActiveCell) anche se non c'è spostamento scatena un cambiamento di selezione (SelectionChange).
Effettivamente se apri un file nuovo (A1 sarà la cella attiva), con impostato application.MoveAfterReturn = False e nel modulo ThisWorkbook metti questi due routine di evento:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) Debug.Print "_SheetChange di " & Sh.Name & " cella " & Target.Address End Sub Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range) Debug.Print "_SheetSelectionChange di " & Sh.Name & " cella " & Target.Address End Subpoi
- scrivi in A1 qualcosa e premere Invio ;
nella finestra immediata avrai
_SheetChange di Foglio1 cella $A$1_SheetSelectionChange di Foglio1 cella $A$1- spostati in A2
nella finestra immediata avrai
_SheetSelectionChange di Foglio1$A$2scrivi qualcosa e premi Invio
nella finestra immediata avrai
_SheetChange di Foglio1 cella $A$2_SheetSelectionChange di Foglio1$A$2ora se premi Invio un paio di volte senza cambiare il contenuto della cella ottieni
_SheetSelectionChange di Foglio1$A$2_SheetSelectionChange di Foglio1$A$2Direi che la sequenza temporale non lascia dubbi.
Ottimo, grazie per lo spunto di riflessione.
gli apprezzamenti di scossa arrivano col contagocce e solo quando sono meritati
Però devo correggere ottima in buona: quell' Exit sub in mezzo al ciclo For mi toglie il sonno
.Secondo me invece serve proprio Exit Sub perché se con Exit For esco dal ciclo poi passa all'istruzione sotto...cosa che non voglio e non serve fare.
Secondo me invece serve proprio Exit Sub perché se con Exit For esco dal ciclo poi passa all'istruzione sotto
Non mi riferivo a questo, ma all'interruzione "violenta" della sub.
Se guardi bene, ti premuri (e condivido pienamente), al termine della sub, di settare a Nothing i vari oggetti istanziati, ma con gli Exit Sub quelle istruzioni verranno ignorate.
Meglio allora, secondo me, implementare un corretta gestione degli errori e/o delle eccezioni con un bel On Error Goto label e al posto di Exit Sub un bel Err.Rise.
Se guardi bene, ti premuri (e condivido pienamente), al termine della sub, di settare a Nothing i vari oggetti istanziati, ma con gli Exit Sub quelle istruzioni verranno ignorate.
Avrei preferito anch'io un Exit For e un qualche altro metodo di controllo come la gestione dell'errore, ma in questo specifico caso non e' un male cosi' grave lasciare che sia Excel a distruggere i suoi due oggetti Range (rng e ur) proprio perche' sono oggetti suoi e non oggetti esterni creati con CreateObject. Ne abbiamo gia' parlato altre volte e so che non concordiamo su questo... ma la distruzione esplicita di due oggetti Range non e' proprio cosi' necessaria.
Però devo correggere ottima in buona:
Sei un prof troppo drastico, io assegnerei un ottimo meno se volessi essere proprio pinolo pinolo
Alexps81
If Sh.CodeName = "Foglio6" Or Sh.CodeName = "Foglio7" Or _
Sh.CodeName = "Foglio8" Or Sh.CodeName = "Foglio9" Or _
Sh.CodeName = "Foglio10" Or Sh.CodeName = "Foglio11" Or _
Sh.CodeName = "Foglio12" Or Sh.CodeName = "Foglio13" Then Exit Sub 'esclude dal controllo i Fogli
Set rng = Sh.Range("B7:B5000") '<<< colonna B
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range) Dim rng As Range, c As Range, ur As Range 'If Sh.CodeName = "Foglio1" Then Exit Sub If Sh.CodeName = "Foglio6" Or Sh.CodeName = "Foglio7" Or _ Sh.CodeName = "Foglio8" Or Sh.CodeName = "Foglio9" Or _ Sh.CodeName = "Foglio10" Or Sh.CodeName = "Foglio11" Or _ Sh.CodeName = "Foglio12" Or Sh.CodeName = "Foglio13" Then Exit Sub 'esclude dal controllo i Fogli 'Set rng = Sh.Range("B7:B20") Set rng = Sh.Range("B7:B5000") '<<< colonna B Set ur = rng.Find(What:="*", _ After:=rng.Cells(1), _ LookAt:=xlPart, _ LookIn:=xlFormulas, _ SearchOrder:=xlByRows, _ SearchDirection:=xlPrevious, _ MatchCase:=False) If ur Is Nothing Then Set ur = Sh.Range("B7") For Each c In Sh.Range("B7:" & ur.Address) If IsDate(c.Value) Then If CDate(c.Value) < DateSerial(2000, 1, 1) Then MsgBox "Attenzione...la data non può essere inferiore al ""01/01/2000""", vbCritical, "Attenzione..." Application.EnableEvents = False c.ClearContents c.Select Application.EnableEvents = True Exit Sub End If ElseIf Not IsEmpty(c.Value) Then MsgBox "Attenzione...il valore inserito non è una data.", vbCritical, "Attenzione..." Application.EnableEvents = False c.ClearContents c.Select Application.EnableEvents = True Exit Sub End If Next c If Not Intersect(Target, Sh.Range("B" & ur.Row + 1 & ":P5000")) Is Nothing Then If Not IsEmpty(Sh.Range("B7")) Then If Intersect(Target, Sh.Range("B" & ur.Row + 1)) Is Nothing Then 'MsgBox "Attenzione...per ora puoi selezionare solo la cella < " & _ ur.Row + 1 & " >", vbCritical, "Attenzione..." MsgBox "Attenzione...per ora puoi selezionare solo la cella < " & _ Replace(Sh.Cells(ur.Row + 1, "B").Address, "$", "") & " >", vbCritical, "Attenzione..." Application.EnableEvents = False Sh.Cells(ur.Row + 1, "B").Select Application.EnableEvents = True End If Else 'MsgBox "Attenzione...per ora puoi selezionare solo la cella < " & _ ur.Row & " >", vbCritical, "Attenzione..." MsgBox "Attenzione...per ora puoi selezionare solo la cella < " & _ Replace(Sh.Cells(ur.Row, "B").Address, "$", "") & " >", vbCritical, "Attenzione..." Application.EnableEvents = False Sh.Cells(ur.Row, "B").Select Application.EnableEvents = True End If End If Set rng = Nothing Set ur = Nothing End SubIf Sh.CodeName = "Foglio6" Or Sh.CodeName = "Foglio7" Or _ Sh.CodeName = "Foglio8" Or Sh.CodeName = "Foglio9" Or _
Sh.CodeName = "Foglio10" Or Sh.CodeName = "Foglio11" Or _
Sh.CodeName = "Foglio12" Or Sh.CodeName = "Foglio13" Then Exit Sub 'esclude dal controllo i FogliO più semplicemente
If InStr("#Foglio6#Foglio7#Foglio8#Foglio9#Foglio10#Foglio11#Foglio12#Foglio13#", "#" & Sh.CodeName & "#") Then Exit SubSei un prof troppo drastico, io assegnerei un ottimo meno se volessi essere proprio pinolo pinolo
Hai ragione, facciamo un buono++
-
AutoreArticoli
