Word (VBA): impostare una password in tutti i file .doc di una cartella

26 aprile 2010

Di seguito riporto una macro VBA per Word che assegna una specifica password (di protezione in modifica) a tutti i file DOC contenuti in una determinata directory.

Una volta applicata la protezione ai file, sarà inibita qualsiasi modifica,  ad esclusione di eventuali moduli presenti nei documenti .

Ovviamente i file a cui deve essere applicata la password, prima dell’esecuzione della macro, non devono essere già protetti.

Sub inserisci_password_file_cartella()
Dim i As Integer
Dim miapassword As String

Set cartella = Application.FileSearch
miapassword = "MiaPassw12345678" 'specificare la passw da inserire
With cartella
  .LookIn = "c:\luca" 'specificare il percorso dove sono contenuti i file
  .FileName = "*.doc" 'la macro considera solo i file DOC

  If .Execute(SortBy:=msoSortByFileName, _
  SortOrder:=msoSortOrderAscending) > 0 Then
  'MsgBox .FoundFiles.Count
     For i = 1 To .FoundFiles.Count
       'MsgBox .FoundFiles(i)
        file_trovato = .FoundFiles(i)
        'apertura file
        Documents.Open FileName:=file_trovato, ConfirmConversions:=False, ReadOnly:= _
        False, AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:= _
        "", Revert:=False, WritePasswordDocument:="", WritePasswordTemplate:="", _
        Format:=wdOpenFormatAuto
        If ActiveDocument.ProtectionType = wdNoProtection Then
           'inserisce protezione
            ActiveDocument.Protect Password:=miapassword, NoReset:=False, _
            Type:= wdAllowOnlyFormFields
           'Chiude e salva il file
           ActiveDocument.Close SaveChanges:=wdSaveChanges
        End If
     Next i
  Else
     MsgBox "Nessun file trovato nella cartella specificata!"
     Exit Sub
  End If
End With
End Sub

Purtroppo le righe del codice vengono interrotte nell’articolo, ma facendo un copia-incolla è possibile visualizzarle per intero.


Excel (VBA): trovare l’ultima riga avvalorata

22 aprile 2010

Capita spesso di dover creare cicli in VBA che coinvolgono tutte le righe avvalorate in un determinato foglio di lavoro.
Ma se il numero di righe è variabile, a priori non è possibile conoscere il numero l’ultima riga avvalorata.

Una delle possibili soluzioni a questo problema è quella di salire (dal basso verso l’alto) fino alla prima riga vuota disponibile (in Excel 2003, e versioni precedenti, il nostro foglio non può avere più di 65.000 righe). In pratica:

UltimaRiga = Sheets("Foglio1").Range("A65000").End(XlUp).Row

Quindi il nostro ciclo sarà qualcosa del genere:

Sub prova()
UltimaRiga = Sheets("Foglio1").Range("A65000").End(XlUp).Row
For i = 1 to UltimaRiga
   ...
Next
End Sub

N.B.: in Excel 2007 e 2010 il numero massimo di righe è stato aumentato a 1.048.576.


Excel (VBA): velocizzare esecuzione macro

21 aprile 2010

Per velocizzare l’esecuzione del codice VBA è possibile bloccare lo “sfarfallio” dello schermo all’inizio della macro e quindi ripristinarlo alla fine dell’esecuzione.

Sub prova()
Application.ScreenUpdating = False
...
Application.ScreenUpdating = True
End Sub

Excel: creare una funzione personalizzata in VBA

17 luglio 2009

VBA, oltre alle normali procedure (sub), permette di creare un’altra tipologia di programma: le funzioni.

A differenza delle procedure che compiono un’azione, le funzioni restituiscono un singolo valore in base a dei parametri (argomenti) passati ad esse.
Una tipica funzione ha la seguente sintassi:

Function NomeFunzione(elencoParametri)
NomeFunzione = QualcheValore
End Function

All’interno della funzione è necessario comunicare quale valore la funzione deve restituire. Tale valore deve essere assegnato al nome identificativo della funzione. Se dimentichiamo di assegnare il valore al nome funzione, questa non restituirà nulla.

Nel semplice esempio seguente, la funzione “Peso” calcola il peso in Newton partendo dalla massa.

Function Peso(Massa)
'La forza peso si calcola in Newton quindi: Massa(kg) x Accelerazione di gravità(m/s2) = Peso(N)
Const g = 9.80665
Peso = Massa * g
End Function

La funzione può essere richiamata all’interno di una procedura o altra funzione VBA, oppure in una formula del foglio di lavoro (come nell’esempio seguente).

peso

In questo banale caso è forse più conveniente scrivere direttamente la formula nella cella interessata (es. =B2*9,80665), ma in situazioni più complesse le funzioni possono semplificare molto le cose.


Word: da campo modulo a file di testo con VBA script

30 Maggio 2009

Questo VBA script per Word consente di salvare il contenuto dei moduli di un file Word in un file di testo esterno.

