Visibilità dei dati e gerarchie

Ciao. Come già detto più volte sto cercando di imparare a programmare Excel. Forse, anzi sicuramente, ho scelto un problema un poco complesso, ma tant'è.

Cerco di spiegare; Per necessità di inizializzazione della gestione e per una gestione dello stesso avrei necessità di poter vedere, e gestire, una serie di dati (variabili e tabelle) in tutti Fogli.

Credo di aver capito che la struttura naturale di Excel è Padre (ThisWorkbook) e Figlio(i) (WorkSheet(s)). Ora, a me, viene naturale pensare che tutto quello che io definisco nella parte (generale) di ThisWorkbook debba essere visibile e disponibile per i suoi figli (WorkSheet(s)), ora le domande:

  1. E' corretto quanto sopra?, perché per tutte le prove fatte non riesco ad ottenere il risultato divisibilità e operatività.
  2. E' possibile ottenere quanto sperato?, se si come?.

grazie, 

Claudio

 

Informazioni domanda


Ultimo aggiornamento febbraio 27, 2018 Visualizzazioni 97 Si applica a:

* Prova con un numero di pagina inferiore.

* Immetti solo numeri.

* Prova con un numero di pagina inferiore.

* Immetti solo numeri.

Ciao claudiomauri ,

Penso che sarebbe utile se tu dovessi fornire un esempio specifico di ciò che vuoi ottenere.

Tuttavia, a titolo di esempio, incolla il seguente codice nel modulo di codice dell'oggetto ThisWorkbook:

'=========>>
Option Explicit

'--------->>
Private Sub Workbook_Open()
    Call MsgBox(Prompt:="Benvenuto " _
                      & Application.UserName _
                      & " al workbook " & Me.Name, _
                Buttons:=vbInformation, _
                Title:="Nome del Workbook")
End Sub

'--------->>
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    Call MsgBox(Prompt:="Benvenuto al foglio " & Sh.Name, _
                Buttons:=vbInformation, _
                Title:="Nome di Foglio!")
End Sub

'--------->>
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    Call MsgBox(Prompt:="Hai selezionato la cella " _
                      & Target.Address(0, 0) _
                      & " sul foglio " _
                      & Sh.Name & " del workbook " _
                      & Me.Name, _
                Buttons:=vbInformation, _
                Title:="Indirizzo")
End Sub
'<<=========

Salva, chiudi e riapri  il file. Poi seleziona qualsiasi foglio e quindi seleziona una cella del foglio.

Questi esempi banali sono intesi a dimostrare che il codice evento nel modulo di codice del ThisWorkbook può operare su tutti i fogli. Se si volesse operare su un singolo foglio in modo analogo, si potrebbe usare il l'evento corrispondente nel modulo di codice del foglio di interesse. 

===

Regards,

Norman

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

Ciao claudiomauri,

Ciao. Come già detto più volte sto cercando di imparare a programmare Excel. Forse, anzi sicuramente, ho scelto un problema un poco complesso, ma tant'è.

Cerco di spiegare; Per necessità di inizializzazione della gestione e per una gestione dello stesso avrei necessità di poter vedere, e gestire, una serie di dati (variabili e tabelle) in tutti Fogli.

Senza utilizzare gli eventi di Excel, forse stai cercando qualcosa del genere:

In un modulo standard

'=========>>
Option Explicit

'--------->>
Public Sub Tester()
    Dim WB As Workbook
    Dim SH As Worksheet, aSH As Worksheet
    Dim srcRng As Range, destRng As Range
    Dim iRow As Long, jRow As Long
    Dim sIntestazioni As Variant
    Const sSheetName As String = "Riepilogo"
    Const sHeadings As String = "Nome,Nazionalità,Data di Nascita,Città"
    Const myColumns As String = "A:D"

    Set WB = ThisWorkbook

    On Error Resume Next
    Set aSH = WB.Sheets(sSheetName)
    On Error GoTo 0

    With WB
        If Not aSH Is Nothing Then
            aSH.UsedRange.Offset(1).ClearContents
        Else
            Set aSH = .Sheets.Add(Before:=.Sheets(1))
            aSH.Name = sSheetName
            sIntestazioni = Split(sHeadings, ",")
            aSH.Range("A1:D1").Value = sIntestazioni
        End If

        For Each SH In .Worksheets
            With SH
                If Not .Name = sSheetName Then
                    iRow = LastRow(SH, .Columns("A:A"))
                    If CBool(iRow) Then
                        Set srcRng = .Range(myColumns).Rows(2).Resize(iRow - 1)
                        jRow = LastRow(aSH, aSH.Columns("A:A"))
                        Set destRng = aSH.Range("A" & jRow + 1)
                        srcRng.Copy Destination:=destRng
                    End If
                End If
            End With
        Next SH
    End With
