2012-02-22 52 views
6

Mã bên dưới đang cố gắng dán phạm vi đã chọn (được chuyển thành rng) vào cuối trang tính. Nó hoạt động nếu đã có 2 hàng (A1, A2).Excel vba - xlDown

Sub copyRow(rng As Range, ws As Worksheet) 
    Dim newRange As Range 
    Set newRange = ws.Range("A1").End(xlDown).Offset(1, 0) 
    rng.Copy 
    newRange.PasteSpecial (xlPasteAll) 
End Sub 

Vì vậy, nếu A1 và A2 có mặt và nếu bạn gọi phương thức này 100 lần, nó sẽ chèn 100 hàng sau hàng. Nhưng, nếu không có hàng nào hiện diện hoặc chỉ A1, nó chỉ ghi đè A2. Tôi có thể thấy excel viết trên cùng một hàng (ghi đè)

Xuất hiện, điều gì đó liên quan đến cách xlDown tính toán nếu có ít hơn 2 hàng, không chắc chắn.

Mọi trợ giúp sẽ được đánh giá cao.

Trả lời

29

Xin lỗi nhưng tôi không đồng ý với câu trả lời của Michael.

Kết thúc (xlDown) tương đương với VBA khi nhấp vào Ctrl + Down.

Hãy thử Ctrl + Down với

  • một cột trống
  • một cột với một giá trị trong dòng 1 nhưng không có
  • giá trị khác trong hàng 1 và 2
  • giá trị trong hàng 1, 2 , 3, 7, 8, 9, 13, 14 và 15

Điều này sẽ cho bạn ý tưởng về tất cả các hàng khác nhau, Ctrl + Down có thể đưa bạn đến.

Set newRange = ws.Range("A1").End(xlDown).End(xlDown).End(xlUp).Offset(1, 0) không nhất thiết đưa bạn đến hàng đã qua sử dụng cuối cùng cộng với 1.

Tôi ngạc nhiên Set newRange = ws.Range("A1").End(xlDown).Offset(1, 0) làm việc với một cột trống. Range("A1").End(xlDown) sẽ đưa bạn đến hàng cuối cùng của trang tính sau đó .Offset(1, 0) sẽ cố gắng đưa bạn ra khỏi trang tính.

xem xét:

Dim RowLast As Long 

RowLast = ws.Cells(Rows.Count, "A").End(xlUp).Row 
  • Nếu cột A là trống rỗng, RowLast sẽ được thiết lập để 1.
  • Nếu A1 có giá trị nhưng không có tế bào khác có giá trị, RowLast sẽ được thiết lập để 1.
  • Nếu một số ô trong cột A có giá trị, RowLast sẽ được đặt thành hàng dưới cùng với một giá trị.
  • Nếu bạn có một giá trị trong hàng cuối cùng, nó sẽ bị bỏ qua.
  • Nếu bạn có một giá trị trong hai hàng cuối cùng, RowLast sẽ được đặt thành Rows.Count - 1.

Tôi giả sử bạn không có giá trị trong các hàng borrom. Nếu bạn không quan tâm nếu hàng 1 được để trống với một cột trống, thì:

RowLast = ws.Cells(Rows.Count, "A").End(xlUp).Row 
Set NewRange = ws.Cells(RowLast + 1, "A") 

nên cho kết quả mong muốn bất kể nội dung hiện tại của trang tính.

Nếu bạn quan tâm đến hàng 1 bị bỏ trống, hãy thử nghiệm với Ctrl + DownCtrl + Up sẽ cho bạn hiểu hiệu quả của các kết hợp giá trị khác nhau.

+5

+1 để giải thích rõ điều đó. Vì nó là, tôi chưa bao giờ được ủng hộ bằng cách sử dụng "ws.Range (" A1 "). End (xlDown)" để thiết lập một phạm vi. Lý do là, Nó không cho (khá dễ hiểu) phạm vi chính xác nếu có một ô trống ở giữa. :) –

+0

Tony, cảm ơn sự giúp đỡ của bạn. Nó làm việc cho tôi. Về phần đầu tiên, tại sao tôi đã làm theo cách đó, tôi đã theo dõi mục 18 http://support.microsoft.com/kb/291308. Ngạc nhiên khi thấy không có cách dễ dàng để làm điều này. cảm ơn aga. – bsr

+0

@SiddharthRout .. hoặc tệ hơn ô cuối cùng nếu hàng trống. Tìm kiếm tốt hơn nhiều, nhưng vẫn cần một thử nghiệm để đảm bảo phạm vi dữ liệu quan tâm không được để trống. ['Find' có thể dễ dàng hơn] (http://stackoverflow.com/q/4872512/641067) tùy thuộc vào những gì cần thiết – brettdj

1

Vấn đề là hàng Bù đắp trỏ đến một hàng không nằm trong phạm vi. Nhưng không có Offset, bạn kết thúc vào hàng cuối cùng của giá trị. Vì vậy, thay vì cố gắng đi xuống từ đầu, chúng ta hãy đi lên từ phía dưới.

Go End (Xuống) hai lần: Sau khi kết thúc phạm vi này, Một lần nữa để thoát khỏi phạm vi này. Sau đó, hãy kết thúc (Lên) một lần và sau đó bù đắp điều đó theo 1:

Sub copyRow(rng As Range, ws As Worksheet) 
    Dim newRange As Range 
    Set newRange = ws.Range("A1").End(xlDown).End(xlDown).End(xlUp).Offset(1, 0) 
    rng.Copy 
    newRange.PasteSpecial (xlPasteAll) 
End Sub 
+0

dường như không hoạt động đối với tôi, nó chỉ tạo mục nhập cho A2, A3 (và A3 ghi lại phần còn lại của thời gian). Tôi sẽ tạo một tệp thử nghiệm và đính kèm với câu hỏi này. Cảm ơn bạn đã giúp đỡ. – bsr