Alcune premesse:

  • Il documento Word deve essere protetto (Strumenti – proteggi documento – Consenti compilazione moduli)
  • In questo esempio specifico i campi modulo devono avere come segnalibro rispettivamente “campo1”, “campo2”, “campo3”, “campo4”, ecc.
  • Nella macro devono essere impostati il numero di campi ed il nome/percorso del file di registro.

Di seguito è riportata la macro da abbinare ad un pulsante:

Private Sub CommandButton1_Click()

Dim file_ini, miariga As String
Dim i, num_campi As Integer

'----------------------------------------------------------------------
'Parametri da personalizzare
file_ini = "c:\registro.txt"
num_campi = 5
'-----------------------------------------------------------------------

Open file_ini For Append As #1
For i = 1 To num_campi
    miariga = miariga & ActiveDocument.FormFields("campo" & i).Result
    miariga = miariga & ";"
Next

Print #1, miariga 'scrive tutti i campi word (separati da ";" su una riga del file)
Close #1 'Chiusura File
End Sub

Ogni volta che si preme il pulsante viene aggiunta una riga al file di registro. Se il contenuto dei moduli nel file fosse così impostato:

campo_modulo1 = testo modulo 1
campo_modulo2 = mio testo modulo 2
campo_modulo3 = prova modulo 3
campo_modulo4 = testo modulo 4
campo_modulo5 = modulo numero 5

al file di registro verrebbe aggiunta la seguente riga:

testo modulo 1;mio testo modulo 2;prova modulo 3;testo modulo 4;modulo numero 5;

Quindi il contenuto dei moduli viene inserito su una stessa riga (record), con il valore di ogni campo modulo separato da “;”.

In allegato un esempio del file Word.


Stampa automatica file Word da directory locale o remota

1 aprile 2009

Dato che mi ha fatto comodo per risolvere un problema un po’ contorto, voglio segnalare questo script VBA per Word che verifica i file .DOC eventualmente presenti in una determinata directory (locale o remota) e per ognuno:
– apre
– stampa sulla stampante predefinita
– chiude

Sub stampa_file()
Set fs = Application.FileSearch
With fs
    .LookIn = "\\server_remoto\percorso"
    .FileType = msoFileTypeWordDocuments
    If .Execute > 0 Then
        For i = 1 To .FoundFiles.Count
            Documents.Open FileName:=.FoundFiles(i)
            ActiveDocument.PrintOut , Copies:=1
            ActiveDocument.Close SaveChanges:=wdDoNotSaveChanges
        Next i
    End If
End With
Application.Quit
End Sub

Spero possa essere utile a qualcuno.


Word: Campo modulo da file esterno

6 agosto 2008

Ipotizziamo di avere molti documenti di Word al cui interno siano contenuti uno (o più) campi modulo “elenco a discesa” con dei valori predefiniti, per esempio i nomi dei maestri di tennis di un Tennis Club.
Se la lista dei nomi variasse, dovremmo correggere uno a uno i campi modulo in ogni documento di Word.
Se invece il campo modulo leggesse i valori da un file estero, allora basterebbe aggiornare tale file, senza dover metter mano ai vari documenti Word.

Ecco i vari passaggi:
– creare un semplice file di testo in locale (o su un percorso remoto) che contenga i nomi dei maestri (uno su ogni riga). Per comodità io l’ho creato su C:\ e l’ho chiamato “nomi_maestri.txt”

Jean Luc Picard
William Riker
Data
Worf
Deanna Troi
Haran Banjo
Beauty Tachibana
Reika Sanjo
Garrison Tokida
---
---

– Da Word aprire l’ambiente di sviluppo macro VBA (ALT+F11), creare un nuovo modulo ed incollarvi il seguente codice:

Sub maestro()
Dim nomi_maestri(10) As String 'deve essere uguale al num righe - 1 nel file txt
Dim num_righe as Integer

num_righe = 10 'deve essere uguale al num righe - 1 nel file txt

Open "c:\nomi_maestri.txt" For Input As #1
i = 0
Do While Not EOF(1)
    Input #1, nomi_maestri(i)
    i = i + 1
Loop
Close #1

ActiveDocument.FormFields("maestro").DropDown.ListEntries.Clear
For i = 0 To num_righe
    With ActiveDocument.FormFields("maestro").DropDown.ListEntries
        .Add nomi_maestri(i)
    End With
Next

End Sub

Attenzione: nel codice VBA abbiamo impostato l’array “nomi_maestri” con il valore 10 (dato che parte da 0, conterrà 11 valori). Quindi il file di testo dovrà contenere almeno 11 righe avvalorate.

– Tornare in Word e creare un nuovo campo modulo “elenco a discesa” settando solo i seguenti valori:

  • Esegui macro in Entrata: maestro
  • Segnalibro: maestro

– Proteggere il documento di Word:

  • Strumenti – Proteggi documento
  • Consenti solo questo tipo di modifiche nel documento: “Compilazione moduli”.

A questo punto, cliccando sul campo modulo verranno mostrati i valori contenuti nel file ti testo esterno.

Allego un file di esempio con la macro VBA già impostata.