XIT:

End Sub

'--------->>
Public Function LastRow(SH As Worksheet, _
                        Optional Rng As Range)
    If Rng Is Nothing Then
        Set Rng = SH.Cells
    End If

    On Error Resume Next
    LastRow = Rng.Find(What:="*", _
                       after:=Rng.Cells(1), _
                       Lookat:=xlPart, _
                       LookIn:=xlFormulas, _
                       SearchOrder:=xlByRows, _
                       SearchDirection:=xlPrevious, _
                       MatchCase:=False).Row
    On Error GoTo 0
End Function
'<<=========

Questo codice crea un foglio riepilogativo (se non è già presente) e popola questo foglio con i dati trovati nelle colonne A: D di tutti gli altri fogli.

===

Regards,

Norman

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

Ora, a me, viene naturale pensare che tutto quello che io definisco nella parte (generale) di ThisWorkbook debba essere visibile e disponibile per i suoi figli (WorkSheet(s)), ora le domande:

E' corretto quanto sopra?,

No, non lo è.

ThisWorkbook è un oggetto.

Ciascun Worksheet è un oggetto.

Ogni cosa metodi(Sub), funzioni(Function), eventi(Sub), variabili, costanti, ecc. presenti nei vari oggetti, se definiti come Private sono visibili (ed utilizzabili), solo all'interno dell'oggetto stesso.

Anche i Moduli di codice standard non sono che oggetti particolari (assimilabili alle classi Static di alcuni linguaggi) nei quali mettere codice che se dichiarato Public può essere utilizzato da tutti gli altri oggetti della soluzione, se dichiarato Private rimane visibile ed utilizzabile solo all'interno delle stesso modulo.

Quindi, se ho variabili/costanti/routine(Sub e Function) che devo utilizzare in tutta la soluzione, le metterò in Moduli standard dichiarandoli Public.

In ThisWorkbook metterò solo il codice che verrà utilizzato ad esempio dagli eventi all'avvio o alla chiusura del file e/o utilizzerò gli eventi dell'insieme degli oggetti Sheets che ne fanno parte.

In ciascun Worksheet metterò il codice relativo agli eventi che riguardano il singolo Worksheet.

Dai un'occhiata a Public e Private nella guida del vb di Excel.

Molto importante è capire cosa si intende per programmazione ad oggetti in Excel. Qui una breve introduzione:

Ovviamente tutto ciò a grandi linee, se spieghi bene cosa vorresti ottenere forse possiamo essere più chiari.

Grazie per l'attenzione.

--
Mauro Gamberini
Microsoft© MVP (Excel)
http://www.maurogsc.eu

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

Ciao Claudio,

già te l'hanno detto ma repetita iuvant:

  1. No

:-)

Scherzi a parte, qualsiasi variabile dichiarata Public in qualsiasi modulo è visibile da tutto il progetto VBA (e pure esternamente, ve ne fosse bisogno).

Quello che cambia è il modo di... raggiungerla. E i casi sono solo due:

  1. Variabile dichiarata Public in un Modulo standard:
    basta chiamarla col nome, da qualsiasi modulo del progetto.
  2. Variabile dichiarata Public in un Modulo di classe (e ThisWorkbook, Worksheet, ecc sono moduli di classe)
    ci si riferisce a essa premettendo il qualificatore dell'oggetto in cui è dichiarata.

Prendi, per esempio, la Cella A1 del Foglio di lavoro Foglio1 della Cartella di lavoro Pippo.xlsx... Se vuoi riferirti a essa, da qualsiasi modulo del Progetto VBA scrivi:

Excel.Application.Workbooks("Pippo.xlsx").Worksheets("Foglio1").Range("A1")

perché Range è una proprietà dichiarata Public nel Modulo di classe dell'oggetto Worksheet che appartiene all'insieme Worksheets del''oggetto Workbook che appartiene all'insieme Worksheets... E mi fermo.

Se anche tu dichiari Public una variabile nel modulo di classe di un Foglio di lavoro dovrai usare lo stesso metodo per riferirti a essa:

' Module : Foglio1 - Worksheet
'
Option Explicit

Public Pippo As String

Come assegnarle un valore all'avvio del progetto? Per esempio così:

