Я не понимаю, что вы пытаетесь сделать, но я думаю, что могу дать вам несколько полезных советов.
Я не объясняю операторы, которые я использую в приведенном ниже коде. Найдите их в справке редактора Visual Basic или попробуйте поискать в Интернете «Excel VBA xxxxx». При необходимости возвращайтесь с вопросами, но чем больше вы узнаете для себя, тем быстрее будут развиваться ваши навыки.
Сначала вам нужно найти последнюю строку, содержащую данные. Изучение каждой строки вплоть до AB30000 просто пустая трата времени. Макрос Demo1
ниже демонстрирует две техники. Есть и другие методы поиска последней строки, ни один из которых не подходит для каждой ситуации. Найдите в StackOverflow фразу «[excel-vba] найти последнюю строку». Есть много актуальных вопросов и ответов, хотя первая техника, которую я использую, безусловно, самая популярная.
Общий совет: если вы можете разбить свое требование на последовательность отдельных вопросов (например, «найти последнюю строку»), вам будет проще искать ответ в StackOverflow.
Всегда добавляйте Application.ScreenUpdating = False
в начале ваших макросов, если вы собираетесь изменить рабочий лист. Без этого оператора каждый раз, когда вы скрываете строку, Excel перерисовывает экран.
Я создал некоторые тестовые данные, которые, я надеюсь, репрезентативны для ваших данных. У меня есть два листа Source
и Dest
. Source
содержит полный набор данных. Я копирую выбранные строки в Dest
.
Я использовал автоматический фильтр, который будет намного быстрее, чем ваша техника, если он даст вам эффект, который вы ищете. Играйте с автофильтром с клавиатуры. Если вы можете получить желаемый эффект, включите средство записи макросов, используйте автоматический фильтр, чтобы получить желаемый выбор, и выключите средство записи макросов. Отрегулируйте операторы средства записи макросов, чтобы удалить Selection
и заменить соответствующие операторы в Demo2
.
Секрет Demo2
заключается в Set Rng = .AutoFilter.Range.SpecialCells(xlCellTypeVisible)
, который устанавливает Rng
в видимые строки. Если вы не можете заставить автофильтр работать так, как вам хочется, и вы решили использовать свою текущую технику, чтобы сделать неинтересные строки невидимыми, оставьте это выражение, чтобы получить оставшиеся строки. Однако я думаю, что макрос Demo3
использует лучшую технику.
Option Explicit
Sub demo1()
Dim ColLast As Long
Dim Rng As Range
Dim RowLast As Long
Application.ScreenUpdating = False
With Worksheets("Source")
' This searches up from the bottom of column AB for a cell with a value.
' It is the VBA equivalent of placing the cursor at the bottom of column AB
' and clicking Ctrl+Up.
RowLast = .Cells(Rows.Count, "AB").End(xlUp).Row
Debug.Print "Last row with value in column AB: " & RowLast
' This searches for the last cell with a value.
Set Rng = .Cells.Find(What:="*", After:=.Range("A1"), SearchDirection:=xlPrevious)
If Rng Is Nothing Then
' Worksheet is empty
Else
RowLast = Rng.Row
ColLast = Rng.Column
Debug.Print "Last cell with value is: (" & RowLast & ", " & ColLast & _
") = " & Replace(Rng.Address, "$", "")
End If
End With
End Sub
Sub Demo2()
Dim Rng As Range
Dim SearchDate As String
SearchDate = "14-May-14"
Application.ScreenUpdating = False
With Sheets("Source")
.Cells.AutoFilter
.Cells.AutoFilter Field:=28, Criteria1:=SearchDate
Set Rng = .AutoFilter.Range.SpecialCells(xlCellTypeVisible)
End With
' Rng.Address has a maximum length of a little under 256 characters.
' Rng holds the addresses of all the visible rows but you cannot display
' all those addresses in an easy manner. However, this is only to give
' you an idea of what is in Rng; the Copy statement below uses the full
' set of addresses.
Debug.Print "Visible rows: " & Rng.Address
Rng.Copy Worksheets("Dest").Range("A1")
End Sub
Sub Demo3()
Dim RngToBeCopied As Range
Dim RowCrnt As Long
Dim RowLast As Long
Dim SearchDate As Long
' Excel holds dates as integers and times as fractions.
SearchDate = CLng(DateValue("20 May 2014"))
With Worksheets("Source")
RowLast = .Cells(Rows.Count, "AB").End(xlUp).Row
' Include header row in range to be copied
Set RngToBeCopied = .Rows(1)
For RowCrnt = 2 To RowLast
If .Cells(RowCrnt, "AB").Value = SearchDate Then
Set RngToBeCopied = Union(RngToBeCopied, .Rows(RowCrnt))
End If
Next
End With
Debug.Print RngToBeCopied.Address
RngToBeCopied.Copy Worksheets("Dest").Range("A1")
End Sub
person
Tony Dallimore
schedule
15.05.2014