2010-04-11 10 views
7

mam nazwany zakres jak na poniższym obejmującego A2: D3Jak wstawić nowy wiersz do zakresu i kopiowania formuł

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

jestem wstawić nowy wiersz przy użyciu VBA do kopiowania zakresie formuły nie wartości.

Wszelkie wskazówki/linki bardzo doceniane.

+0

Skopiuj skąd –

+0

Czy ma znaczenie, z którego wiersza kopiujesz? Zakładam, że jeśli wstawimy wiersz bezpośrednio przed sumą i użyjemy formuł z powyższego wiersza, będzie to działało dla ciebie? –

Odpowiedz

11

To powinno wystarczyć:

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) nie rozszerza nazwanego zakresu o jeden wiersz (AFAIK to jedyny sposób, aby zrobić to bezwarunkowo poprzez wstawienie wiersza (w przeciwieństwie do jawnie modyfikującej definicji zakresu) i aby to zrobić * po * określonym rzędzie # jest przez wiersz # 1 do Count - 1) i 2) tylko przesuwa Kolumny w zakresie 'target' w dół o jeden wiersz. W wielu (i prawdopodobnie większości) przypadkach kolumny po prawej i/lub lewej stronie zakresu "celu" również muszą zostać przesunięte w dół. 3) 'target.Rows (rowNr) .Copy target.Rows (rowNr + 1)' nie kopiuje formatów, które są często, jeśli nie są zwykle pożądane. Zobacz moją alternatywną odpowiedź poniżej. – Tom

4

Jeśli zaczniesz nagrywać makro i faktycznie wykonasz zadanie, wygeneruje ono kod. Po zakończeniu zatrzymaj nagrywanie makra, a otrzymasz kod, który możesz następnie poprawić.

1

musiałem toczyć rozwiązanie, które pracowały jak sposób kwerendy połączenie danych rozszerza się na wynikach asortyment o wzorach opcjonalnie Wypełniając po prawej stronie. Być może spóźnisz się o nagrodę dwa lata, ale z przyjemnością się tym podzielę!

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

tę odpowiedź rozwiązuje następujące problemy z 3 aktualnie akceptuje Odpowiedź @marg Cytat 13 kwietnia '10 w 9:43.

  1. target.Rows(rowNr + 1).Insert: 1.1. nie rozszerza zakresu nazwanego o jeden wiersz (AFAIK to jedyny sposób, aby zrobić to bezwarunkowo poprzez wstawienie wiersza (w przeciwieństwie do jawnie modyfikującej definicję zakresu) i uczynienie tego po określonym numerze wiersza za pośrednictwem wiersza nr 1 do zliczenia - 1) i 1.2) tylko przesuwa Kolumny w zakresie o target w dół o jeden wiersz. W wielu (i prawdopodobnie większości) przypadkach kolumny po prawej i/lub lewej stronie zakresu target również muszą zostać przesunięte w dół.

  2. target.Rows(rowNr).Copy target.Rows(rowNr + 1) nie kopiuje Formaty, które są często, jeśli nie są zwykle również pożądane.

Private Sub InsertNewRowInRange (_ TargetRange jako zakres, _ Opcjonalnie InsertAfterRowNumber As Integer = -1, _ Opcjonalnie InsertEntireSheetRow Jak Boolean)

' -- 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

Użyłem tego kodu. Spełnia moje wymagania i działa jak urok.Ale nagle zacząłem dostawać ** błąd czasu pracy "1004". Metoda wstawiania klasy Range nie powiodła się. ** w wierszu 'TargetRange.Rows (InsertAfterRowNumber + 1) .Insert'. To działało przez kilka dni, a potem nagle zacząłem dostawać ten błąd. – JDoshi

+0

@JDoshi: Właśnie to zobaczyłem. Jaka jest aktualna definicja TargetRange i jakie są parametry, które zdałeś? – Tom

+0

W rzeczywistości mój arkusz był chroniony, co powoduje, że problem. Odbicie to zrobiło dla mnie. Dzięki za wspaniałe rozwiązanie. – JDoshi

0

Oto kolejny budynek rozwiązanie na odpowiedź od @Tomek. Nie korzysta z "Wybór" i istnieje możliwość wstawienia wielu wierszy.

' 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 
Powiązane problemy