' Module : ThisWorkbook - Workbook
'
Option Explicit

Private Sub Workbook_Open()
    Me.Worksheets("Foglio1").Pippo = "Ciao!"
End Sub

Ciao!
Maurizio

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

... e aggiungo:

Una precisazione, però, andrebbe fatta riguardo gli eventuali moduli di classe del Progetto VBA creati da noi: devono essere esplicitamente istanziati in variabili oggetto con visibilità globale, esattamente come succede con gli oggetti Workbook e Worksheet dell'esempio, che però sono istanziati implicitamente all'avvio.

Spero di non aggiungere confusione con il seguente esempio, perché lo scopo sarebbe esattamente il contrario. Sperém...

__________________________________________

' Standard Module : modGlobal
'
Option Explicit

Public mySample As clsSample
Public Pippo    As String

__________________________________________

' Class Module : clsSample
'
Option Explicit

Public Pippo As String

__________________________________________

' Class Module : ThisWorkbook - Workbook
'
Option Explicit

Public Pippo As String

Private Sub Workbook_BeforeClose(ByRef Cancel As Boolean)
      Set mySample = Nothing
End Sub

Private Sub Workbook_Open()
     
      modGlobal.Pippo = "Ciao 1!" ' (il nome del modulo qui è necessario

                                ' perché dal punto di vista di

                                ' Workbook prima viene il "suo" Pippo, poi

                                ' quello globale. 

      If mySample Is Nothing Then Set mySample = New clsSample
      mySample.Pippo = "Ciao 2!"
     
      Me.Pippo = "Ciao 3!"
     
      Me.Worksheets("Foglio1").Pippo = "Ciao 4!"
     
End Sub

__________________________________________

' Class Module : Foglio1 - Worksheet
'
Option Explicit

Public Pippo As String

Private Sub Worksheet_Activate()
      MsgBox modGlobal.Pippo, , TypeName(modGlobal.Pippo)
      MsgBox mySample.Pippo, , TypeName(mySample)
      MsgBox Me.Pippo, , TypeName(Me)
      MsgBox Me.Parent.Pippo, , TypeName(Me.Parent)
End Sub

__________________________________________

Ciao!
Maurizio

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

Ciao, scusa se rispondo con ritardo è perché sono impegnato con qualche controllo personale, ma sopratutto perché sto cercando di risolvere il problema. Vorrei provare i tuoi suggerimenti ma, e qui si vede quanto è grande l'oscurità che mi circonda, non sono riuscito a capire dove si inseriscono queste definizioni.

Standard Module : modGlobal
'
Option Explicit

Public mySample As clsSample
Public Pippo    As String

__________________________________________

Class Module : clsSample
'
Option Explicit

Public Pippo As String

__________________________________________

Class Module : ThisWorkbook - Workbook
'
Option Explicit

Public Pippo As String

Private Sub Workbook_BeforeClose(ByRef Cancel As Boolean)
      Set mySample = Nothing
End Sub

per favore dammi ancora una mano.

grazie, Claudio

Per meglio spiegare quello che vorrei fare ti allego una breve descrizione del codice che ho sviluppato nel tentativo di risolvere, INVANO, il problema.

Il problema è di per se semplice ma la sua soluzione, a me, non pare tale in Excel, stante la mia preparazione e conoscenza dello strumento. Il problema può essere così riassunto:

Ho una applicazione che per essere attivata necessita di una serie di valori di inizializzazione che attualmente sono contenuti in celle non visibili. Per eliminare questa situazione, a mio giudizio, ne elegante e neppure molto funzionale, ho pensato che potevo fare la stessa cosa utilizzando un Foglio ad hoc che chiamerò SetUp, nel quale poter fornire tutti i parametri necessari per il suo avvio. Per spiegare l’ipotesi di lavoro farò riferimento a un esempio con due valori Nome e Data.

Al lancio della procedura (WorkBook_Open) se una delle due variabili (es. Nome) non è stata definita (Nome = “”) , allora viene attivato (vedi codice allegato) il Foglio SetUp che a sua volta è, nel nostro caso, composto (vedi Fig. 1) di un Frame, due TextBox e due Bottoni “Conferma” e “Annulla”.

Codice di attivazione procedura.

Option Explicit

Public Nome As String   ‘Parametri di inizializzazione

Public Data1 As String

 

Private Sub Workbook_Open()

