Если есть такая возможность - помогите, пожалуйста, в решении задачи. В книге 3 листа: 1) Данные - массив с информацией (для примера взята стартовая яндекса). 2) Ключевые слова 3) Структура
Нужно, чтобы макрос искал в первом столбце листа "Данные" сверху вниз ключевые слова и переносил информацию на лист "Структура", в ту его часть, где указано соответствующее ключевое слово. Т.е., к примеру, макрос ищет слово "Новости", находит его в "Данных", копирует все что указано между "Новости" и следующим ключевым словом ("Карты"), далее ищет слово "Новости" на листе "Структура" и вставляет скопированный текст под слово "Новости", дальше копирует инфу между "Карты" и "Недвижимость" - под слово "Карты" и т.д.
- на листе "Данные" поиск производится только по первому столбцу - совпадением считается полное соответствие (т.е. если ищем слово "новости", то ячейка с предложением "горячие новости" - не будет считаться совпадением, макрос должен искать именно "новости") - когда слово найдено копируются строки между двумя ключевыми словами, но не вся строка, а первые 5 столбцов - на листе "Стуктура" поиск производится только по первой строке
И сразу еще один вопрос. Можно ли сделать так, чтобы при повторении ключевого слова макрос воспринимал это как новый запрос. Т.е. если на листе "Ключевые слова" перечислено "Новости", "Карты", "Новости", на листе "Структура" в первой строке так же прописано "Новости", "Карты", "Новости", макрос бы в начале скопировал массив между "Новости" и "Карты" и вставил в первый интервал "Новости", потом скопировал между "Карты" и следующим по тексту "Новости" в интервал для "Карты", а дальше искал между вторым словом "Новости" и следующим ключевым словом, и вставлял во второй интервал "Новости" ? Т.е. каждый последующий поиск ключевого слова должен начинаться не с начала столбца, а с той строки на которой остановился найдя предыдущее слово.
Добрый день, уважаемые гуру VBA!
Если есть такая возможность - помогите, пожалуйста, в решении задачи. В книге 3 листа: 1) Данные - массив с информацией (для примера взята стартовая яндекса). 2) Ключевые слова 3) Структура
Нужно, чтобы макрос искал в первом столбце листа "Данные" сверху вниз ключевые слова и переносил информацию на лист "Структура", в ту его часть, где указано соответствующее ключевое слово. Т.е., к примеру, макрос ищет слово "Новости", находит его в "Данных", копирует все что указано между "Новости" и следующим ключевым словом ("Карты"), далее ищет слово "Новости" на листе "Структура" и вставляет скопированный текст под слово "Новости", дальше копирует инфу между "Карты" и "Недвижимость" - под слово "Карты" и т.д.
- на листе "Данные" поиск производится только по первому столбцу - совпадением считается полное соответствие (т.е. если ищем слово "новости", то ячейка с предложением "горячие новости" - не будет считаться совпадением, макрос должен искать именно "новости") - когда слово найдено копируются строки между двумя ключевыми словами, но не вся строка, а первые 5 столбцов - на листе "Стуктура" поиск производится только по первой строке
И сразу еще один вопрос. Можно ли сделать так, чтобы при повторении ключевого слова макрос воспринимал это как новый запрос. Т.е. если на листе "Ключевые слова" перечислено "Новости", "Карты", "Новости", на листе "Структура" в первой строке так же прописано "Новости", "Карты", "Новости", макрос бы в начале скопировал массив между "Новости" и "Карты" и вставил в первый интервал "Новости", потом скопировал между "Карты" и следующим по тексту "Новости" в интервал для "Карты", а дальше искал между вторым словом "Новости" и следующим ключевым словом, и вставлял во второй интервал "Новости" ? Т.е. каждый последующий поиск ключевого слова должен начинаться не с начала столбца, а с той строки на которой остановился найдя предыдущее слово.ArkaIIIa
1). Как я понимаю, на листе "Структура" у тебя показан конечный результат? 2). Ключевые слова всегда есть на листе Данные и строго в том же порядке? 3). После последнего ключевого слова поиск заканчивается в последней заполненной строке Данных столбца А? 4). В твоём примере в Структуре под словом "Недвижимость" последняя строка: "Работа", но до слова "Расписания" в Данных ещё есть строки "Такси", "Телепрограмма" и т.д. Значит ли это, что переносимые данные заканчиваются там, где появляется пустая ячейка?
ArkaIIIa, привет.
1). Как я понимаю, на листе "Структура" у тебя показан конечный результат? 2). Ключевые слова всегда есть на листе Данные и строго в том же порядке? 3). После последнего ключевого слова поиск заканчивается в последней заполненной строке Данных столбца А? 4). В твоём примере в Структуре под словом "Недвижимость" последняя строка: "Работа", но до слова "Расписания" в Данных ещё есть строки "Такси", "Телепрограмма" и т.д. Значит ли это, что переносимые данные заканчиваются там, где появляется пустая ячейка?Rioran
Роман, Москва, voronov_rv@mail.ru Яндекс-Деньги: 41001312674279
Rioran, привет! 1) Да 2) Не всегда. Порядок всегда тот же. К примеру в порядке "Новости", "Карты", "Недвижимость", слово "Карты" может выпасть (его не будет в "Данных"), тогда поиск идет по следующему слову - "Недвижимость". 3) Да 4) Нет, это моя ошибка в составлении примера. Должно переноситься все до "Расписания".
Rioran, привет! 1) Да 2) Не всегда. Порядок всегда тот же. К примеру в порядке "Новости", "Карты", "Недвижимость", слово "Карты" может выпасть (его не будет в "Данных"), тогда поиск идет по следующему слову - "Недвижимость". 3) Да 4) Нет, это моя ошибка в составлении примера. Должно переноситься все до "Расписания".ArkaIIIa
Сообщение отредактировал ArkaIIIa - Четверг, 02.10.2014, 11:38
Sub qq() Dim arr, arr1, arr2 Dim i&, j&, k&, sCol& arr = Sheets("Ключевые слова").Range("A1").CurrentRegion.Value ReDim Preserve arr(1 To UBound(arr), 1 To 3)
With Sheets("Данные") arr1 = .Range(.Cells(1, "A"), .Cells(.Rows.Count, "A").End(xlUp)).Value End With For i = j + 1 To UBound(arr) If j = 0 Then j = j + 1 For j = j To UBound(arr1) If arr1(j, 1) = arr(i, 1) Then arr(i, 2) = j If i > 1 Then arr(i - 1, 3) = j Exit For End If Next Next arr(i - 1, 3) = UBound(arr1) + 1 With Sheets("Структура")
On Error Resume Next For i = 1 To UBound(arr) ReDim arr2(1 To arr(i, 3) - arr(i, 2) + 1, 1 To 1) k = 1 For j = arr(i, 2) + 1 To arr(i, 3) If Len(arr1(j, 1)) Then arr2(k, 1) = arr1(j, 1) k = k + 1 End If Next sCol = .Rows(1).Find(What:=arr(i, 1), LookAt:=xlWhole).Column .Cells(.Rows.Count, sCol).End(xlUp).Offset(1).Resize(UBound(arr2) - 1) = arr2 Next End With
End Sub
[/vba]
Примерно так [vba]
Код
Sub qq() Dim arr, arr1, arr2 Dim i&, j&, k&, sCol& arr = Sheets("Ключевые слова").Range("A1").CurrentRegion.Value ReDim Preserve arr(1 To UBound(arr), 1 To 3)
With Sheets("Данные") arr1 = .Range(.Cells(1, "A"), .Cells(.Rows.Count, "A").End(xlUp)).Value End With For i = j + 1 To UBound(arr) If j = 0 Then j = j + 1 For j = j To UBound(arr1) If arr1(j, 1) = arr(i, 1) Then arr(i, 2) = j If i > 1 Then arr(i - 1, 3) = j Exit For End If Next Next arr(i - 1, 3) = UBound(arr1) + 1 With Sheets("Структура")
On Error Resume Next For i = 1 To UBound(arr) ReDim arr2(1 To arr(i, 3) - arr(i, 2) + 1, 1 To 1) k = 1 For j = arr(i, 2) + 1 To arr(i, 3) If Len(arr1(j, 1)) Then arr2(k, 1) = arr1(j, 1) k = k + 1 End If Next sCol = .Rows(1).Find(What:=arr(i, 1), LookAt:=xlWhole).Column .Cells(.Rows.Count, sCol).End(xlUp).Offset(1).Resize(UBound(arr2) - 1) = arr2 Next End With
RAN Примерно да, но в Вашем варианте макрос не переносит инфу в "Карты" и "Недвижимость", а так же в "Расписание" переносит начиная со следующей заполненной строки, а нужно просто - со следующей строки, даже если она пустая (т.к. ячейки правее - содержат информацию).
RAN Примерно да, но в Вашем варианте макрос не переносит инфу в "Карты" и "Недвижимость", а так же в "Расписание" переносит начиная со следующей заполненной строки, а нужно просто - со следующей строки, даже если она пустая (т.к. ячейки правее - содержат информацию).ArkaIIIa
Sub qq() Dim arr, arr1, arr2 Dim i&, j&, k&, sCol&, kk& arr = Sheets("Ключевые слова").Range("A1").CurrentRegion.Value ReDim Preserve arr(1 To UBound(arr), 1 To 3)
With Sheets("Данные") sCol = .Cells.Find("*", , , , 2, xlPrevious).Column arr1 = .Range(.Cells(1, sCol), .Cells(.Rows.Count, "A").End(xlUp)).Value End With For i = j + 1 To UBound(arr) If j = 0 Then j = j + 1 For j = j To UBound(arr1) If arr1(j, 1) = arr(i, 1) Then arr(i, 2) = j If i > 1 Then arr(i - 1, 3) = j Exit For End If Next Next arr(i - 1, 3) = UBound(arr1) + 1 With Sheets("Структура")
On Error Resume Next For i = 1 To UBound(arr) ReDim arr2(1 To arr(i, 3) - arr(i, 2) + 1, 1 To UBound(arr1, 2)) k = 1 For j = arr(i, 2) + 1 To arr(i, 3) For kk = 1 To UBound(arr1, 2) arr2(k, kk) = arr1(j, kk) Next k = k + 1 Next sCol = .Rows(1).Find(What:=arr(i, 1), LookAt:=xlWhole).Column .Cells(.Rows.Count, sCol).End(xlUp).Offset(1).Resize(UBound(arr2) - 2, UBound(arr2, 2)) = arr2 Next End With
End Sub
[/vba]
С мусором [vba]
Код
Sub qq() Dim arr, arr1, arr2 Dim i&, j&, k&, sCol&, kk& arr = Sheets("Ключевые слова").Range("A1").CurrentRegion.Value ReDim Preserve arr(1 To UBound(arr), 1 To 3)
With Sheets("Данные") sCol = .Cells.Find("*", , , , 2, xlPrevious).Column arr1 = .Range(.Cells(1, sCol), .Cells(.Rows.Count, "A").End(xlUp)).Value End With For i = j + 1 To UBound(arr) If j = 0 Then j = j + 1 For j = j To UBound(arr1) If arr1(j, 1) = arr(i, 1) Then arr(i, 2) = j If i > 1 Then arr(i - 1, 3) = j Exit For End If Next Next arr(i - 1, 3) = UBound(arr1) + 1 With Sheets("Структура")
On Error Resume Next For i = 1 To UBound(arr) ReDim arr2(1 To arr(i, 3) - arr(i, 2) + 1, 1 To UBound(arr1, 2)) k = 1 For j = arr(i, 2) + 1 To arr(i, 3) For kk = 1 To UBound(arr1, 2) arr2(k, kk) = arr1(j, kk) Next k = k + 1 Next sCol = .Rows(1).Find(What:=arr(i, 1), LookAt:=xlWhole).Column .Cells(.Rows.Count, sCol).End(xlUp).Offset(1).Resize(UBound(arr2) - 2, UBound(arr2, 2)) = arr2 Next End With
И сразу еще один вопрос. Можно ли сделать так, чтобы при повторении ключевого слова макрос воспринимал это как новый запрос. Т.е. если на листе "Ключевые слова" перечислено "Новости", "Карты", "Новости", на листе "Структура" в первой строке так же прописано "Новости", "Карты", "Новости", макрос бы в начале скопировал массив между "Новости" и "Карты" и вставил в первый интервал "Новости", потом скопировал между "Карты" и следующим по тексту "Новости" в интервал для "Карты", а дальше искал между вторым словом "Новости" и следующим ключевым словом, и вставлял во второй интервал "Новости" ? Т.е. каждый последующий поиск ключевого слова должен начинаться не с начала столбца, а с той строки на которой остановился найдя предыдущее слово.
Прикрепил пример. Добавился еще один "Расписания".
RAN Здорово! То, что нужно! Огромное спасибо!!! А вот эту часть можно реализовать?
И сразу еще один вопрос. Можно ли сделать так, чтобы при повторении ключевого слова макрос воспринимал это как новый запрос. Т.е. если на листе "Ключевые слова" перечислено "Новости", "Карты", "Новости", на листе "Структура" в первой строке так же прописано "Новости", "Карты", "Новости", макрос бы в начале скопировал массив между "Новости" и "Карты" и вставил в первый интервал "Новости", потом скопировал между "Карты" и следующим по тексту "Новости" в интервал для "Карты", а дальше искал между вторым словом "Новости" и следующим ключевым словом, и вставлял во второй интервал "Новости" ? Т.е. каждый последующий поиск ключевого слова должен начинаться не с начала столбца, а с той строки на которой остановился найдя предыдущее слово.
Прикрепил пример. Добавился еще один "Расписания".ArkaIIIa
ArkaIIIa, в моём макросе дополнительный запрос реализован. Кнопка с примером во вложении. Пример выкладываю старый, но подставить данные можешь и из нового.
UPD: Проверил макрос на твоём новом примере. Вроде работает, жду твоего вердикта.
[vba]
Код
Sub Rio_Awesome_Data_Eliciter()
'Author: Roman Rioran Voronov 'Date: the 2-nd of October, 2014 'Feedback: voronov_rv@mail.ru
Dim A As Long 'To roll Data rows Dim AA As Long 'Data all rows Dim B As Long 'To roll key words rows Dim BB As Long 'Key words all rows Dim C As Long 'To roll Structure columns Dim StartX As Long 'From where to search
Dim rngX As Range Dim rngY As Range
Dim DataS As Worksheet Dim WordS As Worksheet Dim ProdS As Worksheet
Set DataS = ThisWorkbook.Worksheets("Данные") Set WordS = ThisWorkbook.Worksheets("Ключевые слова") Set ProdS = ThisWorkbook.Worksheets("Структура")
C = 1: StartX = 1 Application.ScreenUpdating = False
With DataS AA = .Cells(.Rows.Count, 1).End(xlUp).Row If AA < 2 Then Exit Sub End With
With WordS BB = .Cells(.Rows.Count, 1).End(xlUp).Row If BB < 2 Then Exit Sub End With
For B = 1 To BB Set rngX = DataS.Range("A" & StartX & ":A" & AA).Find(WordS.Cells(B, 1).Value, , , xlWhole) If Not rngX Is Nothing Then If B = BB Then ProdS.Cells(1, C).Value = WordS.Cells(B, 1).Value ProdS.Cells(2, C).Resize(AA - rngX.Row, 5).Value = rngX.Offset(1, 0).Resize(AA - rngX.Row, 5).Value Exit Sub End If For A = B + 1 To BB Set rngY = DataS.Range("A" & StartX & ":A" & AA).Find(WordS.Cells(A, 1).Value, , , xlWhole) If Not rngY Is Nothing Then ProdS.Cells(1, C).Value = WordS.Cells(B, 1).Value ProdS.Cells(2, C).Resize(rngY.Row - rngX.Row - 1, 5).Value = rngX.Offset(1, 0).Resize(rngY.Row - rngX.Row - 1, 5).Value C = C + 5: B = A - 1: StartX = rngY.Row - 1 Exit For ElseIf A = BB Then ProdS.Cells(1, C).Value = WordS.Cells(B, 1).Value ProdS.Cells(2, C).Resize(AA - rngX.Row, 5).Value = rngX.Offset(1, 0).Resize(AA - rngX.Row, 5).Value Exit Sub End If Next A End If Next B
Application.ScreenUpdating = True
End Sub
[/vba]
ArkaIIIa, в моём макросе дополнительный запрос реализован. Кнопка с примером во вложении. Пример выкладываю старый, но подставить данные можешь и из нового.
UPD: Проверил макрос на твоём новом примере. Вроде работает, жду твоего вердикта.
[vba]
Код
Sub Rio_Awesome_Data_Eliciter()
'Author: Roman Rioran Voronov 'Date: the 2-nd of October, 2014 'Feedback: voronov_rv@mail.ru
Dim A As Long 'To roll Data rows Dim AA As Long 'Data all rows Dim B As Long 'To roll key words rows Dim BB As Long 'Key words all rows Dim C As Long 'To roll Structure columns Dim StartX As Long 'From where to search
Dim rngX As Range Dim rngY As Range
Dim DataS As Worksheet Dim WordS As Worksheet Dim ProdS As Worksheet
Set DataS = ThisWorkbook.Worksheets("Данные") Set WordS = ThisWorkbook.Worksheets("Ключевые слова") Set ProdS = ThisWorkbook.Worksheets("Структура")
C = 1: StartX = 1 Application.ScreenUpdating = False
With DataS AA = .Cells(.Rows.Count, 1).End(xlUp).Row If AA < 2 Then Exit Sub End With
With WordS BB = .Cells(.Rows.Count, 1).End(xlUp).Row If BB < 2 Then Exit Sub End With
For B = 1 To BB Set rngX = DataS.Range("A" & StartX & ":A" & AA).Find(WordS.Cells(B, 1).Value, , , xlWhole) If Not rngX Is Nothing Then If B = BB Then ProdS.Cells(1, C).Value = WordS.Cells(B, 1).Value ProdS.Cells(2, C).Resize(AA - rngX.Row, 5).Value = rngX.Offset(1, 0).Resize(AA - rngX.Row, 5).Value Exit Sub End If For A = B + 1 To BB Set rngY = DataS.Range("A" & StartX & ":A" & AA).Find(WordS.Cells(A, 1).Value, , , xlWhole) If Not rngY Is Nothing Then ProdS.Cells(1, C).Value = WordS.Cells(B, 1).Value ProdS.Cells(2, C).Resize(rngY.Row - rngX.Row - 1, 5).Value = rngX.Offset(1, 0).Resize(rngY.Row - rngX.Row - 1, 5).Value C = C + 5: B = A - 1: StartX = rngY.Row - 1 Exit For ElseIf A = BB Then ProdS.Cells(1, C).Value = WordS.Cells(B, 1).Value ProdS.Cells(2, C).Resize(AA - rngX.Row, 5).Value = rngX.Offset(1, 0).Resize(AA - rngX.Row, 5).Value Exit Sub End If Next A End If Next B