› Sviluppare funzionalita su Microsoft Office con VBA › With – End with
-
AutoreArticoli
-
prendiamo il caso:
With workBooks(A).Workshits(A)
.cells(1) = .cells(10)
.cells(2) = .cells(20)
.cells(3) = .cells(30)
...
End with
Bene, si evita di ripetere "workBooks(A).Workshits(A)".
Ma, se fosse invece:
With workBooks(A).Workshits(A)
.cells(1) = workBooks(B).Workshits(B).cells(10)
.cells(2) = workBooks(B).Workshits(B).cells(20)
.cells(3) = workBooks(B).Workshits(B).cells(30)
...
end with
domanda:
E' possibile evitare, nel secondo caso, la ripetizione di "workBooks(B).Workshits(B)"?
Grazie!
Ciao
Ha ragione patel (ciao Andrea) ma potresti "accorciare" la scrittura settando il secondo Foglio.
Per esempio:
set sh2 = workBooks(B).Workshits(B)
With workBooks(A).Workshits(A)
.cells(1) = sh2.cells(10)
.cells(2) = sh2.cells(20)
.cells(3) = sh2.cells(30)
...
end with
Ciao,
Mario
Ciao Concordo
con patel a Marius (ciao entrambi) avrei pensato anche io alla soluzione con una variabile
L'altra cosa da valutare in caso di ciclicità ricorrente è la possibilità di usare un ciclo e una variabile che si incrementa (automativcamnte con un ciclo for o con apposita istruzione) e una definizione tramite l'indice o del range oppure con un offset
CIao
Luca
workBooks(B).Workshits(B)
Va bene che certe volte i prodotti Microsoft sono una schifezza, ma chiamarli così ("shits") mi sembra eccessivo
ahaha, "shits" ... ma guarda come ci si va a rovinare ... Quando si dice "parla come mangi" ...
Ciao vecchio frac,
"con la faccia sotto i tuoi piedi, e ti puoi anche muovere" (Benigni-Troisi "Non ci resta che piangere")
Ma allora potrei fare benissimo a meno della with-end with:
set AA = workBooks(A).Worksheets(A)
set BB = workBooks(B).Worksheets(B)
AA.cells(1) = BB.cells(10)
AA.cells(2) = BB.cells(20)
AA.cells(3) = BB.cells(30)
...
Anzi, definirle pubbliche, definire così tutte le worksheets in tutte i workbooks e ogni volta che mi riferisco ad una Cells o ad un Range usare:
AA.Cells() o AA.Range o BB.Cells() o BB.Range etc. etc.
ma, per esempio, una
set AA = workBooks(A).Worksheets(A)
definita in una sub è valida solo in quella sub e quindi dovrei ripeterla in ogni sub, o no? Se è così
come faccio per definirla una volta sola (public?) e usarla (AA.Cells per esempio) poi in tutte le sub?
basta definirla fuori della sub in un modulo standard che può essere anche quello delle sub.
set AA = workBooks(A).Worksheets(A) set BB = workBooks(B).Worksheets(B) sub miasub1() AA.cells(1) = BB.cells(10) AA.cells(2) = BB.cells(20) AA.cells(3) = BB.cells(30) End sub sub miasub2() AA.cells(11) = BB.cells(10) AA.cells(21) = BB.cells(20) AA.cells(31) = BB.cells(30) End sub
basta definirla fuori della sub in un modulo standard che può essere anche quello delle sub.
Questo è giusto, ma l'esempio di patel va leggermente spiegato: devi dichiarare Public le variabili oggetto che si riferiscono ai fogli, e l'assegnazione con Set non può essere fatta al di fuori di una routine. Bisogna anche definire A e B e l'esempio vuole che i due file siano già aperti:
'modulo standard Option Explicit Public AA As Worksheet Public BB As Worksheet Sub init() Dim A As String Dim B As String A = ThisWorkbook.Name B = "test.xlsx" ' nota: i due workbooks devono essere già aperti Set AA = workBooks(A).Worksheets("Foglio1") Set BB = workBooks(B).Worksheets("Foglio2") End Sub Sub miasub1() AA.cells(1) = BB.cells(10) AA.cells(2) = BB.cells(20) AA.cells(3) = BB.cells(30) End sub Sub miasub2() AA.cells(11) = BB.cells(10) AA.cells(21) = BB.cells(20) AA.cells(31) = BB.cells(30) End sub
Qui, la sub "init" va chiamata e lanciata prima di chiamare miasub1 e miasub2, allo scopo di referenziare correttamente le variabili AA e BB. In alternativa si può inserire la dichiarazione delle due Public in ThisWorkbook e il codice di inizializzazione con Set dentro l'evento di apertura del Workbook.
Sono stato troppo frettoloso e senza testare, comunque non so se vale la pena di lavorare in questo modo, io non lo faccio.
Ciao
Ho una domanda nell'esempio fatto da VF
la sub init deve essere richiamata o prima della sub miasub1 (o 2) oppure all'interno della stessa.
Corretto?
altrimenti non valorizzo le variabili
Sì, naturalmente prima dell'esecuzione delle istruzioni di assegnazione (Set). Per questo dicevo che si potrebbero anche inserire nell'evento Open del Workbook, così si è sicuri che le assegnazioni vengono eseguite prima di tutte le successive routine.
Per quanto mi riguarda, concluderei che così:
sub miasub1() set AA = workBooks(A).Worksheets(A) set BB = workBooks(B).Worksheets(B) AA.cells(1) = BB.cells(10) AA.cells(2) = BB.cells(20) AA.cells(3) = BB.cells(30) End sub
Trovo sia molto pratico e chiaro, in ogni sub, dichiarare a che WorkBooks e Worksheets ci si riferisce. Meglio del sistema With-End With che "incastra" le istruzioni. Con due lettere si può identificare ogni foglio in qualsiasi tabella e il codice risulta sicuro, semplice, essenziale e chiaro.
Controindicazioni, secondo voi?
Nessuna controindicazione, il costrutto With - End With nasce per semplificare l'utilizzo di oggetti padre quando si devono impostare proprietà a cascata che si riferiscono allo stesso oggetto. Semplificazione per chi scrive codice, non per il compilatore. E non è affatto un problema di incastro di istruzioni. Ricordati però Option Explicit e la dichiarazione delle variabili. Questo è più importante del fatto di decidere di usare/non usare With.
Parlavo di "incastro", in quanto un istruzione tipo .cells trova il suo indirizzo preciso "all'interno" di una with-end with, mentre una MM.cells è definita "di per se".
Aggiungo che ho definito una: Public MM As Worksheet (e consimili).
Ma spiegami, perché la definizione esplicita delle variabili è così importante, vedo che insisti molto su questo ...
Poi, immagino che ogni volta che eseguo una sub, questa viene compilata prima di essere eseguita, o meglio, può darsi che venga compilato l'intero progetto prima di eseguire anche una sola sub? (altrimenti come fa a vedere le variabili public (p.e) che sono dichiarate al di fuori delle sub?)
In un programma con molte istruzioni può capitare di fare errori di battitura e sbagliare il nome di una variabile, la direttiva Option explicit ti obbliga a dichiarare tutte le variabili e ti segnala errore se incontra una variabile non dichiarata e te la evidenzia facendoti risparmiare il tempo per cercarla.
Una domanda:
se devo riferirmi, semplicemente, alla cella A1 è più sensato (nel contesto VBA) usare:
Range("A1")
o
Cells(1, "A")
Le due istruzioni sono equivalenti. Puntano allo stesso oggetto. Non cercare un significato di "sensatezza", una o l'altra soluzione dipende dal contesto in cui ti trovi e anche dal tuo stile di scrivere codice.
Se vogliamo spaccare il capello in quattro, la proprietà Cells lavora meglio con i numeri, per cui sarebbe meno faticoso per l'interprete ricevere un Cells(1, 1) piuttosto che un Cells(1, "a"), per non costringerlo a spendere qualche micron per convertire il carattere alfabetico nel corrispondente numero che identifica la colonna.
tutto dipende dal contesto, Range("A1") è più leggibile, ma se sei in un ciclo conviene usare cells(numriga,numcolonna)
E' possibile, saltare la select? Come?
O1.Range("BL1:BL1").Select Selection.AutoFill Destination:=O1.Range("BL1:BL400"), Type:=xlFillDefault
E' possibile, saltare la select?
Normalmente non serve pre-selezionare un range per farci qualcosa, perchè si risparmiano millisecondi 🙂
Quindi oltre che essere possibile è anche consigliabile farlo.
O1.Range("BL1:BL1").AutoFill Destination:=O1.Range("BL1:BL400"), Type:=xlFillDefault
Perchè è possibile questo? perchè l'oggetto Selection è un oggetto speciale di tipo range di cui ne eredità metodi e proprietà (come Autofill). Pertanto non serve selezionare un range, costruendo così un nuovo oggetto Range, solo per invocarne un suo metodo, quando puoi applicare il metodo direttamente al range originale.
E nell'esempio, se O1 è già un foglio selezionato, puoi anche ometterlo. Qualche volta è invece necessario selezionare esplicitamente foglio e range, ma quando ti salta fuori l'errore... te ne accorgi 🙂
In un programma con molte istruzioni può capitare di fare errori di battitura e sbagliare il nome di una variabile, la direttiva Option explicit ti obbliga a dichiarare tutte le variabili e ti segnala errore se incontra una variabile non dichiarata e te la evidenzia facendoti risparmiare il tempo per cercarla.
VF, mi aspettavo un commento da parte tua sei troppo impegnato ?
-
AutoreArticoli