2010-04-11 10 views
7

ho un intervallo denominato come il seguente A2 che copre: D3Come inserire una nuova riga in una gamma e copiare formule

ITEM PRICE QTY SUBTOTAL 
1   10 3 30 
1   5 2 10 
      TOTAL: 40 

devo inserire una nuova riga utilizzando VBA nella gamma copia le formule non valori.

Qualsiasi consiglio/link molto apprezzato.

+0

copia da dove –

+0

Importa la riga da cui si copia? Presumo che se inseriamo la riga immediatamente prima del totale e usiamo le formule dalla riga precedente, ciò funzionerebbe per te? –

risposta

11

Questo dovrebbe farlo:

Private Sub newRow(Optional line As Integer = -1) 
Dim target As Range 
Dim cell As Range 
Dim rowNr As Integer 

    Set target = Range("A2:D3") 

    If line <> -1 Then 
     rowNr = line 
    Else 
     rowNr = target.Rows.Count 
    End If 

    target.Rows(rowNr + 1).Insert 
    target.Rows(rowNr).Copy target.Rows(rowNr + 1) 
    For Each cell In target.Rows(rowNr + 1).Cells 
     If Left(cell.Formula, 1) <> "=" Then cell.Clear 
    Next cell 
End Sub 
+0

'target.Rows (rowNr + 1) .Insert': 1) non estende l'intervallo denominato di una riga (AFAIK l'unico modo per farlo in modo implicito tramite Insert Row (rispetto alla modifica della definizione di intervallo) e per farlo * dopo * la riga specificata è tramite il numero di righe da 1 a Count - 1) e 2) sposta solo le colonne nell'intervallo di destinazione di una riga. In molti casi (e probabilmente la maggior parte), anche le colonne a destra e/o sinistra dell'intervallo "target" devono essere spostate verso il basso. 3) 'target.Rows (rowNr) .Copy target.Rows (rowNr + 1)' non copia i Formati che sono spesso, se non di solito, anche desiderati. Vedi la mia risposta alternativa qui sotto. – Tom

4

Se si avvia la registrazione di una macro e si esegue effettivamente l'operazione in mano, verrà generato automaticamente il codice. Una volta terminato, interrompi la registrazione della macro e avrai il codice necessario che potrai quindi modificare.

1

avevo bisogno di tirare un soluzione che ha funzionato come il modo in cui una query di connessione dati si espande a seguito di fascia con formule a scelta riempimento automatico fuori a destra. Forse due anni di ritardo per la taglia, ma sono felice di condividere comunque!

Public Sub RangeExpand(rangeToExpand As Range, expandAfterLine As Integer, Optional linesToInsert As Integer = 1, Optional stuffOnTheRight As Boolean = False) 
    Debug.Assert rangeToExpand.Rows.Count > 1 
    Debug.Assert expandAfterLine < rangeToExpand.Rows.Count 
    Debug.Assert expandAfterLine > 0 

    If linesToInsert = 0 Then Exit Sub 
    Debug.Assert linesToInsert > 0 

    Do 
     rangeToExpand.EntireRow(expandAfterLine + 1).Insert 
     linesToInsert = linesToInsert - 1 
    Loop Until linesToInsert <= 0 

    If stuffOnTheRight Then 
     rangeToExpand.Item(expandAfterLine, rangeToExpand.Columns.Count + 1).Select 
     Range(Selection, Selection.End(xlToRight)).Select 
     Range(rangeToExpand.Item(expandAfterLine, 1), Selection).Select 
    Else 
     Range(rangeToExpand.Item(expandAfterLine, 1), rangeToExpand.Item(expandAfterLine, rangeToExpand.Columns.Count)).Select 
    End If 
    Selection.AutoFill Destination:=Range(rangeToExpand.Item(expandAfterLine, 1), rangeToExpand.Item(rangeToExpand.Rows.Count, Selection.Columns.Count)) 
End Sub 
1

Questa risposta risolve i seguenti 3 problemi con la risposta attualmente accettata da @marg pubblicata in origine 13 aprile 10 alle 9:43.

  1. target.Rows(rowNr + 1).Insert: 1.1. non estende l'intervallo denominato di una riga (AFAIK l'unico modo per farlo in modo implicito tramite Insert Row (rispetto alla modifica della definizione di intervallo) e per farlo dopo specificato Row # è tramite il numero riga 1 per Count - 1) e 1.2) sposta solo colonne nella scala target di una riga. In molti casi (e probabilmente la maggior parte), le colonne a destra e/o sinistra dell'intervallo target devono essere anch'esse spostate verso il basso.

  2. target.Rows(rowNr).Copy target.Rows(rowNr + 1) non copia i Formati che sono spesso, se non di solito, anche desiderati.