If Nome <> "" Then

    Call MsgBox(prompt:="Benvenuto " & Application.UserName & " al workbook " & Me.Name)

    Me.Sheets(1).Activate

  Else

    Call MsgBox(prompt:="Inizializza l'Applicazione " & Application.UserName & " al workbook " & Me.Name)

    ThisWorkbook.Sheets("SetUp").Activate

End If

End Sub

Foglio SetUp per l’acquisizione dati.

Fig. 1

L’obiettivo è, ovviamente, raccogliere questi dati e trasferirli in Variabili interne in modo da poter essere utilizzate con lo scopo di configurare l’applicazione. Nel cercare di realizzare questa soluzione incontro una serie di difficoltà:

  • Gestione dei TextBox (Txt1 e Txt2):

Non so se esiste (sembra di si ma non funziona) es. oggetto.SetFocus/oggetto.Focus e oggetto.LostFocus, sicuramente funzioneranno nei Form.

  • Trasferire i dati acquisiti nei TextBox nelle variabili Nome e Data per poterli utilizzare in altri Fogli tramite l’utilizzo del CommandButton “Conferma”.

Per controllare la loro presenza e disponibilità,  nel Foglio2 all’evento Activate è stato attivato un MsgBox con la stampa di detti valori e che risulta essere sempre “”.

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

<cut>

Capisco bene che alla prima apertura del file l'utente deve inserire i suoi dati per personalizzare il file?

--
Mauro Gamberini
Microsoft© MVP (Excel)
http://www.maurogsc.eu

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

Ciao Mauro, grazie. 

Si è corretto, al primo avvio l'utente dovrà inserire dei dati per caratterizzare il programma, dati non solo anagrafici ma anche di dimensionamento o di tipizzazione delle chiavi dei prodotti o delle password.

Il Foglio utilizzato a questo scopo potrà poi essere nascosto o cancellato.

Girando in Internet ho trovato un tuo articolo, sempre relativo a quest'argomento, ma che purtroppo per me, non sono riuscito al utilizzare.

Ringrazio te e tutti quanti stanno dandomi un aiuto,

Claudio

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

[...]

L’obiettivo è, ovviamente, raccogliere questi dati e trasferirli in Variabili interne

[...]

Ciao Claudio,

forse il punto è questo: cosa intendi con variabili interne? In Visual Basic questo concetto non esiste. Come avemmo già modo di discutere a suo tempo, puoi memorizzare permanentemente dei valori, e ritrovarteli a una nuova apertura, in celle della Cartella di lavoro, come già fai (ma dici che non ti piace. Perché?).

Oltre le celle ci sono altre posizioni in cui memorizzare valori, parametri, ecc: le proprietà della Cartella di lavoro, per esempio. Ma non mi sembra il caso.

Ciao!
Maurizio

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

Ciao Maurizio, ti ringrazio per la risposta e per aver sollevato questo problema. Premesso che non ne faccio e non ne voglio fare una questione filosofica, ma hanno ragione i due grandi (Albert e Galilei), è solo una questione di relatività. Dal mio punto di vista una variabile è un valore che cambia nel tempo, me tre una costante è un valore che non cambia. Prediamo ad esempio il Pi Greco: cosa è il pi greco una variabile o una costante? Secondo l'accezione comune è una costante, ma a mio giudizio è una variabile, variabile in funzione del numero di decimali che considero e che, di volta in volta, posso cambiare.

Detto questo, e per favore non mandarmi a quel paese, per me una variabile è un indirizzo di memoria nel quale memorizzo un dato che rimane tale fino a quando non decido di cambiarlo.

Forse mi sono espresso in modo non corretto scrivendo:

L’obiettivo è, ovviamente, raccogliere questi dati e trasferirli in Variabili interne

forse sarebbe stato più corretto dire costanti, ma il senso di quello che vorrei poter fare non cambia.

Perché non mi piace la soluzione di avere quei valori in un foglio? a portata di mano dell'utente? con la possibilità di poterli modificare a suo piacimento inficiando il programma?, è vero che tutto si può fare ma è altresì vero che si può complicare la vita all'infinito a chi tenti di manomettere dei dati di base e, quindi pensavo che la soluzione di trasferire questi dati potesse essere valida.

Grazie.

Claudio

Il problema è stato risolto?

Siamo spiacenti che questo non sia stato d'aiuto.

Fantastico! Grazie per aver scelto questa risposta.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento, ci aiuta a migliorare il sito.

Sei soddisfatto di questa risposta?

Grazie per il tuo commento.

* Prova con un numero di pagina inferiore.

* Immetti solo numeri.

* Prova con un numero di pagina inferiore.

* Immetti solo numeri.