Creazione Tabella - Una Classe per tutte le occasioni

dracoscrigno

CioccaPiatti & VBA Expert
Expert
1 Maggio 2016
3.689
122
63
office pro 2010
42
Era un pochino che ci pensavo.

Tutte le volte che si costruisce una macro, bene o male, ci si trova davanti all' inevitabile; dover impostare il range di una tabella. Al che mi sono detto: "Perchè non scrivere uan cosa che vada bene sempre!?".
Un piccolo scatolino con dentro quelle due o tre funzioni o procedure che si scrivono sempre e che, quindi, può far comodo riciclare.

Ecco che quindi ho pensato di scrivere un paio di istruzioni per poter definire una tabella con le poche istruzioni che si hannno a disposizione quando si incomincia a scrivere una macro.

LA prima cosa è la sintassi, che ho cercato di mantenere limitata il più possibile e coerente con quanto da modo di fare Excel nella normale compilazione del listato.

Codice:
Function CreaTabella(ColXlUp As Variant, AngoloTop As Range, Optional UltimaRiga As Long = 0) As Range
    Dim XlFile As Workbook
[TABLE="class: grid"]

[TD="align: center"]ColXlUp
As Variant[/TD]
Obbligatorio
Il Primo argoento da impostare è una delle due Colonne della Tabella. Solitamente è il primo campo ma può benissimo essere anche l' ultimo. L' importante è che ogni sua cella sia occupata per far si che End(xlup) possa dare il giusto risultato.
IN caso Tabella Vuota, o di Tabella con questa colonna vuota, il risultato è comunque il primo record della tabella stessa.


[TD="align: center"]AngoloTop
As Range[/TD]
Obbligatorio
AngoloTop è uno dei due angoli Superiori della tabella. Non deve appartenere alla colonna impostata in ColXlUp ma alla colonna opposta.


[TD="align: center"]UltimaRiga
As Long[/TD]
Opzionale
Ultima riga, verrà certamente utilizzata poco o niente, ma non si sa mai. potrebbe venir buona.
Con questa variabile aggiuntiva è possibile determinare una tabella completamente vuota.

[/TABLE]


Alcuni esempi di sintassi differente:

Codice:
Set Tabella = DB.CreaTabella(Range("N9"), Range("L3"))
Codice:
Set Tabella = DB.CreaTabella(2, Range("F2"))
Codice:
Set Tabella = DB.CreaTabella("A", [F5])
Codice:
Set Tabella = DB.CreaTabella(5, [F3], 12)

E' una Classe, quindi per utilizzarla, ne va prima creata un istanza e poi la si può utilizzare tranquillamente.

Codice:
Sub MiaSubRoutin()
    Dim DB As New clsDB
    Dim Tabella As Range


    Set Tabella = DB.CreaTabella(2, Range("F2"))
End Sub
Il listato è molto breve e non è tanto differente dai soliti...

Questa mia condivisione, oltre che per la banale idea della procedura che setta una tabella, vuole anche essere un modo per suggerire lo spezzare i propri progetti in piccole parti. Di modo di poter fare come in questo caso, poter riutilizzare lo stesso listato più e piùù volte.
Il tempo risparmiato nel riscrivere potrebbe essere impegnato in altre attività FumaErbaGiroOcchi

clsDB
Codice:
Option Explicit


Public Function CreaTabella(ColXlUp As Variant, AngoloTop As Range, Optional UltimaRiga As Long = 0) As Range
    Dim XlFile As Workbook
    Dim Foglio As Worksheet
    Dim PrimaCella As Range
    Dim Colonna As Variant
    
    Set XlFile = Workbooks(Worksheets(AngoloTop.Parent.Name).Parent.Name)
    Set Foglio = Worksheets(AngoloTop.Parent.Name)
    
    If TypeOf ColXlUp Is Range Then
        Colonna = ColXlUp.Column
    Else
        Colonna = ColXlUp
    End If
    
    With Foglio
        If UltimaRiga = 0 Then
            Set PrimaCella = .Cells(.Rows.Count, Colonna).End(xlUp)
            If PrimaCella.Cells(1).Row < AngoloTop.Row Then
                Set PrimaCella = .Cells(AngoloTop.Row, PrimaCella.Column)
            End If
        Else
            Set PrimaCella = .Cells(UltimaRiga, Colonna)
        End If
        Set CreaTabella = .Range(PrimaCella, AngoloTop)
    End With
End Function

Link a DropBox -> clsDB.cls
 

dracoscrigno

CioccaPiatti & VBA Expert
Expert
1 Maggio 2016
3.689
122
63
office pro 2010
42
Nell' utilizzare la funzione proposta in topic e, come sempre, poco testata, ho scoperto un errore. Tra l' altro molto grossolano:

