Uploading File To Website - vba

I am still a beginner with VBA, so if you need further explanation or I am not describing my problem correctly please let me know.
I am trying to achieve the following:
Upload a file from my computer to a website (You can only try to upload if you login, so sadly I cannot share a link)
In order to achieve this I need to do three things:
1) Click the "Upload" Button
2) Insert the Filepath into the search field of the PopUp Window
3) Click the "Open" Button
The website looks like this:
The PopUp Window looks like this:
The HTML code of the upload field is the following:
<div class="button-wrapper">
<input class="design-file-input" type="file">
<a class=" button prio1" href="javascript:void(0);">Design hochladen</a>
</div>
I guess there might be two solutions two my problem, however, I am not able to realize my plans.
IDEA 1
Somehow get the filepath into the input field and the page to download it
Therefore I tried the vba following VBA codes:
objIE.document.getElementsByClassName("design-file-input")(0).Value
objIE.document.getElementsByClassName("design-file-input")(0).innerText
And then try to somehow make the website submit my entry.
IDEA 2
Click the "Design Hochladen" Button.
objIE.document.getElementsByClassName("button-wrapper")(0).Click
But then the PopUp window comes up and I don't know how to control it with VBA
I am happy to hear and try your suggestions!! If you need any further details, just let me know! Thank you so much if you can give me any advice

