В общем хочу автоматизировать загрузку на сайт: пост запросом не получаеться, уже все перепробовал, с помощью ИЕ- по проще намного, но тут встала проблема - нужно аплоадить картинки, а их фиг укажешь...
нашел 2 процедурки Upload_Set_Filename и Upload_Click_Open - но они не работают, может кто сталкивался?
Скрытый текст
Код
Public Sub Upload_Set_Filename(sFilePathName As String)
' 'Populate the 'File name:' edit window in the Choose File to Upload dialogue with the specified folder and/or filename.
'
'
' 'The Choose File to Upload has the following child window hierarchy:
'
' ' #32770 Choose File to Upload Static Look &in:
'ComboBox N / A
'Static N/A
'ToolbarWindow32 N / A
'ToolbarWindow32 N / A
'ListBox N / A
'SHELLDLL_DefView N/A 1376604 SysListView32 FolderView
'Static File &name:
'ComboBoxEx32 N/A 8520100 ComboBox N/A 1245594 Edit N/A
'Static Files of &type:
'ComboBox N / A
'Button Open as &read-only
'Button &Open
'Button Cancel
'Button &Help
'ScrollBar N / A
Dim hWnd As Long
Dim timeout As Date
'MsgBox ""
'Debug.Print "Save_As_Set_Filename " & folder
'Find the Window, waiting a maximum of 10 seconds for it to appear
timeout = Now + TimeValue("00:00:10")
Do
hWnd = FindWindow("#32770", "Выбор выкладываемого файла") 'Choose File to Upload
DoEvents
Sleep 200
Loop Until hWnd Or Now > timeout
If hWnd Then
SetForegroundWindow (hWnd)
'Find the child ComboBoxEx32 window
hWnd = FindWindowEx(hWnd, 0, "ComboBoxEx32", vbNullString)
'Debug.Print " ComboBoxEx32 "; Hex(hWnd)
End If
If hWnd Then
'Find the child ComboBox window
hWnd = FindWindowEx(hWnd, 0, "ComboBox", "")
'Debug.Print " ComboBox "; Hex(hWnd)
End If
If hWnd Then
SetForegroundWindow (hWnd)
'Find the child Edit window
hWnd = FindWindowEx(hWnd, 0, "Edit", "")
'Debug.Print " Edit "; Hex(hWnd)
End If
If hWnd Then
'Populate the Edit window with the full file name
' Sleep 200
SendMessageByString hWnd, WM_SETTEXT, Len(sFilePathName), sFilePathName
End If
End Sub
Public Sub Upload_Click_Open(Optional cmb As String)
Dim hWnd As Long
Dim timeout As Date
'Debug.Print "File_Download_Click_Save"
'Find the File Download window, waiting a maximum of 30 seconds for it to appear
timeout = Now + TimeValue("00:00:10")
Do
hWnd = FindWindow("#32770", "Выбор выкладываемого файла")
DoEvents
Sleep 200
Loop Until hWnd Or Now > timeout
'Debug.Print " File Download window "; Hex(hWnd)
If hWnd Then
'Find the child Open button
hWnd = FindWindowEx(hWnd, 0, "Button", "&Открыть")
'Debug.Print " Save button "; Hex(hWnd)
End If
If hWnd Then
'Click the Open button
SetForegroundWindow (hWnd)
Sleep 600 'this sleep is required and 600 miiliseconds seems to be the minimum that works
SendMessage hWnd, BM_CLICK, 0, 0
End If
End Sub
Есть еще вариант через джава скрипт, я даже на сайте его нашел когда запрос ПОСТ разбирал, но ка к с ним справиться тоже не понимаю
Скрытый текст
Код
.Document.parentWindow.execScript "document.all.DLIUploader1.UnselectAll;", "jscript"
.Document.parentWindow.execScript "if(document.all.DLIUploader1.FileCount>199) document.all.DLIUploader1.SelectFile(1);", "jscript" 'online repository accept 200 files at one time per data record
.Document.parentWindow.execScript "document.all.DLIUploader1.RemoveSelectedFiles();", "jscript"
.Document.parentWindow.execScript "document.all.DLIUploader1.UploadFile(" & sFile & ")", "jscript"
Во вложении класс и пример работы с ним! Очень много времени трачу именно на загрузку страниц и т.д. сейчас активно читаю MSDN и забугорные форму и как это реализуется на других языках, cURL и т.д. ищу альтернативу особенно ИНДУССКОМУ IE (ой как они его любят же). В общем случае мы используем один из этих объектов и получаем ответы от сервера так:
Код
'Dim XMLHttp As Object: Set XMLHttp = CreateObject("Microsoft.XMLHTTP")
'Dim XMLHttp As Object: Set XMLHttp = CreateObject("WinHttp.WinHttpRequest.5.1")
'Dim XMLHttp As Object: Set XMLHttp = CreateObject("MSXML2.ServerXMLHTTP")
'Dim XMLHttp As Object: Set XMLHttp = CreateObject("MSXML2.XMLHttp") '
'Dim XMLHttp As Object: Set XMLHttp = New WinHttpRequest
XMLHttp.Open "GET", "site.com", False 'OR "POST" type and True for redirect
'XMLHttp.SetRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
'XMLHttp.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
'XMLHttp.SetRequestHeader "Cache-Control", "no-store, no-cache"
'XMLHttp.SetRequestHeader "Pragma", "no-cache"
'XMLHttp.Send StrConv("title=Title&cat=Cat&post=PostText&pas=tipapass", vbFromUnicode)
XMLHttp.Send '"title=Title&cat=Cat&post=PostText&pas=tipapass" << тут дольше всего висит
Debug.Print XMLHttp.ResponseText
Set XMLHttp = Nothing
Если кто сталкивался или знает XMLHttp.Send действительно отправляет и ждет ответа или может только отправить и не ждать или он и так только отправляет какие еще есть варианты?
По сути в общем смысле идея следующая: 1)сделать или массив или несколько объектов через рекурсию, любого из перечисленных выше или может даже IE 2)создали, отправили сайт на загрузку, проверили загрузился или нет 1 раз, если нет: 2.1)создали, отправили сайт на загрузку, проверили загрузился или нет ПЕРВЫЙ САЙТ, потом наш, если нет: 2.n)создали, отправили сайт на загрузку, проверили загрузился или нет ПЕРВЫЙ САЙТ, если да - забрали данные, убили обьект, проверили следующий, до n
Реально ли так сделать? - пока еще думаю на счет реализации и преимущества в скорости. Пока по сравнению всех выше перечисленных объектов WinHttp.WinHttpRequest.5.1 - работает дольше всех в 2.5 раза, но грузит все сайты (и китайские) с любого URL, у него есть TimeAut, если сильно долго грузится и т.д., в теории есть и
Столкнулся со следующей проблемой, хочу наконец сделать нормальное меню и таки интерфейс я сделал, а вот вызывать кнопкой на листе - не красиво, а пункотом в меню ячейки не практично, раньше делал вот так:
Код
Dim objCmdBrBtn As CommandBarButton
CommandBars("Cell").Reset
Set objCmdBrBtn = CommandBars("Cell").Controls.Add(msoControlButton, , , , True)
With objCmdBrBtn
.Caption = "Запуск обработки данных"
.DescriptionText = "Показывает форму настройки"
.enabled = True
.OnAction = "ShowFormFilter"
.TooltipText = "Запуск обработки данных"
.Visible = True
.FaceId = 2
End With
сейчас где-то в интернетах нашел другой способ, добавил, а убрать или поменять уже не могу
Код
Private Sub Workbook_Open()
Call ReadSettings
'Application.CommandBars.Reset
'Application.CommandBars("НАДСТРОЙКИ").Reset
With Application.CommandBars.Add(Name:="Menu", temporary:=True)
.Visible = True
With .Controls.Add
.OnAction = "showformsettings"
.Style = 2
.Caption = "Parser"
.FaceId = 25 ' - значок кнопки из стандартного набора офиса
End With
End With
End Sub
Как видно выше "пытался" найти как его сбросить или убрать по аналогии с первым вариантом, но все тщетно ... Хочу иметь свою кнопку в т.н. "ленте", где ее там разместить уже другой вопрос пусть хоть в надстройках, или в переименовать лучше конечно.
Автоматизация приложений, разработка ботов, парсинг сайтов, поиск информации и многое другое на языках : Delphi, C++, VBA. Информация в профиле.
Function Extract_Number_from_Text(sWord As String, Optional Metod As Integer)
'sWord = ссылка на ячейку или непосредственно текст
'Metod = 0 – числа
'Metod = 1 – текст
Dim sSymbol As String, sInsertWord As String
Dim i As Integer
If sWord = "" Then Extract_Number_from_Text = "Нет данных!": Exit Function
sInsertWord = ""
sSymbol = ""
For i = 1 To Len(sWord)
sSymbol = Mid(sWord, i, 1)
If Metod = 1 Then
If Not LCase(sSymbol) Like "*[0-9]*" Then
If (sSymbol = "," Or sSymbol = "." Or sSymbol = " ") And i > 1 Then
If Mid(sWord, i - 1, 1) Like "*[0-9]*" And Mid(sWord, i + 1, 1) Like "*[0-9]*" Then
sSymbol = ""
End If
End If
sInsertWord = sInsertWord & sSymbol
End If
Else
If LCase(sSymbol) Like "*[0-9.,;:-]*" Then
If LCase(sSymbol) Like "*[.,]*" And i > 1 Then
If Not Mid(sWord, i - 1, 1) Like "*[0-9]*" Or Not Mid(sWord, i + 1, 1) Like "*[0-9]*" Then
sSymbol = ""
End If
End If
sInsertWord = sInsertWord & sSymbol
End If
End If
Next i
Extract_Number_from_Text = sInsertWord
End Function
которая заменяет цифры и решил ее дописать: Но не знаю как написать, мне нужно заменить все символы (0-9~`!@#$%^&*()-_=+,./?\|{}[]<>;:""' ) и т.д. в ANCII это все символы с 0-64 и 91-96 и 123-126 ну и вроде-бы все как их указать в like я не знаю
Автоматизация приложений, разработка ботов, парсинг сайтов, поиск информации и многое другое на языках : Delphi, C++, VBA. Информация в профиле.
начало я давно уже проложил, я написал макрос для того чтобы он залогинился и запомнил меня (ексель). А вот дальше с пост запросом не пошло и наработки ушли (не сохранил).
Сейчас попробовал ручками с помощью IE это делать, но опять-же столкнулся с проблемами, который возможно можно решить, но я не хочу т.е. ИЕ очень много памяти жрет и достаточно долго работает по сравнению с обычной отправкой запроса на сайт. Конкретно такие вопросы у меня: Как можно отправить запрос на сайт для создания поста и что для этого нужно, у меня снифер поймал следующие данные при отправке :
Нужно ли отправлять все эти данные? и как получить post_ID точнее как он его получает, если не только я могу посты создавать? Если кто сталкивался с подобным подскажите помогите!
К Стати у этого сайта база на МУСКУЛЕ, если кто знает как это сделать с его помощью возможно подскажите.
Я сейчас играюсь со значениями, может и получится сделать.
Код
Sub PostForPostWP()
'On Error Resume Next
Set xmlhttp = CreateObject("Microsoft.XMLHTTP")
xmlhttp.Open "POST", "http://nonator.com/wp-login.php", "True"
xmlhttp.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" ' чтобы избежать кеширования
Dim POST() As Byte, PostData$
PostData = "log=test&pwd=test&rememberme=forever&wp-submit=%D0%92%D0%BE%D0%B9%D1%82%D0%B8&redirect_to=http%3A%2F%2Fnonator.com%2Fwp-admin%2F&testcookie=1"
' PostData = PostData & "log=test"
' PostData = PostData & "&pwd=test"
' PostData = PostData & "&rememberme=forever"
' PostData = PostData & "&wp-submit=Войти"
' 'PostData = PostData & "&redirect_to=http://nonator.com/wp-admin/post-new.php" 'post-new.php
' PostData = PostData & "&testcookie=1"
POST = StrConv(PostData, vbFromUnicode)
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.send (POST): DoEvents
If xmlhttp.Status <> 200 Then Exit Sub
Debug.Print xmlhttp.responseText
Set xmlhttp = Nothing
End Sub
Ага разобрался Мне нужно включить кукки и как-то или где-то их хранить.
Текущий вопрос - на форме, есть listbox в нем есть текст, который не помещается, попробовал вот так:
Код
Private Sub Inf_Click()
Inf.ControlTipText = CStr(Inf.List(Inf.ListIndex))
End Sub
да - хорошо, но выводиться только, если вывести за пределы и навести снова Поискал по нэту, принудительного выведения - нету, переноса строк - нету, даже событие нельзя отловить перед показом этого ControlTipText, чтобы его поменять перед показом, писал в процедуре движения мышки...
У меня на уме только поверх всего создавать временный Label с содержимым вместо этого ControlTipText. Кто сталкивался или знает ответ - подскажите.
В тему что-то подобное, интересное буду заносить!
Автоматизация приложений, разработка ботов, парсинг сайтов, поиск информации и многое другое на языках : Delphi, C++, VBA. Информация в профиле.
Не знаю что с этими таблицами делать, с одной вроде придумал - поделю ее пока по периодам ее (недели) и будет нормально, а вот что делать со второй там невозможно работать и фильтры разные пробовал создавать и менять столбцы\строки... Вся суть вопроса какой может быть вид у таблицы где есть 3+1 параметра (адрес, человек, действие + время) по которым можно было-бы удобно фильтрировать.
Спасибо Вам всем что помогаете мне уже не первый раз, видел тут пару тем где вы предлагали отличные преобразования таблиц в нормальный вид, может и мое посмотрите. В файле пример - таблица где мы "распространяем", честно думал очень долго как ее еще можно преобразовать, но ничего даже с использованием формы для поиска и фильтрации - очень не удобно.
Там где пример отчета - я думаю поделить на недели и на другие структуры уже начал работать с макросом, на сколько я понимаю нужно: поиск вдоль строки, если нашли объединеную область - то 1)создать новый лист, 2)первый столбик скопировать, 3) скопировать все столбики под выделенной областью и над. Это я вроде как умею, но не получается что-то определить объедененную область ее начало и конец, сейчас делю ее и заполняю одинаковыми значениями и ищу их.
Помогите с ошибкой поиска текста, иду от большего к меньшему, но почему-то выводит ошибку вместо текста, вроде-бы все учел уже...
Код
Function код(cell, cell2, cell3) As String
Dim ws2, buf As Range
Set ws2 = Sheets(2).Range("A:A")
'On Error Resume Next
'Set buf = ws2.Cells.Find(What:=cell.Value, LookIn:=xlFormulas, LookAt:=xlPart)
'Do While Not buf Is Nothing
'If (InStr(buf, cell2.Value) > 0) Or (InStr(buf, Left(cell3.Value, Len(cell3.Value) - 3)) > 0) Then
' код = buf.Offset(0, 2).Value
' exit do
'Else
' Set buf = ws2.Cells.Findnext(buf)
' код = "Не найдено"
'End If
'Wend
Set buf = ws2.Cells.Find(What:=cell.Value + "*" + cell2.Value + "*" + Left(cell3.Value, Len(cell3.Value) - 3), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False)
If buf Is Nothing Then
Set buf = ws2.Cells.Find(What:=cell.Value + "*" + Left(cell3.Value, Len(cell3.Value) - 3) + "*" + cell2.Value, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False)
If buf Is Nothing Then
Set buf = ws2.Cells.Find(What:=cell.Value + "*" + cell2.Value, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False)
If buf Is Nothing Then
Set buf = ws2.Cells.Find(What:=cell.Value + "*" + Left(cell3.Value, Len(cell3.Value) - 3), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False)
If buf Is Nothing Then
Set buf = ws2.Cells.Find(What:=cell.Value, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False)
End If
End If
End If
End If
'If Not buf Is Nothing Then
код = buf.Offset(0, 2).Value
' Else
' код = ws2.Cells.Find(What:=cell.Value, LookIn:=xlFormulas, _
' LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False).Offset(0, 2).Value
' End If
End Function
Автоматизация приложений, разработка ботов, парсинг сайтов, поиск информации и многое другое на языках : Delphi, C++, VBA. Информация в профиле.
Вот то что нашел в интернете и немного переделал под себя: 1) функция поиска слов и замены их, учитывает только англ буквы
Код
Function RowLingvo(txt As String) As String
Dim i As Integer, str As String, str2 As String, m As String
For i = 1 To Len(txt) ' пробегаем всю фразу по буквам
m = Mid(txt, i, 1) ' берем очередную букву
If m >= "A" And m <= "z" Then ' проверяем ее на кириллицу
str2 = "" ' если кирилица то обнуляем слово
Do ' запускаем цикл для определения очередного слова
str2 = str2 & m 'приклеиваем к слову очередную буку
i = i + 1 'накручиваем счетчик
m = Mid(txt, i, 1) 'берем очередную букву
Loop While m >= "A" And m <= "z" And i <= Len(txt) ' повторять пока слово не закончилось и не закончилась фраза
i = i - 1 ' сбрасываем счетчик на 1
If IsError(Application.VLookup(str2, Range("lingvo"), 2, 0)) Then ' проверяем слово на наличие в словаре
str = str & str2 ' если слова нет, то не переводим
Else
str = str & Application.VLookup(str2, Range("lingvo"), 2, 0) ' переводим текущее слово
End If
Else
str = str & m ' если символ не кириллица, то оставляем его без изминений
End If
Next i ' следующая буква
RowLingvo = str ' возвращаем перевод
End Function
2) Перевод текста с помощью гугла, понравился именно этот вариант (есть еще вариант с нашего форума), переводит длинные описание, но не простые слова как: PINK (перевод как не странно PINK) из-за чего и начал искать другие способы (хотя только что понял что нужно просто сделать маленькие буквы)
Код
Function Translate$(ByVal TextToBeTranslated$, ByVal resultLanguageCode$, _
Optional ByVal sourceLanguageCode$ = "", Optional ByVal direction As Range)
' переводит текст TextToBeTranslated$ с языка sourceLanguageCode$
' на язык resultLanguageCode$, используя сервис переводов Google Translate
Application.Volatile True
Set ADOStream = CreateObject("ADODB.Stream")
With ADOStream
.Charset = "utf-8": .Mode = 3: .Type = 2: .Open
.WriteText TextToBeTranslated: .Flush: .Position = 0
.Type = 1: .Read 3: ByteArrayToEncode = .Read(): .Close
End With
For i = 0 To UBound(ByteArrayToEncode)
iAsc = ByteArrayToEncode(i)
Select Case iAsc ' переводим текст в кодировку, понятную Google
Case 32: sTemp$ = "+" 'space
Case 48 To 57, 65 To 90, 97 To 122: sTemp$ = Chr(ByteArrayToEncode(i))
Case Else: sTemp$ = "%" & Hex(iAsc) 'Chr(iAsc)
End Select
txt$ = txt$ & sTemp$
Next
' формируем ссылку, по которой Google выдаст нам файл с переводом
URL$ = "http://translate.google.com.ua/translate_a/t?client=json&text=" & _
txt$ & "&hl=" & resultLanguageCode$ & "&sl=" & sourceLanguageCode$
Set XMLHTTP = CreateObject("Microsoft.XMLHTTP") ' скачиваем файл
XMLHTTP.Open "GET", Replace(URL$, "\", "/"), "False": XMLHTTP.send
If XMLHTTP.statustext = "OK" Then
LocalPath$ = Environ("TMP") & "\google.txt"
With ADOStream ' перекодировка файла
.Type = 1: .Open: .Write XMLHTTP.responseBody
.SaveToFile LocalPath$, 2
.Close: .Type = 2: .Charset = "utf-8": .Open:
.LoadFromFile LocalPath$ ' загружаем данные из файла
Translate$ = .ReadText ' считываем текст файла в переменную Translate$
End With
On Error Resume Next ' вырезаем нужный текст из ответа
Translate$ = Split(Translate$, """trans"":""")(1)
Translate$ = Split(Translate$, """,""orig")(0)
Translate$ = Replace(Translate$, "quot;", Chr(39))
If direction.Value <> "" Then direction.Value = Translate$
If Translate$ = " null, " Then Translate$ = "Не переведено"
End If
Set XMLHTTP = Nothing: Set ADOStream = Nothing
End Function
3)Вариант с помощью словаря и регулярных выражений, но к сожалению не в виде функции, помогите переделать в функцию пожалуйста
Код
Sub tt()
Dim a(), b(), i&, ii&, buf$
' a = Sheets(1).[a1].CurrentRegion.Value
b = Sheets(2).[a1].CurrentRegion.Value
'простым перебором и заменой :
' For i = 1 To UBound(a)
' For ii = 1 To UBound(b)
' buf$ = a(i, 1)
' a(i, 1) = Replace(a(i, 1), b(ii, 1), b(ii, 2))
' If a(i, 1) <> buf$ Then Exit For
' Next
' Next
'с помощью словаря
With CreateObject("scripting.dictionary")
For i = 1 To UBound(b): .Item(b(i, 1)) = b(i, 2): Next
a = Sheets(1).[a1].CurrentRegion.Value
For i = 1 To UBound(a)
If .exists(a(i, 1)) Then a(i, 2) = .Item(a(i, 1))
Next
Sheets(1).[a1].CurrentRegion.Value = a
End With
End Sub
Автоматизация приложений, разработка ботов, парсинг сайтов, поиск информации и многое другое на языках : Delphi, C++, VBA. Информация в профиле.
Вытягиваю текст, но он без разделителей - т.е. подряд и цифра не ясна, в краце нужна вот эта табличка: даже не вся а нижняя часть, где кол-во отправлено и т.д. я логинюсь и нужные данные уже подставляю, но не могу получить их в нормальном виде. вот основной текст:
Код
Function WebPageText(ByVal sURL, log, pass, edrpou As String, login As Boolean) As String
On Error Resume Next
Set IE = CreateObject("InternetExplorer.Application"): ' open Internet Explorer
With IE
'.Visible = True 'видимость
.Navigate sURL ' переход
While .Busy Or (.readyState <> 4): DoEvents: Wend ' ожидание
Set ieDoc = .Document: DoEvents: DoEvents
If ieDoc.Title Like "Ошибка сертификата*" Or ieDoc.Title Like "Certificate Error*" Then
ieDoc.Links(1).Click
While IE.Busy Or (IE.readyState <> 4): DoEvents: Wend
Set ieDoc = IE.Document
End If
With ieDoc 'login
If login = True Then
Application.Wait (Now + TimeValue("0:00:01"))
.getElementsByName("mylogin")(0).Value = log
.getElementsByName("mypass")(0).Value = pass
.getElementsByName("savepass")(0).Click
'.getElementsByName("login")(0).Click
'.getElementsByValue("submit")(0).Click
.forms(0).submit
While IE.Busy Or (IE.readyState <> 4): DoEvents: Wend
End If
.getElementsByName("group1")(0).Click
.getElementsByName("edrpou")(0).Value = edrpou
'.getElementsByName("im1")(0).Click
.forms(0).submit
While IE.Busy Or (IE.readyState <> 4): DoEvents: Wend
WebPageText = .body.innerText ' тянем
End With
'Application.Wait (Now + TimeValue("0:00:13"))
.Quit: Set IE = Nothing ' закрываем
End With
End Function