Gianni Giaccaglini

Tricks & mini applics on WPF
posts - 46, comments - 0, trackbacks - 0

Inserimento clausole di apertura/chiusura in documenti burocratici

In documenti di tipo notarile e simili, sono previste espressioni standard di due tipi, poste di solito all’inizio e al termine dell’atto:

• L’anno duemilaquattordici addì ventitre del mese di febbraio alle ore…

• Documento composto da venti pagine, progressivamente numerate da 1 (UNO) a venti.

Per evitare la noia di digitare a mano tali logorroiche formule il ricorso a template Word non va, perché diversi termini variano da caso a caso, così ho escogitato due macro di inserimento, basate rispettivamente sulle funzioni seguenti;

Function DataBurocr() As String e

Function NumPagine(questoDoc As Document) As Integer

 Il codice per la clausola di apertura

Come appena detto, alla base si ha la funzione seguente, ove per semplicità si è rinunciato alla tipizzazione delle variabili, salvo la funzione DataBurocr. Probabilmente molti si attendono l’utilizzo della funzione VBA Date() che restituisce il numero seriale della data offerta dal clock del sistema, nonché le conseguenti funzioni Day, Month e Year traducendone subito dopo i risultati nei testi letterali corrispondenti. La funzione preannunciata non presenta sorprese, salvo per quanti obliassero o addirittura ignorassero la comoda funzione Array che permette di creare i vettori del caso:

Function DataBurocr() As String
    Giorni = Array("", "primo", "due", "tre", "quattro", "cinque", "sei", "sette", "otto", "nove", "dieci", "undici", "dodici", "tredici", "quattordici", "quindici", "sedici", "diciassette", "diciotto", diciannove", "venti", "ventuno", "ventidue", "ventitre", "ventiquattro", "venticinque", "ventisei", "ventisette", "ventotto", "ventinove", "trenta", "trentuno")
    Mesi = Array("", "gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre")
    Anni = Array("quattordici", "quindici", "sedici", "diciassette", "diciotto", "diciannove", "venti")
    Oggi = Date ' Numero seriale data odierna
    Giorno = Day(Oggi)
    Mese = Month(Oggi)
    indAnnoVs14 = Right(Year(Oggi), 2) - 14
    DataBurocr = _
   "L'anno duemila" & Anni(indAnnoVs14) & " addì " & Giorni(Giorno) & " del mese di " & Mesi(Mese) & " alle ore "
End Function

Ulteriori commenti.

La stringa vuota ("") all’inizio dei vettori Giorni e Mesi deriva dal fatto che un Array parte con indice zero, mentre Day e Month iniziano – ci mancherebbe – con 1. Qualcuno poi osserverà che in luogo della funzione Date si sarebbe potuto adottare la funzione Now, che fornisce il numero seriale con tanto di parte decimale (mentre Date ci dà solo la parte intera). Solo così infatti si potrebbe ricavare l'ORA, con Hour(Now), mentre Hour(Date) dà sistematicamente 0. Giusto!, però ho pensato che fosse meglio affidare all'utente la responsabilità di definire questo particolare, in quanto la clausola dataria inserita all'inizio troppo presto potrebbe risultare imprecisa

Qualcuno a questo punto si stupirà che per l’anno non si utilizzi una funzione di conversione da cifre a lettere, reperibile agevolmente su Internet. Il motivo pratico è legato, oltre che alla pigrizia, alla riflessione che non si debba operare da qui all’eternità, ma solo a partire dal 2014, andando avanti per un numero ragionevole di anni.

Chi vuole può estendere a suo uso e consumo il vettore Anni. In questo caso, comunque il... tormentino dell’indice zero viene risolto togliendo 14 al valore fornito dalle due ultime cifre di Year(Oggi) e inserendo il risultato nella variabile indAnnoVs14 (indice dell’anno rispetto al 2014).

Il concatenamento di stringhe che chiude la funzione si commenta da solo. Idem la macro che utilizza DataBurocr per infilarla in cima all’atto (salvo far notare che lo spostamento finale a destra si è reso necessario in quanto Selection.Text inserisce una stringa selezionata.

Sub InserDataBurocratica()
    ' MsgBox DataBurocr ' Usata per debug
    Selection.HomeKey Unit:=wdStory
    Selection.Text = DataBurocr
    Selection.MoveRight Unit:=wdWord
End Sub

Il codice per la clausola di chiusura

In questo caso confesso di essermi trovato inizialmente in difficoltà, perché – salvo segreti tuttora a me ignoti – nel modello a oggetti di Word non sembra esistere un oggetto Page o un insieme Pages.

Pensa e ripensa ho escogitato un trucco che ritengo brillante, senza falsa modestia. DEVO SUBITO ANTICIPARE CHE ALLA FINE HO SCOPERTO IL CODICE SPECIFICO VBA. L’algoritmo si basa su questi passi:

1. Inizia piazzando la strana coppia “#@” (difficilmente reperibile in atti burocratici) in testa al documento;

2. salta alla sua fine;

3. procedi a ritroso con ripetute mosse Ctrl+PagUp , incrementando il contapagine;

4. arresta il loop quando si arriva alla strana coppia in cima al documento.

L’inusitata funzione e la relativa macro che inserisce la clausola introduttiva sono riportate qui senza altre storie e pensando che i commenti inseriti nel codice siano sufficienti per chi non è alle prime armi col VBA.

Function NumPagine(questoDoc As Document) As Integer
   Application.ScreenUpdating = False
' Evita i movimenti di schermo, velocizzando il codice
   
Selection.HomeKey Unit:=wdStory
' Inizio documento
   
Selection = "#@"
' Coppia speciale di caratteri
   
Selection.EndKey Unit:=wdStory
' Fine documento
   
Dim Np As Integer
   Np = 1
' Inizializza il contapagine
  
While Selection <> "#@"
' Finché non incontri la coppia "#@"
  
   Application.Browser.Previous
' Equivale a Ctrl+PageUp
  
   Np = Np + 1
' Incrementa il contapagine
  
   Selection.MoveRight Extend:=wdExtend, Count:=2
' Seleziona i primi 2 caratteri
  
Wend
   Selection.Delete
' Cancella l'ultima coppia
  
NumPagine = Np
' Restituisci NumPagine
End Function

Sub ProvaNumPagine() ' Test di prova della funzione NumPagine
   
Application.ScreenUpdating = True
' Ripristina movimenti di schermo
   
MsgBox "Numero pagine: " & NumPagine(ActiveDocument)
End Sub

Sub InserChiusuraBurocratica()
    Application.ScreenUpdating = True
    Dim Np As Integer
    Np = ContaPagine(ActiveDocument)
    Selection.EndKey Unit:=wdStory
    Selection = _
    "Documento composto da " & Np & " pagine, progressivamente numerate da 1 (UNO) a " & Np
    Selection.EndKey Unit:=wdStory
End Sub

Il metodo funziona anche con documenti che comprendono immagini e tabelle.

La funzione che offre l'ambiente VBA, suggerita da D. CATTARUZZA

Public Function GetPageCount(doc As Document) As Integer
Dim oStat As WdStatistic
oStat = WdStatistic.wdStatisticPages
GetPageCount = doc.ComputeStatistics(oStat)
End Function


TUTTO QUI! MEGLIO TARDI CHE MAI..

Print | posted on venerdì 29 agosto 2014 18:15 |

Feedback

No comments posted yet.

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 3 and 2 and type the answer here:

Powered by:
Powered By Subtext Powered By ASP.NET