Codice:
    Set XlFile = Workbooks(Worksheets(AngoloTop.Parent.Name).Parent.Name) [COLOR=#333333]    Set Foglio = Worksheets(AngoloTop.Parent.Name)[/COLOR]
Tutte e due le istruzioni contengono un errore e, togliendo il superfluo, una delle due non è necessaria

Sia Worbooks che worksheets, sono influenzati da ciò che, in Excel Application, ha il focus nel dato memento dell' utilizzo. Cosa significa? Semplicemente che workbooks e worksheets, se non specificato, restituiscono informazioni riguardo al file in primo piano ed al foglio in primo piano.
Naturalmente me ne sono accorto quando ho utilizzato la Function avendo due file aperti contemporaneamente....

Per ovviare a questo, avevo deciso, di raggiungere il workbook giusto ed il worksheet giusto attraverso l' unico argomento sicuramente range.
Codice:
[COLOR=#333333]Public Function CreaTabella(ColXlUp As Variant, [B]AngoloTop As [/B][/COLOR][COLOR=#006400][B]Range[/B][/COLOR][COLOR=#333333], Optional UltimaRiga As Long = 0) As Range[/COLOR]
Tutti gli oggetti hanno una proprietà, denominata Parent, che definisce il loro "genitore" o "contenitore".
(una cella è il contenuto di un foglio quindi il suo contenitore è quel dato foglio. Ovvero un foglio è anche membro, proprietà di un workbook. tale appartenenza è deinita nelal propoerty .Parent.

Ecco che quindi, avendo a disposizione SOLO la variabile oggetto "AngoloTop" è possibile sapere, attraverso di essa, qul' è tutta la gerarchia di oggetti in cui essa è contenuta... come una matriosca a aritroso.

AngoloTop.Parent rappresenta l' oggetto Worksheet di cui angolotop ne è un range.
Se AngoloTop.Parent ne è il worksheet, allora, analogamente, la sua property .Parent, sarà il proprio workbook ed in effetti:
AngoloTop.Parent.Parent è proprio il workbook in cui è presente il foglio in cui è presente il range rappresentato da AngoloTop.

Il primo errore commesso nella stesura della funzione è stato quello di utilizzare la proprietà name per avere a che fare con l' oggetto, quando potevo utilizzare direttamnte l' oggetto stesso. Questo ha poi portato, a casacata, a commettere anche tutti gli altri errori.
Non mi ricordo perché questa scelta. probabilmente perchè stavo dormendo davanti al pc e mi è venuto un attacco di idiozia fulminante.
Semplificando all' essenziale le istruzioni attraverso un primo ragionamento:


  1. Per definire un range servono due celle. queste due celle devon, ovviamente e senza ombra di dubbio, essere parte di uno stesso foglio.
  2. Per determinare il foglio di un range, è possibile farlo attraverso la propria property .Parent.
la funzione corretta, quindi, dovrebbe essere quella che segue:

(ho lasciato le istruzioni da cancellare come commentate per la comprensione della correzione)
Codice:
Option Explicit


Public Function CreaTabella(ColXlUp As Variant, AngoloTop As Range, Optional UltimaRiga As Long = 0) As Range
     [COLOR=#008000][B]'Dim XlFile As Workbook ... istruzione da cancellare[/B][/COLOR]
    Dim Foglio As Worksheet
    Dim PrimaCella As Range
    Dim Colonna As Variant
    
    '[B][COLOR=#008000]Set XlFile = Workbooks(Worksheets(AngoloTop.Parent.Name).Parent.Name)... da cancellare
     'Set Foglio = Worksheets(AngoloTop.Parent.Name)... istruzioni da cancellare[/COLOR][/B]
    [B][COLOR=#008000][/COLOR]Set Foglio = AngoloTop.Parent[/B]    

    If TypeOf ColXlUp Is Range Then
        Colonna = ColXlUp.Column
    Else
        Colonna = ColXlUp
    End If
    
    With Foglio
        If UltimaRiga = 0 Then
            Set PrimaCella = .Cells(.Rows.Count, Colonna).End(xlUp)
            If PrimaCella.Cells(1).Row < AngoloTop.Row Then
                Set PrimaCella = .Cells(AngoloTop.Row, PrimaCella.Column)
            End If
        Else
            Set PrimaCella = .Cells(UltimaRiga, Colonna)
        End If
        Set CreaTabella = .Range(PrimaCella, AngoloTop)
    End With [COLOR=#333333]End Function[/COLOR]
 

dracoscrigno

CioccaPiatti & VBA Expert
Expert
1 Maggio 2016
3.689
122
63
office pro 2010
42
la ripubblico corretta dai tag del vecchio forum visto che nessuno passa a ripulire i vecchi post... così. magari la si può anche lincare al posto di scrivere sempre le stesse 22 istruzioni per definire una la solita tabella

Visual Basic:
Option Explicit

Public Function CreaTabella(ColXlUp As Variant, AngoloTop As Range, Optional UltimaRiga As Long = 0) As Range
    Dim Foglio As Worksheet
    Dim PrimaCella As Range
    Dim Colonna As Variant
    
    Set Foglio = AngoloTop.Parent

    If TypeOf ColXlUp Is Range Then
        Colonna = ColXlUp.Column
    Else
        Colonna = ColXlUp
    End If
    
    With Foglio
        If UltimaRiga = 0 Then
            Set PrimaCella = .Cells(.Rows.Count, Colonna).End(xlUp)
            If PrimaCella.Cells(1).Row < AngoloTop.Row Then
                Set PrimaCella = .Cells(AngoloTop.Row, PrimaCella.Column)
            End If
        Else
            Set PrimaCella = .Cells(UltimaRiga, Colonna)
        End If
        Set CreaTabella = .Range(PrimaCella, AngoloTop)
    End With
End Function
 
  • Like
Reactions: Powerwin

Sostieni ForumExcel

Aiutaci a sostenere le spese e a mantenere online la community attraverso una libera donazione!