Я начинаю с VBA (начал 3 дня назад), пытаясь построить макрос. Я надеюсь получить помощь с моим кодом, а также понять, что происходит с кодом в тех частях, в которых я ошибся.Цитирование через рабочие листы
Целью кода является сбор значений из ячеек в последнем столбце каждого листа и их компиляция в столбце банка на первом листе (который я создам при первом открытии рабочего листа).
Мой код очень сырой и, возможно, содержит много ошибок. Это, для большинства частей, скопировано и вставлено из источников (даже из макрорекордера). Мне удалось заставить его работать, но я надеюсь его конденсировать. Код, который работает:
Sub Test()
Dim LastCol As Long
Dim rng As Range
' Creating a bank sheet
Sheets.Add
' Returning to Page 1
Sheets("Page 1").Activate
' Use all cells on the sheet "Page 1"
Set rng = Sheets("Page 1").Cells
' Find the last column in "Page 1" and COPY
LastCol = Last(2, rng)
rng(2, LastCol).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
' Paste Selection in Sheet1
Sheets("Sheet1").Activate
Sheets("Sheet1").Paste
' Reset cursor to next blank space
Range("A" & Cells.Rows.Count).End(xlUp).Offset(1, 0).Select
' Repeat for Page 2
Sheets("Page 2").Activate
Set rng = Sheets("Page 2").Cells
LastCol = Last(2, rng)
rng(2, LastCol).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("Sheet1").Activate
Sheets("Sheet1").Paste
' Reset cursor to next blank space
Range("A" & Cells.Rows.Count).End(xlUp).Offset(1, 0).Select
' Repeat for Page 3
Sheets("Page 3").Activate
Set rng = Sheets("Page 3").Cells
LastCol = Last(2, rng)
rng(2, LastCol).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("Sheet1").Activate
Sheets("Sheet1").Paste
' Selecting range to sort
Set rng = ActiveSheet.Cells
LastCell = Last(3, rng)
With rng.Parent
.Select
.Range("A1", LastCell).Select
End With
' Sorting
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A177"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A2:A176")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Это не будет работать для книг с различным количеством рабочих листов. Я попытался сконденсировать его, найдя количество рабочих листов и прокручивая их, но я не могу больше понять из онлайн-источников. Это то, что я постарался сделать:
For N = 2 To ThisWorkbook.Worksheets.Count
' Use all cells on active sheet
ActiveWorkbook.Worksheets(N).Select
Set rng = ActiveWorkbook.Cells
' Find the last column in active sheet and COPY
LastCol = Last(2, rng)
rng(2, LastCol).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
' Paste Selection in Sheet1
Sheets("Sheet1").Activate
Sheets("Sheet1").Paste
' Reset cursor to next blank space
Range("A" & Cells.Rows.Count).End(xlUp).Offset(1, 0).Select
Next N
К сожалению, этот код не работает.
Как создать цикл для достижения того, что я смог сделать с моим первым кодом?
Соответствующие функции я использовал в моем коде, приведены ниже (любезность от Ron De Bruin):
Function Last(choice As Long, rng As Range)
'Ron de Bruin, 5 May 2008
' 1 = last row
' 2 = last column
' 3 = last cell
Dim lrw As Long
Dim lcol As Long
Select Case choice
Case 1:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
Case 2:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Case 3:
On Error Resume Next
lrw = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
On Error Resume Next
lcol = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
On Error Resume Next
Last = rng.Parent.Cells(lrw, lcol).Address(False, False)
If Err.Number > 0 Then
Last = rng.Cells(1).Address(False, False)
Err.Clear
End If
On Error GoTo 0
End Select
End Function
Function LastCol(sh As Worksheet)
On Error Resume Next
LastCol = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
End Function
Во-первых, я бы потратьте много времени на очистку всех выбранных и активированных из вашего кода. Эти заявления, как правило, затрудняют работу. Затем я бы исследовал, как полностью квалифицировать ссылки на диапазон. Это позволит убедиться, что ваш код выполняется там, где вы хотите. Проблема с кем-то, кто решает эту конкретную проблему для вас, - это вы вернетесь сюда, когда у вас возникнет другая проблема. Лучше понять свой код, чтобы вы могли исправить/изменить его по дороге. – sous2817
спасибо @ sous2817. Я старался изо всех сил, прежде чем задавать этот вопрос, консультируя книги и форумы. Надеюсь, вы поможете мне понять, где я ошибся. – zaczx
Как было сказано выше, выбор и активация замедляют работу и затрудняют ее чтение. Тем не менее, одна из проблем - это «Установить rng = ActiveWorkbook.Cells». Измените его на 'Set rng = ActiveSheet.Cells'. –