Private Sub InsertNewRowInRange (_ TargetRange come gamma, _ opzionale InsertAfterRowNumber As Integer = -1, _ opzionale InsertEntireSheetRow come booleano = True)

' -- InsertAfterRowNumber must be 1 to TargetRange.Rows.Count - 1 for TargetRange to be extended by one Row and for there to be 
' -- Formats and Formulas to copy from (e.g. can't be 0). Default: If -1, defaults to TargetRange.Rows.Count. 
' -- Recommend dummy spacer Row at the bottom of TargetRange which, btw, would also be necessary to manually extend a Range 
' -- by one Row implicitly via Insert Row (vs. explicilty via changing Range definition). 

     If InsertAfterRowNumber = -1 Then 
      InsertAfterRowNumber = TargetRange.Rows.Count 
     End If 

     If InsertEntireSheetRow Then 
      TargetRange.Cells(InsertAfterRowNumber + 1, 1).Select 
      Selection.EntireRow.Insert 
     Else 
      TargetRange.Rows(InsertAfterRowNumber + 1).Insert 
     End If 

     TargetRange.Rows(InsertAfterRowNumber).Select 
     Selection.Copy 

     TargetRange.Rows(InsertAfterRowNumber + 1).Select 
     Selection.PasteSpecial _ 
      Paste:=xlPasteFormats, _ 
      Operation:=xlNone, _ 
      SkipBlanks:=False, _ 
      Transpose:=False 
     Selection.PasteSpecial _ 
      Paste:=xlPasteFormulas, _ 
      Operation:=xlNone, _ 
      SkipBlanks:=False, _ 
      Transpose:=False 

     Application.CutCopyMode = False 

    End Sub 
+0

Ho usato questo codice. Soddisfa le mie esigenze e ha funzionato come un fascino.Ma all'improvviso ho iniziato a ricevere ** Errore di run-time '1004'. Inserire il metodo della classe Range non riuscito. ** alla riga 'TargetRange.Rows (InsertAfterRowNumber + 1) .Insert'. Ha funzionato per alcuni giorni e poi improvvisamente ho iniziato a ricevere questo errore. – JDoshi

+0

@JDoshi: Ho appena visto questo. Qual è la definizione corrente di TargetRange e quali sono i parametri che hai passato? – Tom

+0

In realtà il mio foglio era protetto, il che mi causava il problema. Nonprotecting ha fatto il lavoro per me. Grazie comunque per l'ottima soluzione. – JDoshi

0

Ecco un altro edificio soluzione sulla risposta da @ Tom. Non usa "Selezione" ed è possibile inserire più righe.

' Appends one or more rows to a range. 
' You can choose if you want to keep formulas and if you want to insert entire sheet rows. 
Private Sub expand_range(_ 
         target_range As Range, _ 
         Optional num_rows As Integer = 1, _ 
         Optional insert_entire_sheet_row As Boolean = False, _ 
         Optional keep_formulas As Boolean = False _ 
         ) 

    Application.ScreenUpdating = False 
    On Error GoTo Cleanup 

    Dim original_cell As Range: Set original_cell = ActiveCell 
    Dim last_row As Range: Set last_row = target_range.Rows(target_range.Rows.Count) 

    ' Insert new row(s) above the last row and copy contents from last row to the new one(s) 
    IIf(insert_entire_sheet_row, last_row.Cells(1).EntireRow, last_row) _ 
     .Resize(num_rows).Insert Shift:=xlShiftDown, CopyOrigin:=xlFormatFromRightOrBelow 
    last_row.Copy 
    last_row.Offset(-num_rows).PasteSpecial 
    last_row.ClearContents 

    On Error Resume Next ' This will fail if there are no formulas and keep_formulas = True 
     If keep_formulas Then 
      With last_row.Offset(-num_rows).SpecialCells(xlCellTypeFormulas) 
       .Copy 
       .Offset(1).Resize(num_rows).PasteSpecial 
      End With 
     End If 
    On Error GoTo Cleanup 

Cleanup: 
    On Error GoTo 0 
    Application.ScreenUpdating = True 
    Application.CutCopyMode = False 
    original_cell.Select 
    If Err Then Err.Raise Err.Number, , Err.Description 
End Sub 
Problemi correlati