Directly assigning the file path to the value of that specific HTML element does not work. A while ago, I had the same issue (automatically passing a file to an upload file dialog). After a long googling session, I found following solution. Unfortunately, I could not find the link from where I took this answer. In case I come accross the website, I will share the link with you:
Dim FilePath As String
Dim FileName As String
FilePath = Environ$("temp") & "\"
FileName = "test_file_for_upload" & ".xlsx"
UploadFile DestURL, FilePath & FileName, "file" 'Usage
'******************* upload - begin
'Upload file using input type=file
Public Sub UploadFile(DestURL As String, FileName As String, _
Optional ByVal FieldName As String = "File")
Dim sFormData As String, d As String
'Boundary of fields.
'Be sure this string is Not In the source file
Const Boundary As String = "---------------------------0123456789012"
'Get source file As a string.
sFormData = GetFile(FileName)
'Build source form with file contents
d = "--" + Boundary + vbCrLf
d = d + "Content-Disposition: form-data; name=""" + FieldName + """;"
d = d + " filename=""" + FileName + """" + vbCrLf
d = d + "Content-Type: application/upload" + vbCrLf + vbCrLf
d = d + sFormData
d = d + vbCrLf + "--" + Boundary + "--" + vbCrLf
'Post the data To the destination URL
IEPostStringRequest DestURL, d, Boundary
End Sub
'sends URL encoded form data To the URL using IE
Sub IEPostStringRequest(URL As String, FormData As String, Boundary As String)
'Create InternetExplorer
Dim WebBrowser: Set WebBrowser = CreateObject("InternetExplorer.Application")
'You can uncoment Next line To see form results
WebBrowser.Visible = True
'Send the form data To URL As POST request
Dim bFormData() As Byte
ReDim bFormData(Len(FormData) - 1)
bFormData = StrConv(FormData, vbFromUnicode)
WebBrowser.navigate URL, , , bFormData, _
"Content-Type: multipart/form-data; boundary=" + Boundary + vbCrLf
Do While WebBrowser.Busy
' Sleep 100
DoEvents
Loop
'WebBrowser.Quit
End Sub
'read binary file As a string value
Function GetFile(FileName As String) As String
Dim FileContents() As Byte, FileNumber As Integer
ReDim FileContents(FileLen(FileName) - 1)
FileNumber = FreeFile
Open FileName For Binary As FileNumber
Get FileNumber, , FileContents
Close FileNumber
GetFile = StrConv(FileContents, vbUnicode)
End Function
'******************* upload - end
The third argument "file" denotes the ID of the HTML element which needs to be triggered.
Hope this solution workds for you as well

Related

File Download via shdocvw.dll with custom headers

I need to download a really large file in msaccess via a vba application.
Using the objects MSXML2.ServerXMLHTTP.6.0 and WinHttp.WinHttpRequest.5.1 result in an error stating that there is not enough storage available to complete this operation. Therefore i resorted in using the DoFileDownload method from shdocvw.dll.
What i want to do is pass an extra header (an API key) to the request sent by the function.
Here is roughly what i want to do.
Private Declare Function DoFileDownload Lib "shdocvw.dll" _
(ByVal lpszFile As String) As Long
Public Sub Download()
sDownloadFile = StrConv(<link_to_download>, vbUnicode)
'set a header before calling DoFileDownload
Call DoFileDownload(sDownloadFile)
End Sub
How do i approach this problem?
A WebRequest downloading a whole file at once stores the whole data in response.
Although there are options to chunk response, using Wget is less coding, but more options.
Private Sub DownloadFileWget()
Const PathToWget As String = "" 'if wget is not in path use "Path\To\Wget"
Dim LinkToFile As String
Dim SavePath As String
With CreateObject("WScript.Shell")
LinkToFile = "http://download.windowsupdate.com/microsoftupdate/v6/wsusscan/wsusscn2.cab" 'huge file > 500MB
SavePath = "C:\doc" 'folder to save download
.CurrentDirectory = SavePath
.Run Chr(34) & PathToWget & "wget.exe" & Chr(34) & " --header='name: value' " & Chr(34) & LinkToFile & Chr(34) & " -N", 1, True
' -N: Continue download only if the local version is outdated.
End With
End Sub

Open a file in a new instance of program

All;
I have a bit of code I've written that opens a design blueprint when I scan a bar code. It works well enough, but I'd like to open a new instance of the design software (Solidworks) and have the print display in the new instance. Right now, no matter how many Solidworks instances I have open, the print will only open in the first instance started.
The line commented out below is the line that works, just not in the right instance. The line below that is what I'd expect to work, but it returns a 'file not found' even though the path to solidworks and the print path are both correct.
Any explanation as to why this isn't working would be much appreciated as I'm obviously very new at this...and have no idea what I'm doing.
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Try
Dim barcode As String = tb_barcode.Text
Dim filename As String = tb_barcode.Text
'Add File Extension to end of path
Dim ext As String = ".SLDDRW"
'Split job number from detail number in barcode textbox
barcode = Split(tb_barcode.Text, ".")(0)
filename = Split(tb_barcode.Text, ".")(1)
'- This works, just in primary instance
'System.Diagnostics.Process.Start("G:\Fixtures\" & barcode & "\Details\" & barcode & " DET " & filename & ext)
'- This does not work
System.Diagnostics.Process.Start("'C:\Program files\Solidworks Corp\Solidwork\SLDWORKS.exe' 'G:\Fixtures\" & barcode & "\Details\" & barcode & " DET " & filename & ext + "'")
Catch
MessageBox.Show("File Not Found")
End Try
End Sub
Sorry for naive approach but shouldn't there be a comma in Process.Start between 2 arguments?
Start(String, String)
Starts a process resource by specifying the name of an application and a set of command-line arguments, and associates the resource with a new Process component. docs
Why don't you use the Application.ExecutablePath.That returns the Application's path with its full name. Then your code should be
System.Diagnostics.Process.Start(Application.Executablepath, "G:\Fixtures\" & barcode & "\Details\" & barcode & " DET " & filename & ext + "'")
Also make sure that the second string argument is a valid path.

how can a target the current user's documents folder?

So we have a system that requires users to log in and it has there own roaming profile. So in this string of code how can i target the current users document folder? (FYI excel 2010)
'WORKAROUND:
Dim PID As Double
Dim strRootPath As String
Const strExpExe = "explorer.exe"
Const strArg = " " '" /e,/root, "
'this is where i need to figure out how to target current user's documents
'// Change rootpath here
strRootPath = "C:\Data Files"
PID = Shell(strExpExe & strArg & strRootPath, 3)
the rest of the function does great... it opens file explorer i just cant figure the syntax for telling it to look for the current user.
Probably the best way would be with a function like this:
Function docsFolder() As String
docsFolder = CreateObject("WScript.Shell").SpecialFolders("MyDocuments")
End Function
There are other ways too but this one will work on any version of Windows and with user customizations.
For example, in my case, I have my documents folder on a mapped X: drive, so simply stuffing my username into a C:\ path would not work.
More Information:
Stack Overflow : Language independent way to get “My Documents” folder in VBA
Microsoft Technet : What is the path to My Documents?
MSDN : Wshell: SpecialFolders Property
I'm not sure how flexible you want this to be but you could try the following
strRootPath = "C:\Users\" + Environ("Username") + "\Documents"
Got it! thanks! for anyone that might care... The final string that made her run!
Function docsFolder() As String
docsFolder =
CreateObject("WScript.Shell").SpecialFolders("MyDocuments")
End Function
Private Sub test()
Dim PID As Double
Dim strRootPath As String
Const strExpExe = "explorer.exe"
Const strArg = " " '" /e,/root, "
'// Change rootpath here
strRootPath = "C:\Users\" + Environ("Username") + "\Documents"
PID = Shell(strExpExe & strArg & strRootPath, 3)
End Sub

Open, Launch or Show a file for the user to read or write in vb.net

It sounds very simple but I have searched and cannot seem to find a way to open a log file which the user just created from my windows form app. The file exits I just want to open it after it is created.
I have a Dim path As String = TextBox1.Text and once the user names and clicks ok on the savefiledialog I have a msgbox that says "Done" and when you hit OK I have tried this
FileOpen(FreeFile, path, OpenMode.Input) but nothing happens. I just want it to open the log and show it to the user so they can edit or save it again or anything.
This is where I got the above code.
http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.filesystem.fileopen.aspx
Searching is difficult because everyone is trying to "Open" a file and process it during runtime. I am just trying to Show a file by Launching it like someone just double clicked it.
Here is the entire Export Button click Sub. It basically writes listbox items to file.
Private Sub btnExport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExport.Click
Dim sfd As New SaveFileDialog
Dim path As String = TextBox1.Text
Dim arypath() As String = Split(TextBox1.Text, "\")
Dim pathDate As String
Dim foldername As String
foldername = arypath(arypath.Length - 1)
pathDate = Now.ToString("yyyy-MM-dd") & "_" & Now.ToString("hh;mm")
sfd.FileName = "FileScannerResults " & Chr(39) & foldername & Chr(39) & " " & pathDate
sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal)
sfd.Filter = "Text files (*.txt)|*.txt|CSV Files (*.csv)|*.csv"
sfd.ShowDialog()
path = sfd.FileName
Using SW As New IO.StreamWriter(path)
If CkbxFolder.Checked = True Then
SW.WriteLine("Folders")
For Each itm As String In ListBox1.Items
SW.WriteLine(itm)
Next
End If
If CkbxFiles.Checked = True Then
SW.WriteLine("Files")
For Each itm As String In ListBox2.Items
SW.WriteLine(itm)
Next
End If
End Using
MsgBox("Done...")
FileOpen(FreeFile, path, OpenMode.Input) 'Why can't I open a file for you...
End Sub
Do not use the old VB6 methods. They are still here for compatibility reason, the new code should use the more powerful methods in the System.IO namespace.
However, as said in comments, FileOpen don't show anything for you, just opens the file
You coud write
Using sr = new StreamReader(path)
Dim line = sr.ReadLine()
if !string.IsNullOrEmpty(line) Then
textBoxForLog.AppendText(line)
End If
End Using
or simply (if the file is not too big)
Dim myLogText = File.ReadAllText(path)
textBoxForLog.Text = myLogText
As alternative, you could ask the operating system to run the program associated with the file extension and show the file for you
Process.Start(path)
To get the same behavior as if the user double-clicked it, just use System.Diagnostics.Process, and pass the filename to it's Start method:
Process.Start(path)
This will open the file using whatever the default application is for that filename based on its extension, just like Explorer does when you double-click it.

Google Chrome command line link with named tags from a vb string

I have a series of HTTP links stored in the database the have a named tag as part of the link (e.g. http://somecompany.com/products#123332) which represents a product 123332 in a rather large page.
The above link works fine when using IE but doesn't work with Chrome. The # character gets converted to %23 and Chrome can't find the ref. Changing the %23 back to # in the browser's address field works correctly.
The link is stored in a standard VB String and I've tried replacing the # with different values via String.Replace(). There must be a proper way to encode this correctly, I just can't seem to find any references on the web that seem to work.
A simplified example of the call would be something like:
Shell(strBrowser & strLink)
where strBrowser contains all the necessary path and exe name and the strLink is a string similar to what I mentioned above. Also as mentioned it works fine with IE. How can I go about encoding this correctly?
Thanks.
The code
If oFichierAide.LienIntern = 1 Then
strLink = " " + Chr(34) + VarGlobales.EmplacementAppl + oFichierAide.LienFichier + Chr(34)
Else
strLink = " " + Chr(34) + oFichierAide.LienFichier + Chr(34)
End If
Try
regBrowserKey = My.Computer.Registry.ClassesRoot.OpenSubKey("HTTP\shell\open\command", False)
strBrowser = regBrowserKey.GetValue(Nothing).ToString().ToLower().Replace(Chr(34), "")
strBrowser = strBrowser.Substring(0, strBrowser.LastIndexOf(".exe") + 4)
Finally
If regBrowserKey IsNot Nothing Then
regBrowserKey.Close()
End If
End Try
If strBrowser.Length > 0 And strLink.Length > 1 Then
Dim strCall As String = strBrowser + strLink
Shell(strCall, AppWinStyle.NormalFocus, False)
Return True
End If
You can open any chrome window to any URL stored with a string variable via Visual Basic by doing:
Dim appData As String = GetFolderPath(SpecialFolder.ApplicationData)
Dim chromelocation = appdata + "\Local\Google\Chrome\Application\chrome.exe"
process.start(chromelocation + strLink)
Chrome should then open up and the address it goes to should be the contents of strLink.