JavascriptProva

Visualizzazione post con etichetta vba. Mostra tutti i post
Visualizzazione post con etichetta vba. Mostra tutti i post

lunedì 7 marzo 2016

Creazione di un nuovo foglio con un dato nome in Excel.

Da un elenco di fogli "intoccabile" si copia il tutto su un nuovo foglio rinominato ad hoc.
Bisogna anche gestire l'ipotesi in cui il nuovo foglio già esista.


Sub Macro3()


    Set NewSheet = Sheets.Add
    On Error GoTo ErrHandler
    NewSheet.Name = "Foglio elaborazione"
    Sheets("riserva").Cells.Copy Destination:=NewSheet.Cells

    Exit Sub
ErrHandler:
    NewSheet.Delete
    
End Sub
Con questo codice ci siamo quasi.
Viene aggiunto un nuovo foglio, e viene rinominato, ma c'è una gestione dell'errore nel caso in cui un foglio con questo nome già esista: il foglio viene eliminato.
L'unico neo è che all'atto dell'eliminazione del foglio appare un avviso, come di default ogni qualvolta si elimini un foglio.
La cosa è disattivabile: devo solo ricordare come.

Ecco:
Sub Macro3()


    Set NewSheet = Sheets.Add
    On Error GoTo ErrHandler
    NewSheet.Name = "Foglio elaborazione"
    Sheets("riserva").Cells.Copy Destination:=NewSheet.Cells

    Exit Sub
ErrHandler:
    Application.DisplayAlerts = False
    NewSheet.Delete
    Application.DisplayAlerts = True
End Sub
In questo modo, il tentativo di rinominare un nuovo foglio aggiunto abortisce alla base, in quanto il nuovo foglio aggiunto viene prontamente eliminato, come se non fosse mai stato aggiunto.
Peraltro, provando manualmente a eliminare un foglio della cartella, gli avvisi appaiono come di norma perché l'impostazione Application.DisplayAlerts è settata a false solo per il momento necessario ad eliminare senza "traumi" il foglio appena aggiunto.
Però la cosa sarebbe più completa ed elegante se l'utente potesse avere la possibilità di scegliere se mantenere il vecchio foglio "Foglio Elaborazione", oppure crearne uno nuovo che sia la copia dell'originale, nel caso in cui il foglio sia stato per qualche motivo modificato.
Ci provo...

Ed ecco il risultato finale: si può scegliere se si vuole ricreare il foglio o mantenere quello preesistente.
Sub Macro3()

    
    Set NewSheet = Sheets.Add
    On Error GoTo ErrHandler
    NewSheet.Name = "Foglio elaborazione"
   
    GoTo fine

ErrHandler:
    risposta = MsgBox("Creare un nuovo Foglio Elaborazione?", vbYesNo)
    If risposta = vbYes Then
        Application.DisplayAlerts = False
        Sheets("Foglio elaborazione").Delete
        Application.DisplayAlerts = True
        NewSheet.Name = "Foglio elaborazione"
    Else
        Application.DisplayAlerts = False
        NewSheet.Delete
        Application.DisplayAlerts = True
    End If
    
fine:
     Sheets("riserva").Cells.Copy Destination:=Sheets("Foglio elaborazione").Cells
End Sub

lunedì 29 febbraio 2016

VBA Excel: un paio di funzioni utili per manipolare un documento

Ecco un paio di routines di VBA utili per manipolare il foglio Excel.

Questa copia un frammento di una riga in una colonna:
'Codice per ricopiare un range di celle disposte in riga in colonna su un altro o sullo stesso foglio.
'Accetta come parametri:
'NOME DEL FOGLIO DI ORIGINE
'RIGA DEL RANGE DA COPIARE
'COLONNA DI INIZIO DEL RANGE DA COPIARE
'COLONNA DI FINE DEL RANGE DA COPIARE
'NOME DEL FOGLIO DI DESTINAZIONE
'RIGA DI INIZIO DEL RANGE DI DESTINAZIONE
'COLONNA DESTINAZIONE DEL RANGE DA COPIARE

Private Sub copy(SourceSheetName As String, SourceRow As Integer, SourceCol1 As Integer, SourceCol2 As Integer, DestSheetName As String, DestRow As Integer, DestCol As Integer)
For n = SourceCol1 To SourceCol2
Sheets(SourceSheetName).Cells(SourceRow, n).copy Destination:=Sheets(DestSheetName).Cells(DestRow + n - 2, DestCol)
Next
End Sub

Questa cancella le righe vuote da un documento:
'Cancella le righe vuote di un foglio.
Sub DeleteEmptyRows()
Dim Righe As Collection
Set Righe = New Collection
For n = 1 To ActiveSheet.UsedRange.Rows.Count
Righe.Add ActiveSheet.Rows(n)
Next n
For Each riga In Righe
If WorksheetFunction.CountA(riga) = 0 Then riga.Delete
Next
End Sub

venerdì 26 febbraio 2016

Approccio VBA a un documento

Veniamo al VBA...

Devo elaborare un file di risposte di pazienti a un'intervista.
Lo avevo già fatto, ma dal momento che rimuovo attivamente memorie connesse a questa attività che detesto, rimuovo anche i codici.
Così è meglio che metta tutto per iscritto.
Mi rianalizzo un po' il codice.
Sub main()
For n = 1 To 100
Sheets("Risposte").Cells(n, 1).Formula = n
Sheets("Risposte").Cells(n, 2).Formula = Sheets("Questionario").Cells(1, n).Formula
Next n
End Sub
In italiano, significa che nel foglio chiamato "Risposte", su 100 righe nella prima colonna mettiamo il numero di riga, mentre nella seconda mettiamo il contenuto delle celle su 100 colonne progressive della prima riga del foglio "Questionario".

Creo un nuovo foglio chiamato "Risposte" per vedere come funziona senza peraltro combinare danni.
Ecco applicata la macro:

Foglio "Questionario":


Foglio "Risposte":


Era come ho previsto io.

Ma ora sono a un punto morto: come ho fatto a ottenere i SI NO? Da quali dati?

Cerchiamo di decifrare altri files...

Ho dimenticato tutto.
Riprendo il file originale e me lo ristudio con calma...



Ecco, qui sono presentati in modo molto confuso. L'unico riferimento è il numero che sta sulla colonna Q.
Dal momento che devo fare calcoli mi conviene avere le colonne in formato numerico.

Fatto! Strumenti->Opzioni->Generale->Stile di riferimento R1C1.

Fatto questo, mi vorrei separare le varie interviste. Il punto di riferimento è il numero nella colonna Q, che ora diventa colonna 17! (E infatti contando sulle ditine ho verificato che la Q è la 17esima lettera dell'alfabeto inglese... GUH! GUH!)

Separarle potrebbe significare mettere delle righe vuote per separare ciascuna intervista dall'altra.
O anche, più elegantemente e funzionalmente, ricopiare ognuna su un foglio separato!
Studierei una macro in tal senso...

Contare le righe che presentano il numero 1 sulla colonna 17...
Sub suddividi()
Dim contatore As Integer
contatore = 0
Dim linea As Integer
linea = 174

Do Until Cells(linea, 17).Formula <> 3
linea = linea + 1
contatore = contatore + 1
Loop
Debug.Print linea & " " & contatore
End Sub
Cambiando il numero di linea iniziale e il numero da ricercare nella colonna 17 ottengo sempre lo stesso numero.
88 86
174 86
260 86

Ora, su questa base, costruisco un codice in cui copio ogni singolo troncone di 86 linee su un nuovo foglio di Excel.
Separo, praticamente, le interviste, ognuna su un nuovo foglio---