Aggiungi righe vuote in Tabella



  • Aggiungi righe vuote in Tabella
    di Perry data: 16/11/2013 18:27:57

    Grazie anticipate
    Nel foglio Sh_TITOLI ho una tabella (circa 300 righe) a cui ho associato il nome TITOLI, vorrei, associando ad un pulsante "Aggiungi Righe", una macro per aggiungere n.righe vuote in fondo alla tabella TITOLI.
    Grazie 1K per la vostra comprensione.



  • di Vecchio Frac data: 16/11/2013 18:34:50

    Mi sembra che nelle Tabelle create in Excel esiste già il pulsantino in fondo alla tabella per aggiungere un nuovo set di dati, a forma di asterisco.





  • di Perry (utente non iscritto) data: 16/11/2013 18:49:02

    Scusa Vecchio Frac
    Credo di non essermi spiegato bene, il mio è un insieme di righe che ho associato ad un nome (TITOLI), devo trovare l' ultima riga e aggiungere a questa alcune righe vuote per implementare le righe di immissione.



  • di Perry (utente non iscritto) data: 16/11/2013 18:58:02

    Per la precisione dovrei copiare l' ultima riga vuota (ma che contiene formule e Formati) e aggiungerla n.volte in fondo.
    Scusa, grazie 1K



  • di Vecchio Frac data: 17/11/2013 12:59:30

    cit. "dovrei copiare l' ultima riga vuota (ma che contiene formule e Formati)"
    ---> E questa è un'informazione importante, che cambia parecchio lo scenario, ma perchè bisogna sempre tirare fuori con le pinze i particolari che contano?
    Serviranno alcune righe di codice per raggiungere l'automatismo desiderato.





  • di Perry (utente non iscritto) data: 18/11/2013 14:58:45

    per Vecchio Frack, hai perfettamente ragione e mi scuso per la superficialità della mia richiesta, aspetto con impazienza tuoi suggerimenti e codice.
    Grazie



  • di Grograman (utente non iscritto) data: 18/11/2013 15:08:58

    Siamo noi che aspettiamo con trepidazione il tuo file di esempio



  • di Grograman (utente non iscritto) data: 18/11/2013 15:16:01

    Allegato esempietto:
     
    Option Explicit
    
    Sub Righe()
      Dim oTbl As Object
      Dim x As Long
      Set oTbl = ActiveSheet.ListObjects("Tabella1")
      
      With oTbl
        x = oTbl.ListRows.Count
        .ListRows.Add (x)
      End With
      
      Set oTbl = Nothing
    End Sub
    



  • di Grograman (utente non iscritto) data: 18/11/2013 15:17:22

    Scusate, meglio sarebbe:
     
      Dim oTbl As ListObject



  • di Perry (utente non iscritto) data: 18/11/2013 15:48:42

    Grazie 1K
    Ho provato la Sub Righe, ma ottengo il seguente errore :
    Indice non incluso nell' intervallo - Errore di run-time '90 , all specifica

    Set oTbl = ActiveSheet.ListObjects("Tabella1")
    Alle righe/Celle del mio intervallo ho associato il Nome Tabella1
     
    Option Explicit
    
    Sub Righe()
      Dim oTbl As ListObject
      Dim x As Long
      Set oTbl = ActiveSheet.ListObjects("Tabella1")
      
      With oTbl
        x = oTbl.ListRows.Count
        .ListRows.Add (x)
      End With
      
      Set oTbl = Nothing
    End Sub



  • di Grograman (utente non iscritto) data: 18/11/2013 16:35:00

    cit: "Alle righe/Celle del mio intervallo ho associato il Nome Tabella1"

    E qui volevo arrivare.
    Seleziona l'intervallo e premi CTRL+T
    Per magia ti compariranno le tabelle!




  • di Perry (utente non iscritto) data: 18/11/2013 18:36:02

    Grazie Grograman
    Ho fatto come mi hai suggerito (creato Tabella) ma mi aggiunge una riga (SENZA le formule contenute nelle celle) PRIMA dell' ultima riga. Facendo il debug ho visto che conteggia -1 riga rispetto all' intervallo
    Scusa se ti Rompo, ma è proprio necessario creare una Tabella ? non è possibile operare sul range di righe/colonne chiamato "Campi_Excel" ?
    Quando eseguivo la Copia-Incolla da macro funzionava ma mi imposta il range della riga sorgente, mentre io volevo renderlo variabile pescando sempre l' ultima riga
    Ti allego il file cosi potrai vedere a cosa mi serve.
    Grazie 1k




  • di Grograman (utente non iscritto) data: 19/11/2013 09:21:16

    Porca vacca hai ragione... non copia le formule.

    Se riesco vedo di capire cosa bisogna aggiungere.

    Per aggiunger euna riga SOTTO l'ultima devi modificare così:
     
      With E_oTbl
        .ListRows.Add (.ListRows.Count + 1), True
      End With



  • di Perry (utente non iscritto) data: 19/11/2013 12:31:08

    Grazie Grograman
    In effetti ora aggiunge una riga all' ultima, aspetto fiducioso la modifca per la copia delle formule.
    Nel precedente ti chiedevo lumi tra l' operare con una tabella e un range di nomi, credo sia un fatto di sintassi VBA non so come sostituire al range di ultima riga con il nome dell' insieme "Excel_Campi" ecco un esempio :

    Sub Macro3()
    Rows("368:368").Select ' <--- ultima riga del range "Excel_Campi"
    Selection.Copy
    Rows("368:368").Select '<---qui vorrei sostituire con il range "Excel_Campi"
    Selection.Insert Shift:=xlDown
    Application.CutCopyMode = False
    End Sub

    che funziona e mi copia la riga e le formule, ma associando la macro ad un pulsante il range non è ovviamente variabile.

    Ancora grazie 1k per la tua disponibilità



  • di Perry (utente non iscritto) data: 20/11/2013 16:03:10

    salve a tutti in particolare a Grograman
    sul mio precedente avete lumi ???
    Grazie 1K



  • di Perry (utente non iscritto) data: 21/11/2013 15:04:39

    salve a tutti in particolare a Grograman
    sul mio precedente avete lumi ???
    Grazie 1K


  • x grograman
    di Perry (utente non iscritto) data: 22/11/2013 18:42:02

    Gent.mo grograman,
    aspetto fiducioso tue nuove circa il mio post,
    ho attivato la macro e mi aggiunge una riga senza copiare formati e formule.

    Ho aggiunto nel foglio la macro di Raffaele_53 (post 5310 - Eliminare i doppioni) che mi pareva particolarmente utile, ma quando clicco sul bottone per inserire una riga mi da un errore di run-time 13 - tipo non corrispondente
    --->> If Application.WorksheetFunction.CountIf(Range("D:D"), Nome) > 1 Then

    Se tu avessi la gentilezza di darci un' occhiata Ri-allego il mio file e aspetto con fiducia.
    Grazie 1k



  • di Perry (utente non iscritto) data: 24/11/2013 18:28:48

    Resto sempre in attesa di illuminanti soluzioni.



  • di Vecchio Frac data: 24/11/2013 20:15:45

    Probabilmente Grograman non ha avuto la possibilità di occuparsi della questione in questi giorni.
    Il consiglio è che è sempre meglio non rivolgersi mai a un utente specifico, ma all'intera comunità, perchè a volte accade che quell'utente non possa o non sappia rispondere.

    Nel caso specifico, "Nome" è valorizzato? è un numero o una stringa?





  • di Perry (utente non iscritto) data: 25/11/2013 16:49:48

    Scusa ma non capisco la tua domanda :
    "Nome" è valorizzato? è un numero o una stringa?

    --->> If Application.WorksheetFunction.CountIf(Range("D:D"), Nome) > 1 Then

    Ho utilizzato questa istruzione (foglio1 in VBA) modificando esclusivamente il range della colonna "D:D" dove si trovano le celle di testo, eventualmente doppio, che sto inserendo con un copia/incolla ed esegue il suo lavoro egregiamente, solo quando aggiungo una riga nuova-vuota (con VBA da modulo)mi da errore. Ecco l' insieme del codice.:
     
    Option Explicit
      Dim x As Long
                          ' per aggiungere una riga da modulo tramite botton.:
    Sub Pulsante1_Click()
    E_Righe
    End Sub
    
    Sub E_Righe()
      Dim E_oTbl As ListObject
      ' Dim x As Long
      Set E_oTbl = ActiveSheet.ListObjects("Excel_Tab")
        With E_oTbl
        .ListRows.Add (.ListRows.Count + 1), True
      End With
      Set E_oTbl = Nothing
    End Sub
                                       ' per testare inserimento doppioni da foglio1.:
    Private Sub Worksheet_Change(ByVal Target As Range)
        If Not Intersect(Target, Range("D:D")) Is Nothing Then
            Nome = Target.Offset(0, 0).Value 
            If Application.WorksheetFunction.CountIf(Range("D:D"), Nome) > 1 Then
     ' qui ricevo errore di run-time 13 - tipo non corrispondente 
                MsgBox "Titolo già inserito", , "EXCEL"
                Target.Offset(0, 0) = ""
            End If
        End If
    End Sub



  • di Vecchio Frac data: 25/11/2013 23:18:47

    Bè, mi sembrava importante specificare il tipo di "Nome".
    Comunque ho testato la tua routine, funziona perfettamente, attenzione solo a specificare Application.EnableEvents prima di modificare il target per evitare ricorsioni.
    Inoltre nota che Target.Offset(0,0) non ha senso, è sufficiente Target.
    Per l'estetica e per l'utente, ho riposizionato la selezione sulla cella annullata casomai venisse individuato un doppione.
    Hai ancora problemi col codice?

     
    Option Explicit
    
    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim nome As String
        If Not Intersect(Target, Range("D:D")) Is Nothing Then
            nome = Target
            If Application.CountIf(Range("D:D"), nome) > 1 Then
                Application.EnableEvents = False
                MsgBox "Titolo già inserito", , "EXCEL"
                Target = ""
                Application.EnableEvents = True
                Target.Select
            End If
        End If
    End Sub






  • di Perry (utente non iscritto) data: 28/11/2013 15:49:17

    Mi da errore quando aggiungo una riga

    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim nome As String
    If Not Intersect(Target, Range("D:D")) Is Nothing Then

    nome = Target '<---- errore run time 13 - tipo non corrispondente

    If Application.CountIf(Range("D:D"), nome) > 1 Then
    Application.EnableEvents = False
    MsgBox "Titolo già inserito", , "EXCEL"
    Target = ""
    Application.EnableEvents = True
    Target.Select
    End If
    End If
    End Sub

    Allego il mio progetto per verifica; Il test sui doppioni funziona, ma quando aggiungo una riga (vedi pulsante) va in errore
    ancora grazie per la pazienza.



  • di scossa data: 28/11/2013 16:01:13

    Dim nome As String
    .....
    nome = Target '<---- errore run time 13 - tipo non corrispondente


    nome è una variabile String, tu vuoi assegnarle un Range ....

    quindi, o:
    nome = Target.Text

    oppure (risparmiando la variabile "nome"):
    If Application.CountIf(Range("D:D"), Target.Text) > 1 Then



  • di Perry (utente non iscritto) data: 28/11/2013 17:15:06

    Funziona, ma devo testare che il campo non sia vuoto, quando aggiungo una riga dal pulsante " Aggiungi Riga" associato alla Sub E_Righe() è vuoto.
    Vedi file allegato.
    Grazoe 1k



  • di Vecchio Frac data: 28/11/2013 21:16:43

    cit. "nome è una variabile String, tu vuoi assegnarle un Range .... "
    ---> Dissento da scossa, non è quello il motivo ^_^
    Quando il compilatore arriva a
    nome = Target
    non fa altro che prelevare il valore dell'oggetto Target, e assegnarlo a "nome". Il cast implicito lo converte in stringa.
    Se avessi voluto riferirmi a Target come a un range avrei usato Set che si utilizza per assegnare ad una variabile un oggetto.
    Naturalmente prelevare il valore text dal Target elimina ogni dubbio.
    Mi sembra davvero strano che Perry abbia un errore di tipo non corrispondente su un codice che invece funziona benissimo.
    E' molto più probabile che l'errore venga sollevato da questa operazione: seleziono più celle e inserisco un valore multiplo (con Ctrl-Invio). Oppure premo Canc. Allora sì: si scatena l'errore proprio su "nome = Target" ed è logico che sia così, perchè il Target è multicella mentre "nome" è - poverina - una semplice variabile stringa ^_^
    Sono invece d'accordo sul risparmiare anche la variabile "nome".





  • di Perry (utente non iscritto) data: 30/11/2013 18:08:34

    Vorrei ringraziare tutti coloro che hanno dato suggerimenti al mio progetto, ma purtroppo non ho risolto i problemi che si sono evidenziati.
    Provo a sintetizzare ed evidenziare lo scopo del progetto, nato dalla volontà di tenere traccia di tutte le discussioni che si succedono in questo bellissimo sito.

    Regolarmente memorizzo il link (una volta) di ogni singola discussione sul foglio "Elenco titoli EXCEL".
    Su vostro suggerimento ho tramutato l' insieme di celle a cui avevo attribuito il nome "EXCEL_Campi" in una Tabella che ho chiamato Excel.Tab"
    Avendo la necessità di aggiungere in automatico delle righe, ho applicato al pulsante1 "Aggiungi riga" la seguente macro (in modulo1):

    Option Explicit
    Dim x As Long

    Sub Pulsante1_Click()
    E_Righe
    End Sub

    Sub E_Righe()
    Dim E_oTbl As ListObject
    ' Dim x As Long
    Set E_oTbl = ActiveSheet.ListObjects("Excel_Tab")

    With E_oTbl
    ' x = E_oTbl.ListRows.Count
    ' .ListRows.Add (x)
    .ListRows.Add (.ListRows.Count + 1), True
    End With

    Set E_oTbl = Nothing
    End Sub

    Questa macro mi aggiunge una riga in fondo ma NON COPIA le FORMULE e la FORMATTAZIONE delle righe precedenti o quantomeno dell' ultima riga inserita.

    Ho poi aggiunto la seguente macro per controllare eventuali doppioni in Foglio1:
    Option Explicit
    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim nome As String
    If Not Intersect(Target, Range("D:D")) Is Nothing Then
    nome = Target.Text
    If Application.CountIf(Range("D:D"), nome) > 1 Then
    Application.EnableEvents = False
    MsgBox "Titolo già inserito", , "EXCEL"
    Target = ""
    Application.EnableEvents = True
    Target.Select
    End If
    End If
    End Sub

    Che fa il suo dovere e mi controlla di non aver inserito in una riga vuota un link già esistente.

    Ora nascono i problemi :
    1- quando aggiungo una riga esce il msgbox - titolo già inserito (è vuoto !)
    2 - se copio la formattazione (pennello) dell' ultima riga valida mi da errore run-time "94" - utilizzo non valido di Null

    Spero di aver evidenziato correttamente i miei problemi e conto sulla vostra pazienza e disponibilità invitandovi a testare il progetto che ho allegato.
    In ogni caso vi ringrazio e confermo la mia stima a tutti voi
    Grazie



  • di Vecchio Frac data: 30/11/2013 18:15:35

    cit. "lo scopo del progetto, nato dalla volontà di tenere traccia di tutte le discussioni che si succedono in questo bellissimo sito"
    ---> Cioè stai riprogettando uno storico? ^_^

    Prova ad allegare uno stralcio del file così vediamo com'è esattamente lo scenario.
    E aggiungo, lodevole iniziativa :)





  • di Perry (utente non iscritto) data: 30/11/2013 18:27:12

    Ho allegato il progetto completo
    Grazie



  • di Vecchio Frac data: 30/11/2013 18:47:28

    Bel lavoro, complimenti.
    Però devo avviare il mio Excel 2010 in macchina virtuale altrimenti ottengo solo una serie di errori :)





  • di Vecchio Frac data: 30/11/2013 18:56:53

    Ma quando fai "aggiungi riga", si limita a inserire una riga vuota?
    Le formule le devi aggiungere a mano?
    Dovresti fargliele inserire in automatico.
    In questo modo avresti la nuova riga col numero progressivo già compilato e, nella Worksheet_Change del foglio relativo agli inserimenti di Excel (ma uguale ragionamento per quello al foglio Word: poi si penserà ad ottimizzare visto che il codice è identico e potrai spostare la routine in nu evento di Workbook piuttosto che di Worksheet) potresti evitare l'errore di Titolo già inserito semplicemente testando se la prima cella contiene qualcosa:
    If Not Intersect(Target, Range("D:D")) Is Nothing And Target(1) <> "" Then

    Questo per il problema n° 1, ma risolveresti di colpo anche il problema n° 2 ^_^





  • di Vecchio Frac data: 30/11/2013 19:03:53

    Guarda, ti risolvo io il problema della copia della formula soprastante.
    Tu fai anche la modifica della sub che intercetta l'evento Change del foglio come detto prima.
     
    Sub E_Righe()
      Dim E_oTbl As ListObject
      Set E_oTbl = ActiveSheet.ListObjects("Excel_Tab")
      
      With E_oTbl
        .ListRows.Add alwaysinsert:=True
        .ListRows(.ListRows.Count).Range(1).Offset(-1).Copy .ListRows(.ListRows.Count).Range(1)    '<<<<< nuova riga
      End With
      
      Set E_oTbl = Nothing
    End Sub






  • di Perry (utente non iscritto) data: 30/11/2013 20:15:13

    Perfetto,
    ora mi copia le formule della riga precedente, ma non mi copia il formato delle varie celle (es. altezza riga 15)

    ho fatto la modifica della sub che intercetta l'evento Change del foglio come detto prima ma continuava a darmi errore l' ho modificata ed ora funziona :

    If Not Intersect(Target, Range("D:D")) Is Nothing And Target(1) <> "" Then
    ' nome = Target.Text <-- vecchia versione
    nome = Target(1).Text <-- nuova versione

    ma non mi è chiaro il perchè, anche il range "D:D" non mi piace perchè se per sbaglio inserisco un link fuori della tabella (sempre in colonna D) mi fa lo stesso il controllo di univocità che vorrei fosse limitato solo alle righe della tabella.

    Dici di spostare l' evento da Worksheet a Workbook però perderei la personalizzazione EXCEL o WORD ??
    Grazie, grazie 1k



  • di Vecchio Frac data: 30/11/2013 20:30:51

    Sono perplesso su quel Target(1).Text, che significa solo "la prima cella del range del target", anche perchè le mie prove riguardano l'uso del solo "Target" senza .text ^_^ ma verificherò.
    Il copia formato lo fai col Copy e poi col PasteSpecial su riga separata. Tra poco vedo se ci rimetto le mani.
    Per il range dell'intera colonna basta forse solo verificare di essere all'interno della tabella.
    Gestirei tutto a livello di Workbook senza temere la personalizzazione del foglio perchè l'evento sa a quale foglio ti stai riferendo in quel momento.





  • di Vecchio Frac data: 01/12/2013 12:00:34

    Allora, intanto aggiustiamo la copia dei formati.
    Sostituisci le sub E_Righe e W_Righe con quelle che seguono.
    Adesso mi occupo di limitare il range di inserimento alla porzione di D:D che contiene la tabella.
    Poi penseremo a come sfruttare gli eventi di Workbook per non duplicare il codice (E_Righe e W_Righe non servono distinte, se ne potrà fare una sola passando come parametro la tabella su cui intervenire).
     
    Sub E_Righe()
    Dim E_oTbl As ListObject
      Set E_oTbl = ActiveSheet.ListObjects("Excel_Tab")
      
      Application.EnableEvents = False
      With E_oTbl
        .ListRows.Add alwaysinsert:=True
        With .ListRows(.ListRows.Count)
            .Range(1).Offset(-1).Copy .Range(1)
            .Range.Offset(-1).Copy
            .Range.PasteSpecial xlPasteFormats
        End With
      End With
      Application.EnableEvents = True
      Application.CutCopyMode = False
      Set E_oTbl = Nothing
    End Sub
     
    
    Sub W_Righe()
      Dim W_oTbl As ListObject
      Application.EnableEvents = False
      With W_oTbl
        .ListRows.Add alwaysinsert:=True
        With .ListRows(.ListRows.Count)
            .Range(1).Offset(-1).Copy .Range(1)
            .Range.Offset(-1).Copy
            .Range.PasteSpecial xlPasteFormats
        End With
      End With
      Application.EnableEvents = True
      Application.CutCopyMode = False
      Set W_oTbl = Nothing
    End Sub
    






  • di Vecchio Frac data: 01/12/2013 12:07:48

    Vabbè, era più facile di quel che pensassi ^_^
    Modifica l'If dell'evento Worksheet_Change come segue.
    La stessa modifica va fatta nel foglio per Word, solo che invece di [excel_tab] metterai [word_tab] (così tu stesso hai chiamato le tabelle ^_^)
     
    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim nome As String
        If Not Intersect(Target, [excel_tab].Columns(4)) Is Nothing And Target(1) <> "" Then
    ....
    end sub






  • di Perry (utente non iscritto) data: 02/12/2013 18:13:10

    Perfetto funziona tutto, mi rimane un unico dubbio sul range "D:D".:

    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim nome As String
    If Not Intersect(Target, [excel_tab].Columns(4)) Is Nothing And Target(1) <> "" Then
    nome = Target(1).Text

    If Application.CountIf(Range("D:D"), nome) > 1 Then ' <--- ? perchè rimane questo Range

    Application.EnableEvents = False
    MsgBox "Titolo già inserito", , "EXCEL"
    Target = ""
    Application.EnableEvents = True
    Target.Select
    End If
    End If
    End Sub

    Spero di non abusare troppo della vostra disponibilità in ogno caso grazie 1+2K




  • di Vecchio Frac data: 02/12/2013 19:52:27

    Bè sì, hai ragione a evidenziare l'incongruenza nel senso che dovrebbe essere
    If Application.CountIf([excel_tab].Columns(4), nome) > 1 Then
    visto che poco sopra abbiamo deciso di testare soltanto la zona della colonna D relativa a Excel_Tab.
    All'atto pratico non cambia niente.
    All'atto teorico invece direi che è un filino più performante e, dal punto di vista del programma, anche più logicamente corretto.

    Fai la stessa modifica anche all'evento del foglio relativo a Word... se riesco ti getto le basi epr rivedere l'impianto del programma in modo da non duplicare i codici degli eventi _Change.





  • di Perry (utente non iscritto) data: 03/12/2013 18:14:17

    OK, ho allineato tutto e funziona perfettamente, resto in attesa della revisione del progetto (la curiosità è femmina).
    Grazie 1+2+3K



  • di Vecchio Frac data: 03/12/2013 21:59:24

    Il tuo progetto mi piace e, pur con la difficoltà che ho a far girare bene questa macchina virtuale, ci darò un'occhiata volentieri asap.





  • di Perry (utente non iscritto) data: 15/12/2013 19:23:32

    Attendo con curiosità.

    Nel frattempo potresti spiegarmi la differenza che esiste nello strutturare le celle in una tabella piuttosto che limitarsi ad un insieme con NOME ?

    Come puoi vedere ero partito con quest' ultimo metodo e mi è stato suggerito di trasformare l' insieme in una tabella (Grograman), cosa che ho fatto ma non ho capito il perchè.

    Grazie per le presiose risposte.
    Perry