NascondereMostrare Colonne Tramite Funzione
Hai un problema con Excel? 
Nascondere/Mostrare Colonne Tramite Funzione
di KouSkabb (utente non iscritto) data: 11/11/2012 16:26:39
Salve a tutti, dopo un'intensa ricerca nella rete mi ritrovo a dover chiedere aiuto a voi, intanto mi scuso se è già stato trattato quest'argomento in un'altro post ma non sono riuscito a trovare nulla. Passerei quindi ad esporre il problema
Devo realizzare una grande tabella, nella quale o bisogno di inserire un comando (anche una modifica di cella, o una sua semplice selezione, o un DoubleClick) che permetta di nascondere un'intervallo di colonne personalizzabile. Ora qui viene il problema, infatti ovunque è possibile leggere che questo problema può essere risolto con una macro o con un codice VBA. Purtroppo se dopo aver creato questi due codici si va ad inserire una nuova colonna (inserendola prima della cella di comando) i codici non vengono modificati ed in questo modo si crea una grande confusione perché verranno nascoste colonne sbagliate (cioè sfasate di una posizione). Quindi in definitiva mi servirebbe una Funzione che permetta di nascondere le colonne, ma che allo stesso tempo cambi i riferimenti di cella se vengono aggiunte o rimosse delle celle
Ora ecco la mia mezza soluzione: avevo pensato di creare una funzione personalizzabile che permettesse di fare questa cosa in seguito ad una regola IF tuttavia non funziona e probabilmente dipende dal fatto che non ci capisco niente. Riporto ciò che di meglio sono riuscito a fare con VBA
Public Function Nascondi_Colonne(Colonna_Inizio, Colonna_Fine)
ActiveCell.Offset(0, 0).Columns("Colonna_Inizio:Colonna_Fine").EntireColumn.Select
Selection.EntireColumn.Hidden = False
End Function
Vi prego non mi defilate semplicemente dicendo che non si può fare, perché il codice di sopra funziona perfettamente se fatto eseguire con un CommandButton (quindi è esatto) e la parte per creare una funzione personalizzabile funziona benissimo per creare una funzione semplice, quindi dipende dal fatto che non so unire le due cose. Per favore aiutatemi
di Vecchio Frac data: 11/11/2012 19:44:39
Non preoccuparti, nessuno si defila, e la soluzione per me è semplice: dai un nome alle colonne da nascondere, quindi potrai riferirti ad esse in futuro nonostante gli inserimenti.
Nel codice di esempio che segue do un nome alle colonne H e J, quindi inserisco una colonna prima di I e due colonne prima di A e B. Quindi nascondo le due colonne che in origine erano H e J e che adesso naturalmente sono J e M.
Sub test()
[H:H].Name = "colonna_H"
[J:J].Name = "colonna_J"
[I:I].EntireColumn.Insert
[A:B].EntireColumn.Insert
[colonna_H].EntireColumn.Hidden = True
[colonna_J].EntireColumn.Hidden = True
End Sub |
di KouSkabb (utente non iscritto) data: 11/11/2012 19:46:37
controllo subitissimo!
di KouSkabb (utente non iscritto) data: 11/11/2012 20:35:46
Sembrava potesse funzionare ed invece no! Forse sono io che non riesco a far funzionare il codice. Credo dipenda dal fatto che mi sono espresso male, io non ho necessità di inserire delle colonne da codice, ma semplicemente ho bisogno di modificare la tabella in qualsiasi momento. Per chiarire ogni dubbio allego il file e aggiungo che sopra alla cella Attitudine Fisica ci sono due celle una cosa "<" l'altra con ">" se ci si clicca sopra si ottiene il risultato che vorrei, cioè quello di nascondere una parte della tabella (Colonne e Righe) che gli sta a destra e sotto fino ad un certo punto (in questo caso colonna BD, ma DEVE essere personalizzabile). Tuttavia si nota da qui che non è possibile inserire una colonna o una riga prima della posizione delle celle M2 e N2 (quelle che contengono "<" ">") ne nell'intervallo O:BD perchè altrimenti i due codici riprendono i nuovi riferimenti e si perde tutto
Ovviamente non voglio che mi risolviate il problema, ma che mi spiegate come fare!
di Vecchio Frac data: 11/11/2012 21:04:47
Ma era chiaro che non volevi inserire colonne.
Il mio esempio mirava a farti vedere che definendo una colonna con un nome, e poi cambiandone i riferimenti (spostandola, inserendo colonne in mezzo, ecc.), Excel è comunque in grado di conservarne il ricordo per poter poi recuperarla successivamente.
Appena posso do un'occhiata al file che hai saggiamente allegato :)
di Vecchio Frac data: 11/11/2012 21:47:07
Il codice che hai allegato è riscrivibile come segue, e forse è anche più chiaro.
Quel che ti chiedo però è descrivere meglio cosa hai in mente e cosa vorresti realizzare, io credo che forse con una semplice Raggruppa e struttura eviti di scrivere del codice.
Tu vuoi impostare dei comandi che ti permettano di nascondere/scoprire determinate colonne e righe, presumo in corrispondenza di ogni caratteristica del personaggio. Quindi dovrai/vorrai creare tanti "<" e ">", sopra ogni descrizione, che ti permettano di comprimere ed espandere le colonne / righe relative. Non è così?
Mi piacerebbe che tu facessi vedere un esempio del risultato desiderato (perchè in effetti nascondendo le colonne intere si perdono le informazioni legate alle caratteristiche).
p.s. preferisco nel tuo caso trattare il before_double_click in cella piuttosto che il selection_change. In tale modo non corri il rischio di capitare inavvertitamente sulle celle di comando e scatenare la macro :)
Option Explicit
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Application.EnableEvents = False
If Not Intersect(Target, [M2,N2]) Is Nothing Then
Columns("C:AQ").EntireColumn.Hidden = True
Rows("3:10").EntireRow.Hidden = True
Cancel = True
End If
Application.EnableEvents = True
End Sub |
di KouSkabb (utente non iscritto) data: 11/11/2012 22:03:41
Ci sono quasi riuscito, soltanto che non riesco a far si che una cella si comporti allo stesso modo, allego il codice così da poter essere più chiaro.
Tutto il codice funziona benissimo e ti ringrazio per la parte Sub test.
Purtroppo come puoi vedere nell'istruzione If Target.Address sono costretto ad usare il riferimento $T$3 nonostante io abbia assegnato a tale cella un nome. Infatti come puoi vedere sotto assegnando alla stessa istruzione il nome "AgilityUp_O" che corrisponde alla cella U3 non succede niente, mentre assegnando il riferimento di cella come per "$T$3" il risultato è giusto ed ottengo quello che mi serve. Ovviamente però nel primo caso se inserisco una colonna perdo la formattazione e siamo punto e a capo. Come faccio ad inserire il nuovo nome "AgilityUp_C" all'interno dell'istruzione If Target.Address oppure un metodo alternativo?
Sub test()
[V:V].Name = "Colonna_V"
[BW:BW].Name = "Colonna_BW"
[T3].Name = "AgilityUp_C"
[U3].Name = "AgilityUp_O"
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Address = "$T$3" Then
[Colonna_V:Colonna_BW].EntireColumn.Hidden = True
End If
If Target.Address = "AgilityUp_O" Then
[Colonna_V:Colonna_BW].EntireColumn.Hidden = False
End If
End Sub
|
di KouSkabb (utente non iscritto) data: 11/11/2012 22:31:20
--Tu vuoi impostare dei comandi che ti permettano di nascondere/scoprire determinate colonne e righe, presumo in corrispondenza di ogni caratteristica del personaggio. Quindi dovrai/vorrai creare tanti "<" e ">", sopra ogni descrizione, che ti permettano di comprimere ed espandere le colonne / righe relative. Non è così? --
Esattamente
--Mi piacerebbe che tu facessi vedere un esempio del risultato desiderato --
Nel file allegato ci sono impostate delle macro, e se selezioni le celle M2 ed N2 vedi esattamente come dovrebbe essere il risultato (a parte l'eventuale perdita di formattazione se vengono inserite righe e colonne)
--(perchè in effetti nascondendo le colonne intere si perdono le informazioni legate alle caratteristiche). --
é proprio quello che voglio (se clicco "<"o">" devono scomparire/apparire tutto quello che c'è dopo)
Aggiungo perchè non l'ho specificato che il file è impostato come il menu di esplora risorse (quello che attraverso i "+" e "-" permette di navigare attraverso le cartelle) infatti le varie caratteristiche sono impostate con un concetto identico a quello delle cartelle sottocartelle di esplora risorse.
Quindi semplicemente vorrei riproporre quello schema di tendina
di Vecchio Frac data: 12/11/2012 08:49:38
Allora avevo capito giusto :)
Una rispostina veloce veloce: utilizza il codice qui sotto al posto del tuo e scopri le differenze ;)
naturalmente devi lanciare "test" prima di tutto (poi chiaramente inserirai il codice nell'evento Open del file).
Preferisco intercettare il doppio click in cella piuttosto che il cambio di selezione (più controllabile ed eviti che se ti sposti con tastiera si scateni la macro inavvertitamente).
Comunque riscritto così il codice fa quel che volevi tu, e non sono costretto ad utilizzare il riferimento stringa "$T$3" (infatti target è già un oggetto range di per sè).
Ovviamente nel foglio in T3 e U3 (rispettivamente AgilityUp_C e AgilityUp_O) ci vogliono i segni "<" e ">".
Option Explicit
Sub test()
[V:V].Name = "Colonna_V"
[BW:BW].Name = "Colonna_BW"
[T3].Name = "AgilityUp_C"
[U3].Name = "AgilityUp_O"
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Application.EnableEvents = False
If Not Intersect(Target, [AgilityUp_C,AgilityUp_O]) Is Nothing Then
[Colonna_V:Colonna_BW].EntireColumn.Hidden = (Target = [AgilityUp_C])
Cancel = True
End If
Application.EnableEvents = True
End Sub |
di KouSkabb (utente non iscritto) data: 12/11/2012 13:20:09
Perfetto, ho capito anche come funziona il DoubleClick meglio (infatti come lo usavo io, ogni volta che andavo a fare doppio click sulla cella mi entrava in quest'ultima per modificare il testo all'interno, invece adesso no!)
Ultimissima facilissima domanda. Siccome ho fatto un pò di casino rinominando colonne a caso, vorrei sapere come si fa a togliere il nome dato alle colonne (o alle celle o alle righe che poi è lo stesso). Per esempio ho una colonna che si chiama adesso colonna_H ma lo voglio togliere giusto per un fatto di ordine (tanto non cambierebbe niente) come faccio?
di Vecchio Frac data: 12/11/2012 13:36:18
cit. " ogni volta che andavo a fare doppio click sulla cella mi entrava in quest'ultima per modificare il testo all'interno, invece adesso no"
---> Certo, adesso no, e ti metto alla prova: dimmi esattamente quale istruzioni inibisce la modifica della cella ^_^
cit. " vorrei sapere come si fa a togliere il nome dato alle colonne "
---> In Excel 2003:
Menu "Inserisci" --> "Nome" --> "Definisci..." seleziona il nome da cancellare poi "Elimina".
di KouSkabb (utente non iscritto) data: 12/11/2012 13:50:41
Grazie mille! Tutto lavora a meraviglia adesso!
Non sono certo di quale parte ma è questa stringa
If Not Intersect(Target, [AgilityUp_C,AgilityUp_O]) Is Nothing Then
Ho fatto varie prove e dipende se viene inserito "Not" oppure no, infatti se si inserisce "Not" la cella non viene "Aperta in modalità modifica" se non viene inserito la cella può essere editata (cosa utile ca sapere)
Però non conosco questa sintassi (o meglio non so ne cosa faccia "Not Intersect", ne cosa faccia "Is Nothing") :)
di Vecchio Frac data: 12/11/2012 14:11:10
No, l'istruzione giusta è "Cancel = True" che indica alla routine, al momento di uscire, di annullare l'effetto prodotto dal doppio click in cella (l'effetto normale è entrare in modalità modifica: per annullare questo effetto è come premere ESC).
Per capire l'istruzione che riporti devi pensare che Intersect è un metodo (una funzione) che restituisce un oggetto che può essere valorizzato ad un oggetto Range oppure di valore Nullo (o Nothing nel linguaggio degli oggetti di Excel). L'istruzione si legge così: "se non è nullo il valore restituito quando la cella target (cioè quella su cui si è fatto doppio click) ricade nel range definito da [AgilityUp_C] oppure [AgilityUp_O], allora esegui le istruzioni che seguono".
In pratica è una doppia negazione che equivale ad un'affermazione: Not ... Is Nothing è un test che restituisce a sua volta un valore vero o falso, per cui l'If si comporta di conseguenza: dire "se qualcosa non è nullo" equivale a dire "se qualcosa esiste", qui l'esistenza è data dal fatto che il target ricade o no nel range specificato.
E per finire anche Application.EnableEvents è utile in questa procedura... ma ti ho già confuso abbastanza per oggi :)
di KouSkabb (utente non iscritto) data: 12/11/2012 15:41:28
No vabbè è quai chiaro, ma mi occorre un pò di pratica. comunque avrei un'altra domanda (lo so sto esagerando :()
come da codice qui sotto vorrei cambiare questo comando
[Riga_5:Riga_5].EntireRow.Hidden = (Target = [GiantSwordStyle_C])
perchè se viene eseguito mi nasconde l'intera riga, mentre a me serve che venga nascosta una porzione (tipo tabella) che diciamo ha questi riferimenti [BX5:CC10] Ovviamente credo che l'istruzione .EntireRow.Hidden non vada bene... che ci vuole?
If Not Intersect(Target, [GiantSwordStyle_C,GiantSwordStyle_O]) Is Nothing Then
[GiantSwordStyle_S1I:GiantSwordStyle_S1F].EntireColumn.Hidden = (Target = [GiantSwordStyle_C])
[Riga_5:Riga_5].EntireRow.Hidden = (Target = [GiantSwordStyle_C])
Cancel = True
End If |
di Vecchio Frac data: 12/11/2012 16:24:00
Devo deluderti.
Purtroppo non si può nascondere una porzione di righe e colonne (detta anche "Range"), il che è anche abbastanza logico. In linea generale, se qualcosa può essere fatto a mano, può essere fatto mediante codice.
Non so se potresti accontentarti, ma potresti simularne la scomparsa impostandone il colore di font allo stesso colore della cella (es. bianco su sfondo bianco è come se non ci fosse alcun contenuto). Naturalmente non ci sarebbe nessun verso shift nè a destra nè sotto.
di KouSkabb (utente non iscritto) data: 12/11/2012 19:02:48
Si infatti dopo aver mandato il messaggio, mi sono accorto che non potevo farlo neanche manualmente, quindi non fa niente eviterò. Mi accontento così grazie mille! Davvero ottimo aiuto!
di KouSkabb (utente non iscritto) data: 14/11/2012 20:00:11
Risolto
Vuoi Approfondire?