Копирование строк по условию из существующего набора данных в отдельную таблицу с помощью кода VBA Excel. Определение числа строк в исходной таблице.
Условие задачи
Есть исходная таблица (набор данных) со списком файлов, расположенных в двух папках. Необходимо строки таблицы, содержащие слово «Изображения», скопировать в новую таблицу, расположенную ниже исходного набора данных, через одну пустую строку. В результате должно получиться, как на изображении ниже:
Решение задачи
Код VBA Excel для копирования строк исходного набора данных по условию в отдельную таблицу:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Sub KopirovaniyeStrok() Dim s As String, n As Long, m As Long, i As Long ‘Задаем условие поиска s = «Изображения» ‘Определяем номер последней строки исходной таблицы n = Range(«A2»).CurrentRegion.Rows.Count ‘Задаем номер первой строки новой таблицы m = n + 2 For i = 2 To n ‘Проверяем условие If Cells(i, 1) = s Then ‘Копируем строку, удовлетворяющую условию, в новую таблицу Cells(i, 1).Resize(1, 3).Copy Cells(m, 1) m = m + 1 End If Next End Sub |
При желании, можно добавить в эту процедуру еще одну переменную и автоматическое определение количества столбцов:
Dim c As Long c = Range(«A2»).CurrentRegion.Columns.Count |
Тогда выражение копирования примет следующий вид:
Cells(i, 1).Resize(1, c).Copy Cells(m, 1) |
somebox Пользователь Сообщений: 64 |
#1 06.06.2019 19:35:03 Знаю, что тема не новая, но никак не могу решить проблему. Есть код:
Нужно, чтобы по условию введенному в поле окна, открывающегося по нажатию кнопки, программа копировала значение определенных ячеек со второго листа на первый. Причем не ячейки с самим значением, а соседние. То есть делала выборку. Вроде ничего сложного, но почему-то у меня ничего не выходит. Программа даже не ругается, просто молчит. Прикрепленные файлы
|
||
skais675 Пользователь Сообщений: 2177 |
#2 06.06.2019 20:02:23 Для начала это неверно. Вам проще описать что нужно, так как из кода не совсем понятно.
Изменено: skais675 — 06.06.2019 20:04:14 Мой канал |
||
somebox Пользователь Сообщений: 64 |
|
skais675 Пользователь Сообщений: 2177 |
Я уже сказал, опишите задачу, потому как догадываться нет желания. |
somebox Пользователь Сообщений: 64 |
Так я ж написал. Нужно, чтобы программа отобрала значения из первых двух столбцов таблицы со второго листа по условию, находящемуся в третьем столбце. После составила из них новую таблицу на первом листе. Например, я указываю в открывшемся окне слово «Англия», и программа копирует все значения из таблицы, касаемо Англии. |
skais675 Пользователь Сообщений: 2177 |
#6 06.06.2019 20:15:00 Ну ну. Теперь найдите — сколько отличий?
Изменено: skais675 — 06.06.2019 20:16:38 Мой канал |
||
somebox Пользователь Сообщений: 64 |
#7 06.06.2019 20:27:13 А почему не работал предыдущий Range? И
должен быть таким сложным, с таким количеством вложений (и Cells, и Rows.Count, и End)? Я пытаюсь понять, как я должны был сам до такой конструкции додуматься. Изменено: somebox — 06.06.2019 20:28:02 |
||
skais675 Пользователь Сообщений: 2177 |
somebox
Наберитесь терпения и изучите тему определения последней ячейки. Ну соответственно диапазона. Методик несколько — каждая имеет свои нюансы. |
somebox Пользователь Сообщений: 64 |
Да вроде уже читал все эти инструкции, но посмотрю еще. Видимо, что-то упустил. За код спасибо. Работает. |
somebox Пользователь Сообщений: 64 |
#10 06.06.2019 21:22:01 Хотя нет. Работает, да не так. Поторопился я. Данные на первый лист вставляются, но почему-то в ячейки с такими же адресами, что и у ячеек на втором листе. То есть во втором у меня Лондон и Манчестер находятся в А2, А3 и на первый лист они добавляются в А2, А3. Хотя писал
Предполагалось, что будет создаваться новая таблица из избранных значений, а они просто копируются «как есть». Все. Нашел ошибку. Надо было i = i + 1 поставить в блок If. Изменено: somebox — 06.06.2019 21:46:39 |
||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
Option Explicit ' Обязательное объявление переменных Option Compare Text ' отсутствие чувствительности к регистру при сравнении символов Sub Raspredelenie_po_listam() Const FirstRow& = 7 ' Константа - первая строка данных ниже шапки на всех листах Dim i&, j&, LastRow&, LastRowTarget&, ShName, Sh_Target As Worksheet, Prefix$, FormulaRC$, A Application.ScreenUpdating = False ' Временное отключение обновления экрана в Excel For Each ShName In Array("Лист2", "Лист3", "Лист4") ' Цикл по 3 листам с результатами для очистки старых данных With Sheets(ShName) ' Работа с объектом Sheet через символ "." LastRowTarget = .Cells(.Rows.Count, "Z").End(xlUp).Row ' Определение последней заполненной строки по столбцу Z If LastRowTarget < FirstRow Then LastRowTarget = FirstRow ' последняя заполненная строка не должна быть меньше FirstRow (=7) .Rows(FirstRow & ":" & LastRowTarget).Clear ' Удаление строк со старыми данными при новом распределении End With Next ShName With Лист1 ' Работа с объектом Лист1 (программное имя объекта) через символ "." LastRow = .Cells(.Rows.Count, "Z").End(xlUp).Row ' Определение последней заполненной строки по столбцу Z Prefix = "=" & Лист1.Name & "!R" ' Первая часть ссылочных формул A = .Range(.Cells(1, 1), .Cells(LastRow, 15)).Value ' Формируем массив для проверки условий For i = FirstRow To LastRow ' Цикл по строкам анализируемого листа A(i, 8) = Trim(A(i, 8)) ' удаление пробелов спереди и сзади в элементах 8-го столбца массива A(i, 15) = Trim(A(i, 15)) If A(i, 8) = "ЗБС" Or A(i, 8) = "ВНС" Then ' Комплекс условий 1 Set Sh_Target = Лист2 ' Объектная ссылка на лист цель. ElseIf (A(i, 8) = "Конс" Or A(i, 8) = "Раск") And A(i, 15) = "Я" Then ' Комплекс условий 2 Set Sh_Target = Лист3 ' Объектная ссылка на лист цель. Else ' если не выполняется ни 1-ый ни 2-ой комлекс условий Set Sh_Target = Лист4 ' Объектная ссылка на лист цель. End If .Range(.Cells(i, 1), .Cells(i, "AU")).Copy ' копирование i-той строки (по AU,для последующей вставки форматов) FormulaRC = Prefix & Format(i) & "C" ' 2-я часть ссылочной формулы With Sh_Target ' Работа с объектом листом-целью, куда копируем форматы, через символ "." LastRowTarget = .Cells(.Rows.Count, "Z").End(xlUp).Row + 1 ' Определение последней пустой строки по столбцу Z If LastRowTarget < FirstRow Then LastRowTarget = FirstRow .Cells(LastRowTarget, 1).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False ' вставка скопированных форматов .Rows(LastRowTarget).RowHeight = Лист1.Rows(i).RowHeight ' Выравнивание высоты строки по исходной .Range(.Cells(LastRowTarget, 1), .Cells(LastRowTarget, "AU")).FormulaR1C1 = FormulaRC ' заполнение целевого диапазона ссылочными формулами End With Next i End With Set Sh_Target = Nothing ' Очистка памяти от объектных ссылок End Sub |
Копирование, с листа на лист (по нескольким условиям) |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
I have two sheets. One has the complete data and the other is based on the filter applied on the first sheet.
Name of the data sheet : Data
Name of the filtered Sheet : Hoky
I am just taking a small portion of data for simplicity. MY objective is to copy the data from Data Sheet, based on the filter. I have a macro which somehow works but its hard-coded and is a recorded macro.
My problems are:
- The number of rows is different everytime. (manual effort)
- Columns are not in order.
Sub TESTTHIS()
'
' TESTTHIS Macro
'
'FILTER
Range("F2").Select
Selection.AutoFilter
ActiveSheet.Range("$B$2:$F$12").AutoFilter Field:=5, Criteria1:="hockey"
'Data Selection and Copy
Range("C3").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("Hockey").Select
Range("E3").Select
ActiveSheet.Paste
Sheets("Data").Select
Range("D3").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Hockey").Select
Range("D3").Select
ActiveSheet.Paste
Sheets("Data").Select
Range("E3").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Hockey").Select
Range("C3").Select
ActiveSheet.Paste
End Sub
ashleedawg
20k8 gold badges73 silver badges104 bronze badges
asked Aug 24, 2016 at 11:21
Best way of doing it
Below code is to copy the visible data in DBExtract sheet, and paste it into duplicateRecords sheet, with only filtered values. Range selected by me is the maximum range that can be occupied by my data. You can change it as per your need.
Sub selectVisibleRange()
Dim DbExtract, DuplicateRecords As Worksheet
Set DbExtract = ThisWorkbook.Sheets("Export Worksheet")
Set DuplicateRecords = ThisWorkbook.Sheets("DuplicateRecords")
DbExtract.Range("A1:BF9999").SpecialCells(xlCellTypeVisible).Copy
DuplicateRecords.Cells(1, 1).PasteSpecial
End Sub
answered Aug 22, 2017 at 1:46
Arpan SainiArpan Saini
4,3541 gold badge38 silver badges50 bronze badges
1
I suggest you do it a different way.
In the following code I set as a Range
the column with the sports name F and loop through each cell of it, check if it is «hockey» and if yes I insert the values in the other sheet one by one, by using Offset.
I do not think it is very complicated and even if you are just learning VBA, you should probably be able to understand every step. Please let me know if you need some clarification
Sub TestThat()
'Declare the variables
Dim DataSh As Worksheet
Dim HokySh As Worksheet
Dim SportsRange As Range
Dim rCell As Range
Dim i As Long
'Set the variables
Set DataSh = ThisWorkbook.Sheets("Data")
Set HokySh = ThisWorkbook.Sheets("Hoky")
Set SportsRange = DataSh.Range(DataSh.Cells(3, 6), DataSh.Cells(Rows.Count, 6).End(xlUp))
'I went from the cell row3/column6 (or F3) and go down until the last non empty cell
i = 2
For Each rCell In SportsRange 'loop through each cell in the range
If rCell = "hockey" Then 'check if the cell is equal to "hockey"
i = i + 1 'Row number (+1 everytime I found another "hockey")
HokySh.Cells(i, 2) = i - 2 'S No.
HokySh.Cells(i, 3) = rCell.Offset(0, -1) 'School
HokySh.Cells(i, 4) = rCell.Offset(0, -2) 'Background
HokySh.Cells(i, 5) = rCell.Offset(0, -3) 'Age
End If
Next rCell
End Sub
answered Aug 24, 2016 at 14:30
RémiRémi
3723 silver badges8 bronze badges
2
When i need to copy data from filtered table i use range.SpecialCells(xlCellTypeVisible).copy. Where the range is range of all data (without a filter).
Example:
Sub copy()
'source worksheet
dim ws as Worksheet
set ws = Application.Worksheets("Data")' set you source worksheet here
dim data_end_row_number as Integer
data_end_row_number = ws.Range("B3").End(XlDown).Row.Number
'enable filter
ws.Range("B2:F2").AutoFilter Field:=2, Criteria1:="hockey", VisibleDropDown:=True
ws.Range("B3:F" & data_end_row_number).SpecialCells(xlCellTypeVisible).Copy
Application.Worksheets("Hoky").Range("B3").Paste
'You have to add headers to Hoky worksheet
end sub
answered Aug 24, 2016 at 11:34
3
it needs to be .Row.count not Row.Number?
That’s what I used and it works fine
Sub TransfersToCleared()
Dim ws As Worksheet
Dim LastRow As Long
Set ws = Application.Worksheets(«Export (2)») ‘Data Source
LastRow = Range(«A» & Rows.Count).End(xlUp).Row
ws.Range(«A2:AB» & LastRow).SpecialCells(xlCellTypeVisible).Copy
answered Oct 6, 2020 at 18:09