Здравствуйте. Необходимо следущее: На первом листе книги в столбце А расположен список URL. Необходимо выполнить веб-запрос по этим адресам (запрос однотипный, извлекаются определённые таблицы, а вот URL разные, вручную займёт огромное количество времени), каждый раз записывая его результаты в новый лист книги. В интернете находил решения, в которых давался некоторый однотипный адрес, вида ?id=xxxxx и xxxxx менялись, мне же нужно просто пройтись по адресам из списка. Почему каждый раз на новый лист? Потому что длина таблиц разная, возможно, возникнут проблемы если копировать в строку за предыдущей таблицей на одном листе. Вот пример кода для единичного запроса (как я понял, чтобы осуществить моё, нужно всё в цикл, который закончится на последнем адресе из столбца A; в connection= отправлять строку из A(i-го), а в destination указывать каждый раз новый лист, перед этим его создав ):
Catboyun написал: Так Вам нужен один запрос или все на одном листе? 1-й в $A$1 2-й например в $A$200 и т.д. я правильно понял?
Извините за плохое объяснение. Нужно множество запросов, каждый запрос запрос берёт адрес из столбца A и помещает результат либо на другом листе (в одном, по порядку, результат за результатом, без перезаписи), либо каждый раз на новый лист (думаю, что на одном листе придётся возится). Накидал в пейнте схему, может поможет понять.
Doober написал: Могу предложить без веб-запроса на лист
Спасибо за ваши старания. Внешне как раз то, что нужно, но к сожалению, дело в том, что та ссылка была дана для примера, веб-запрос должен быть относительно универсальным, чтобы указав номер таблицы можно было получить с нескольких разных сайтов, поддерживающих обработку веб-запросом, парсинг под каждый отдельный сайт нет смысла делать. Легче будет получить данные в более-менее табличном виде, потом уже удалить пустые строки и т.п. Вот тут добавил псевдокод (помечен звёздочками) для случая когда на один лист все таблицы, чтобы объяснить ещё. Вроде бы так должно работать, но как сделать это в подробностях на самом языке, не знаю.
Код
Sub GetNames()
Application.Run "Êíèãà1!Ìàêðîñ2"
*пока (не пустая ячейка в столбце А) делать:
k=k+1
i = НомерПоследнейЗанятойЯчейки в (ТекущаяКнига.Лист2.СтолбецА) + 1*
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;*ТекущаяКнига.Лист1.А[k]*", Destination:=*ТекущаяКнига.Лист2.А[i]*
.CommandType = 0
.Name = *ПолучитьИмяФайла(A[k])*//не знаю, нужно ли это вообще или достаточно полного url, который мы уже указали
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
* .WebTables = "2"* //тут будет номер таблицы на странице вместо .WebSelectionType = xlAllTables
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
End Sub
если хотите именно через запросы (что дОльше, чем код, предложенный Doober) - то можно, как в коде от Doober, прогнать запросы циклом... см. модуль Листа1 (и комменты там)... принцип такой... P.S. ... и убрала пустые строки... Перевложила файл (чуть что - подправите по ситуации проверку в первых 20 строках (на глаз), чтобы не искать далее - см. комменты по коду)
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Примерно додумался как сделать для случая с одним листом. Выдаёт ошибку в конце выполнения (1004), но данные добавляет (может что-то подправить надо). Сам решил постепенно делать парсер вместо этого, но вот код, может кому пригодится:
Код
Sub Макрос1()
Dim CurRow As Long
For Each link In Worksheets("Лист1").Range("A:A").Cells
With Worksheets("Лист2")
CurRow = .Cells(.Rows.Count, "B").End(xlUp).Row + 1
End With
With Worksheets("Лист2").QueryTables.Add(Connection:= _
"URL;" & link.Value, Destination:=Worksheets("Лист2").Range("$A$" & CurRow _
))
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
'.WebSelectionType = xlAllTables
.WebFormatting = xlNone
'.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = False
.WebSingleBlockTextImport = True
.WebDisableDateRecognition = True
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
Next
End Sub
FuncX написал: Сам решил постепенно делать парсер вместо этого
тогда ЗАЧЕМ было слать личное сообщение постороннему человеку? - до того, как подумали сами ... p.s. - не приветствуется чужой ход мыслей в своём почтовом ящике... вопросы ветки лучше задавать по ветке... p.p.s. там всё было откомментировано, но можно и одним модулем: (выполнять на активном листе со списком url)
в обычный модуль
Код
Sub QuerySeveral()
Dim T, Url As String, Sh As Worksheet
With Application: .ScreenUpdating = False: .DisplayAlerts = False: .EnableEvents = False: .Calculation = xlManual: End With
Set Sh = ActiveSheet
'определение диапазона с адресами
LastRow = Sh.Cells(Sh.Rows.Count, 1).End(xlUp).Row 'последняя строка
dx = Sh.Range("A1:A" & LastRow)
'цикл по массиву с адресами
For n = 1 To UBound(dx)
Url = dx(n, 1)
'добавление листа
Set Sh = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
'создание Подключения и выполнение запроса
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;" & Url, Destination:=Sh.Range("$A$1"))
.Name = "запрос"
.WebFormatting = xlWebFormattingNone
.PreserveFormatting = False
.RefreshStyle = xlInsertDeleteCells
.WebDisableDateRecognition = True
.Refresh BackgroundQuery:=False
End With
'удалить Подключение
ActiveWorkbook.Connections(1).Delete
'удалить строки (из первых 20) не содержащие хоть что-либо во 2-м (B) столбце
For rr = 20 To 1 Step -1
If Sh.Range("B" & rr).Value = "" Then Sh.Rows(rr).Delete
Next rr
Next n
With Application: .ScreenUpdating = True: .DisplayAlerts = True: .EnableEvents = True: .Calculation = xlCalculationAutomatic: End With
'окно сообщение
MsgBox "Queries Done", 64, "That's all"
End Sub
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
JeyCi, я примерно сделал, посмотрел, что результат всё же не совсем удовлетворительный выходит (до этого, когда по-одному делал, добавлял вручную, казалось, что более-менее) и решил от такого метода отказаться. А от вас ответа не ожидал бесплатного, поэтому сначала просто спросил, чтобы потом договориться.