мне необходимо автоматизировать действия на сайте. одним из этих действий является выгрузка файла с диска на сайт через форму на сайте. вот сайт вот как я делаю:
Код
Function GetIE() As Object
For Each GetIE In CreateObject("Shell.Application").Windows() 'Loop to find
If (Not GetIE Is Nothing) And GetIE.name = "Internet Explorer" Then Exit For 'Found!
Next GetIE
If GetIE Is Nothing Then Exit Function
GetIE.Visible = True 'Make IE window visible
End Function
Sub upload()
Dim myShell As Object
Dim ie As Object
Set ie = GetIE
ie.Navigate ("https://xmltools.corefiling.com/miniSchemaValidate/index.jsp")
Do: DoEvents: Loop While ie.Busy Or ie.ReadyState <> 4
Set ElementCol = .getElementsByTagName("input")
For Each btnInput In ElementCol
If btnInput.name = "schema" Then
'btnInput.Click
btnInput.Value = "C:\Users\file.txt"
Exit For
End If
Next btnInput
.....
end sub
проблема в строке
Код
btnInput.Value = "C:\Users\file.txt"
она не присваивае т значение. т.е. не работает.
если я вручную тыкаю в форму и выбираю файл в открывшемся диалоговом окне, то после этого debug.print btnInput.Value показывает путь к файлу, но вот программно присвоить путь не получается.
Sub PostFile()
Const boundary As String = "----WebKitFormBoundaryOtMjnxAQ1j0yc83f"
Dim file_path As String
Dim file_name As String
Dim post_data As String
Dim post_url As String
Dim body() As Byte
post_url = "https://xmltools.corefiling.com/miniSchemaValidate/Controller"
file_path = "D:\example2.xml"
file_name = Mid(file_path, InStrRev(file_path, "\") + 1)
post_data = File_Reader(file_path)
body = Prepare_Body(post_data, boundary, file_name)
With CreateObject("Microsoft.XMLHTTP")
.Open "POST", post_url, 0
.SetRequestHeader "Content-Type", "multipart/form-data; boundary=" & boundary
.Send (body)
result = .ResponseText
Debug.Print result
End With
End Sub
Private Function Prepare_Body(ByVal post_data As String, ByVal boundary As String, ByVal file_name As String) As Byte()
post_data = "--" & boundary & vbCrLf & _
"Content-Disposition: form-data; name=""uploadfile""; filename=""" & file_name & """" & vbCrLf & _
"Content-Type: application/octet-stream" & vbCrLf & vbCrLf & post_data & vbCrLf & "--" & boundary & "--"
Prepare_Body = StrConv(post_data, vbFromUnicode)
End Function
Private Function File_Reader(ByVal file_path As String)
With CreateObject("ADODB.Stream")
.Charset = "utf-8"
.Open
.LoadFromFile (file_path)
File_Reader = .ReadText()
End With
End Function
это очень круто! но мне бы всё таки нужно найти способ без post. в заданном мной вопросе адрес указан для примера. В действительности мне нужно работать с другим сайтом, и там работа происходит с участием ключа рутокен. Я в Вашем-то примере не понимаю как формируется текст post запроса..а с нужным мне сайтом и подавно закопаюсь.
с нажатием кнопок, заполнением форм и извлечением сведений из форм проблем нет. затык только с этой загрузкой файла (
Максим, я вас понял. К сожалению, под этот сайт даже onchange не срабатывает. Других методов не знаю.
Есть такие грабли))
Код
#If VBA7 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems
#Else
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds as Long) 'For 32 Bit Systems
#End If
'''
With CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
.SetText "D:\example.xml"
.PutInClipboard
End With
btnInput.Focus
Application.SendKeys " "
Sleep (250)
Application.SendKeys "^v"
Sleep (100)
Application.SendKeys "{ENTER}"
хороший вариант, но элемент на страничке не допускает ручной ввод пути. Курсор ставится, но ввести ничего не даёт. подозреваю что есть какое-то свойство (что-нибудь типа Editable) которое можно предварительно поставить в значение true. Пока перебираю все свойства с похожим смыслом.
Максим написал: но элемент на страничке не допускает ручной ввод пути. Курсор ставится, но ввести ничего не даёт.
что-то вы делаете не то. В моем последнем посте код копирует путь в буфер обмена, далее на страничке фокус падает на элемент кнопки, потом посылается системе активацию пробела, тем самим вызвав клик по кнопке и открытие окошка выбора файла, далее посылается команда CTRL + V - вставка текста(скопированного) в поле выбора файла и после этого энтер. Таким образом мы как бы эмулируем выбор файла. Если будете пошагово проверять - не выйдет, IE активно должно быть в момент срабатывания SendKeys.
у меня элемент вот так выглядит (на прикреплённой картинке) и после выбора файла руками (без макроса) в строке, куда указывает стрелочка, прописывается путь к файлу, но корректировать это поле форма не даёт.
я сначала решил что текст из буфера обмена вставляется в это поле. И, кстати, способа активировать это поле для ввода в него текста я не нашёл. а не работало, т.к. окно IE было свёрнуто. развернул его таким кодом:
Код
Declare Function ShowWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
ShowWindow IE.hwnd, 3 ' SW_SHOWMAXIMIZED = 3
без WinAPI не получилось развернуть.
не очень, конечно изящно внешне получилось, НО работает!! это главное