domenica 21 settembre 2014

Creazione dei menu e problemi nuovi da studiare...

E veniamo alla creazione di menu al click destro sulle celle del Calendario.

Il codice che governa questo è inserito nel modulo ThisWorkbook, in quanto parte dalla gestione dell'evento click destro sul foglio di lavoro, che viene gestito in questa sede.
Ecco la routine dell'evento:
Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
    If IsDate(Sh.Name) = False Then Exit Sub
    Cancel = True
    If campoConMenu(Target) Then
        Set Bersaglio = Target
        showMenu
    End If
End Sub
Innanzitutto bisogna accertarsi che il nome del foglio sia quello di una data, perché in caso contrario il codice funzionerebbe per qualunque foglio, incluso il foglio base e quello nascosto (qualora non fosse nascosto), o comunque qualunque foglio volessimo per qualunque motivo inserire nella cartella.
Questo accertamento viene fatto con la funzione IsDate:
If IsDate(Sh.Name) = False Then Exit Sub
che significa: "Se il nome del foglio non è una data, esci dalla routine", concludendo la gestione dell'evento in un nulla di fatto.

Cancel = True
Questo qui sopra serve per evitare che appaia anche il menu popup di default per il click destro sul foglio di lavoro, che altrimenti apparirebbe dopo il menu da me desiderato.

    If campoConMenu(Target) Then
        Set Bersaglio = Target
        showMenu
    End If
Questo subordina le istruzioni Set Bersaglio=Target e showmenu al fatto che il campo cliccato sia uno di quelli dal quale vogliamo ottenere un menu, altrimenti il menu verrebbe fuori da qualunque cella del foglio.

Bersaglio è una variabile oggetto globale, definita nel modulo delle variabili globali, che assume il valore della cella cliccata, in modo da averla come obiettivo nello scrivere poi ciò che figura sul menu nella giusta cella.
Potrei anche tentare di passarla come parametro, e forse ci proverò.
Ho preferito al momento usarla come variabile globale anziché passarla come parametro solo perché la sintassi del passaggio di parametri nella gestione dell'evento click su menu di Excel è strana e complicata, e non sono riuscito a trovare alcun modo per passare un parametro di tipo oggetto, leggendo addirittura su alcuni forum che non ne esisterebbe proprio la possibilità! Per questo motivo lo uso in questo modo, altrimenti non ne vengo più fuori!


La funzione campoConMenu(Target) identifica se il campo cliccato è uno di quelli su cui si desidera appaia un menu.
Eccola:
Function campoConMenu(campo As Range) As Boolean
    Dim valore As String    'determina il valore che c'è nella prima cella della fila
    valore = Cells(campo.Row, 1).FormulaR1C1
    If campo.Row > 3 And campo.Row < 35 Then
        If campo.Column = 4 And valore <> "" Then campoConMenu = True
        On Error Resume Next
        If campo.Column = 2 And festivo(valore) Then campoConMenu = True
    End If
End Function
Ma non potremmo rinominare le varie sezioni del Foglio Calendario, in modo da rendere più leggibile e maneggevole la cosa?

Proviamo...

Però dobbiamo ritornare al modulo formattazioneFoglio.
La sequenza delle routines chiamate dalla routine principale del modulo è questa:
scriviIntestazioni
    
aggiuntaDate

creazioneGriglia

scrittaDiCoda

copiaLista

scorri

impostazioniStampa
Quella marcata in rosso è quella in cui vengono rinominati la Lista Nomi del foglio Nascosto e la Lista Nomi del Mese del foglio Calendario.
E se inserissi prima di questa una routine che rinomina tutti i campi una volta per tutte, nel momento in cui tutto il foglio è stato formattato?

Ci provo...

Sub nominaCampi()
    ActiveWorkbook.Names.Add Name:="ListaNomi", RefersToR1C1:="=Nascosto!C1:C2"
    ActiveWorkbook.Names.Add Name:="ListaNomiMese", RefersToR1C1:="=C6:C7"
End Sub




Sub copiaLista()


    
    Dim k As Integer, z As Integer
    k = 1
    z = 15
    Do While Range("ListaNomi").Cells(k, 1) <> ""
...
Ecco, prima della routine copiaLista ho inserito la routine nominaCampi spostando in essa il codice per nominare i due campi che avevo già nominato, e nella quale potrò aggiungere il codice per nominare gli altri campi.
Vediamo se funziona, inserendo la chiamata di quest'altra routine in quella principale...
scriviIntestazioni
    
aggiuntaDate

creazioneGriglia

scrittaDiCoda

nominaCampi

copiaLista

scorri

impostazioniStampa
Sì, funziona perfettamente.

Allora rinominiamo il resto agendo sulla nominaCampi.
    ActiveWorkbook.Names.Add Name:="GiorniDelMese", RefersToR1C1:="=C1"
    ActiveWorkbook.Names.Add Name:="TurniFestivi", RefersToR1C1:="=C2"
    ActiveWorkbook.Names.Add Name:="TurniNotturni", RefersToR1C1:="=C4"
    ActiveWorkbook.Names.Add Name:="NomiReparti", RefersToR1C1:="=C3"
    
    ActiveWorkbook.Names.Add Name:="ListaNomi", RefersToR1C1:="=Nascosto!C1:C2"
    ActiveWorkbook.Names.Add Name:="ListaNomiMese", RefersToR1C1:="=C6:C7"
Ecco, ho rinominato le colonne del calendario del Foglio Calendario.
Ma invece di rinominare le colonne potrei delimitare anche i campi a un certo numero di righe, almeno per alcuni.
Provo a limitare il numero di righe del campo Lista Nomi, basandomi sulla ricerca della prima cella vuota andando dall'alto in basso.
E qui mi si apre tutta una serie di problemi...

Nessun commento:

Posta un commento