I am writing a small program which can download stock market information. Below is the code:
Dim DLink As String = "https://www.nseindia.com/content/historical/EQUITIES/" & strThisYear & "/" & txtMonth & "/cm" & strDate & "bhav.csv.zip"
Dim SaveDir As String = GetLocation()
Dim strFile As String = SaveDir & "\Bhavcopy\" & strDate & "bhav.csv.zip"
Dim webClient As New WebClient()
webClient.Headers(HttpRequestHeader.Accept) = "text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8"
webClient.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, Like Gecko) Chrome/26.0.1410.64 Safari/537.31")
webClient.DownloadFileAsync(New Uri(DLink), strFile)
System.Threading.Thread.Sleep(500) ' Using Thread.sleep to give time for writing. Else, the next operation fails with error 'File in Use'
Dim myFile As New FileInfo(SaveDir & "\Bhavcopy\" & strDate & "bhav.csv.zip")
Dim sizeInBytes As Long = myFile.Length
If myFile.Exists = True And myFile.Length > 0 Then ' Checking file size>0 then only unzip
System.IO.Compression.ZipFile.ExtractToDirectory(myFile.ToString, SaveDir & "\Bhavcopy\")
End If
System.Threading.Thread.Sleep(500) ' again thread.sleep used for unzipping operation..else file in use error appears
If myFile.Exists = True Then
Try
myFile.Delete()
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End If
I believe this is not efficient since I am using Thread.Sleep a few times in order to overcome 'File in Use' error. I have adjusted the sleep time from 2000ms to 500 ms but sometimes it still gives an error.
Checking the filesize > 0 is to check the fact that the download can be a holiday or weekend when there exists no data on that day.
Is there a better way to convert this code to efficiently download the zip file, check for file size > 0, then unzip it and then safely delete it?
Dim saveAs as string="C:\Documents and Settings\All Users\Documents\google.zip"
Dim theResponse As HttpWebResponse
Dim theRequest As HttpWebRequest
Try 'Checks if the file exist
theRequest = WebRequest.Create(fileUrl) 'fileUrl is your zip url
theResponse = theRequest.GetResponse
Catch ex As Exception
'could not be found on the server (network delay maybe)
Exit sub 'Exit sub or function, because if not found can't be downloaded
End Try
Dim length As Long = theResponse.ContentLength
Dim writeStream As New IO.FileStream(saveAs, IO.FileMode.Create)
Dim nRead As Integer
Do
Dim readBytes(4095) As Byte
Dim bytesread As Integer = theResponse.GetResponseStream.Read(readBytes, 0, 4096)
nRead += bytesread
If bytesread = 0 Then Exit Do
writeStream.Write(readBytes, 0, bytesread)
Loop
theResponse.GetResponseStream.Close()
writeStream.Close()
'File downloaded 100%
This code snippet too came stackoverflow but I forgot to note down the original post URL. Thanks for that code.
With this, the files are downloaded, I added code to unzip, no file lock occurs
Related
EDIT: I took PeterT's advice from comment and reprogrammed this using Dir() instead of FileSystem object. My new code, plus one alteration I made to it, scans my target directory in just about a minute. Still not ideal, but a huge improvement from where I started. If anyone knows how to further reduce the processing time, please, lmk!
The alteration is that I include the year in the Dir(filepath/filename) to search for, which should be the current year. I'm lucky in that the reference files have their dates saved as part of their filenames.
Note: Forgot to mention that the directory/reference files are saved on a network folder, which would lend to explain why accessing the file properties is taking soo long.
Here is the new code:
Public Function FindMostRecent_inYear() As String
'Debug
Dim i As Integer
i = 0
Dim StartTime As Double
Dim MinutesElapsed As String
'Remember time when macro starts
StartTime = Timer
Dim FolderName As String
Dim iFileName As String
Dim searchYear As String
searchYear = ActiveWorkbook.Sheets("CONFIG_MACRO").Range("A2").Value
Dim iDateLastMod As Date
Dim iFoundFile As String
Dim DateMax As Date
DateMax = 0
FolderName = "C:\Network\Folder\Data\"
iFileName = Dir(FolderName & "ALL_REF_FILES_START_W_THIS" & searchYear & "*.xlsx")
Do While iFileName <> ""
i = i + 1
iDateLastMod = FileDateTime(FolderName & iFileName)
If iDateLastMod > DateMax Then
iFoundFile = iFileName
DateMax = iDateLastMod
End If
iFileName = Dir()
Loop
MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss")
MsgBox "This code ran successfully in " & MinutesElapsed & " minutes", vbInformation
FindMostRecent_inYear = iFoundFile
End Function
!
My code is trying to scan a directory of excel files (~650 .xlsx files) and find the most recent modified file. It then returns the most recent modified file.
When I went to run it, it made excel non-responsive so I got to debugging, I found that it doesn't seem to be an infinite loop, rather an efficiency issue:
A few lines of code, which effectively is run ~650 times, take each anywhere from 1.4 s to 2.5 seconds each time. So at best its gonna take 30 mins for it to scan the whole directory, or longer.. waaay too long. The lines of code that are taking so long are accessing the properties of each file in the directory, specifically the file.Name, file.Type and the file.datelastmodified, such as:
iName = iFile.Name
iDateLastMod = iFile.datelastmodified
...
if iFile.Type = "Microsoft Excel Worksheet" Then
Is there anyway to check, in each iteration of 650, the file properties quickly?
I should note that I know for a fact all of the files in the directory are .xlsx files, So this I don't technically have to check, but I want to make my code failsafe, if I can. I do have to check the filename and date last modified..
Below is the code without debugging:
Public Function FindMostRecentWorkbook()
' iFile is iteration file
Dim iFile As Object
Dim DateMax As Date
Dim iFoundFile As Object
'RIDD_Folder is Raw Input Data Directory Folder
Dim RIDD_Folder As Object
Dim FileSysObj As Object
Dim strFileName As String
Set FileSysObj = CreateObject("scripting.filesystemobject")
Set RIDD_Folder = FileSysObj.GetFolder("C:\Filepath\Output\data\PROTECTED")
DateMax = 0
Dim iName As String
Dim iDateLastMod As Date
For Each iFile In RIDD_Folder.Files
iName = iFile.Name
iDateLastMod = iFile.datelastmodified
With iFile
If iFile.Type = "Microsoft Excel Worksheet" Then
If iName Like "ALL_REF_FILES_START_W_THIS" And iDateLastMod > DateMax Then
Set iFoundFile = iFile
DateMax = iDateLastMod
End If
End If
End With
Next iFile
Set FindMostRecentWorkbook = iFoundFile
End Function
Here is the code with debugging included:
Public Function FindMostRecentWorkbook()
'Debug code
'iterations
Dim c, x, i, iLike As Integer
c = 0
x = 0
i = 0
iLike = 0
'timer
Dim StartTime_Assign, StartTime_With, StartTime_IfType, StartTime_IfName As Double
Dim SecondsElapsed As Double
' iFile is iteration file
Dim iFile As Object
Dim DateMax As Date
Dim iFoundFile As Object
'RIDD_Folder is Raw Input Data Directory Folder
Dim RIDD_Folder As Object
Dim FileSysObj As Object
Dim strFileName As String
Set FileSysObj = CreateObject("scripting.filesystemobject")
Set RIDD_Folder = FileSysObj.GetFolder("C:\Filepath\Output\data\PROTECTED")
DateMax = 0
Dim iName As String
Dim iDateLastMod As Date
'Dim iFileType As Type
For Each iFile In RIDD_Folder.Files
i = i + 1
StartTime_Assign = Timer
iName = iFile.Name
iDateLastMod = iFile.datelastmodified
SecondsElapsed = Round(Timer - StartTime_Assign, 2)
Debug.Print "Time elapsed in Assign:" & SecondsElapsed
StartTime_With = Timer
With iFile
StartTime_IfType = Timer
If iFile.Type = "Microsoft Excel Worksheet" Then
StartTime_IfName = Timer
If iName Like "ALL_REF_FILES_START_W_THIS" And iDateLastMod > DateMax Then
iLike = iLike + 1
Set iFoundFile = iFile
DateMax = iDateLastMod
End If
SecondsElapsed = Round(Timer - StartTime_IfName, 2)
Debug.Print "Time elapsed in If iName Like ....:" & SecondsElapsed
End If
SecondsElapsed = Round(Timer - StartTime_IfType, 2)
Debug.Print "Time elapsed in If iFile.Type = ...:" & SecondsElapsed
End With
SecondsElapsed = Round(Timer - StartTime_With, 2)
Debug.Print "Time elapsed in With iFile:" & SecondsElapsed
If (((i / 10) <> 0) And ((i Mod 10) = 0)) Then
'breakpoint on below line
x = x + 1
End If
If (((i / 100) <> 0) And ((i Mod 100) = 0)) Then
c = c + 1
End If
Next iFile
Set FindMostRecentWorkbook = iFoundFile
End Function
When tested this debug code printed this:
Time elapsed in Assign:2.49000000953674
Time elapsed in If iName Like ....:0
Time elapsed in If iFile.Type = ...:1.5
Time elapsed in With iFile:0
Time elapsed in Assign:1.73000001907349
Time elapsed in If iName Like ....:0
Time elapsed in If iFile.Type = ...:1.6599999666214
Time elapsed in With iFile:0
Time elapsed in Assign:1.76999998092651
Time elapsed in If iName Like ....:0
Time elapsed in If iFile.Type = ...:1.51999998092651
Time elapsed in With iFile:0
Time elapsed in Assign:1.75
Time elapsed in If iName Like ....:0
Time elapsed in If iFile.Type = ...:1.5
Time elapsed in With iFile:0
...
In doing some testing where I had to read the directory for a large number of files from a network drive, I found that the windows Command Prompt dir command executed much faster than the VBA dir command or the FileSystemObject.
I also found that writing the results to a temporary file resulted in no screen flickering, whereas I had problems with screens when trying to read it directly into VBA.
In the code below, I make use of that. I have used arguments for the dir command so that it returns the desired files sorted in reverse order by date/time last written.
Also, note the use of arguments and wild cards to construct a string which includes the base folder, the starting part of the file name, and the various xls file extensions.
Since dir will return the file list properly sorted, one only needs to return the first entry in the file.
Also note that I used early-binding, but you could convert to late-binding if inconvenient.
At the end, I debug.print the full path of the most recent file.
I can't imagine this would take more than a second to locate the most recent excel file.
'Set References:
' Windows Script Host Object Model
' Microsoft Scripting Runtime
Option Explicit
Sub GetMostRecentFile()
Dim WSH As WshShell, lErrCode As Long
Dim FSO As FileSystemObject, TS As TextStream
Dim sTemp As String
Dim MostRecentFile As String
Const sRIDD_Folder_Path As String = "c:\users\ron\documents\" 'note terminal backslash
Const sFileSpec As String = "Book1*.xls*"
sTemp = Environ("Temp") & "\FileList.txt"
Set WSH = New WshShell
'note /U to enable Unicode output, as some names have char codes > 127 which are altered by redirection
lErrCode = WSH.Run("CMD /U /c dir """ & sRIDD_Folder_Path & sFileSpec & """ /TW /O-d /B > " & sTemp, xlHidden, True)
If Not lErrCode = 0 Then
MsgBox "Problem Reading Directory" & _
vbLf & "Error Code " & lErrCode
Exit Sub
End If
Set FSO = New FileSystemObject
Set TS = FSO.OpenTextFile(sTemp, ForReading, False, TristateTrue)
MostRecentFile = Split(TS.ReadAll, vbLf)(0)
TS.Close
FSO.DeleteFile sTemp
Set FSO = Nothing
Debug.Print sRIDD_Folder_Path & MostRecentFile
End Sub
I have created an excel application that listed all files in a selected directory (in Excel 2013 32 bit). Following is the script
Const path_col = 1;
Const PDF_File_Col = 2;
Sub input_file(zipFile As String)
Dim source As String
Dim FileCount As Integer
Dim FileName As String
Dim fso
Dim currentPDF As String
Dim currentTXT As String
Dim currentrow As Long
Dim first_Date_Created As String
Dim Cur_Date_Created As String
Dim CurSheet As Worksheet
Set CurSheet = ActiveSheet
source = Replace(zipFile, ".zip", "\")
FileCount = 0
currentrow = Sheets("List").Cells(4, 1).Value
FileName = Dir(source, vbReadOnly)
Set fso = CreateObject("Scripting.FileSystemObject")
Application.ScreenUpdating = False
Do While FileName <> ""
If Right(FileName, 3) = "pdf" Then
Cur_Date_Created = Format(fso.getfile(source & FileName).datecreated, "yyyy-Mmm-dd")
currentPDF = FileName
With Sheets("List")
.Cells(currentrow, path_col).Value = source
.Cells(currentrow, PDF_File_Col).Value = currentPDF
End With
' read_file source & currentTXT, currentrow
currentrow = currentrow + 1
End If
FileName = Dir()
Loop
Application.ScreenUpdating = True
Exit Sub
Issues
The script have been running daily since few years ago under Windows 7 without any issue until moving the Windows 10 a few months ago. After moving into Windows 10 we start finding it failed to list all pdf files (ie. stopped in the middle so how) intermittently without any error message populated (Note: we have not dismissed any error message before running this subroutine.)
The PDF files inside the folder was named by consecutive number and always end with ".pdf" (always in lower case). For Example: If the folder have 1200 PDF file, it will then be in arange as "PDF0001.pdf", "PDF0002.pdf" - "PDF1200.pdf". However, for some reason the sub-routine may stop running at "PDF0900.pdf"and the rest ("PDF0901.pdf - "PDF1200.pdf") will be missed from the list. However, it mayworks fine if we simply rerun the subroutine.
Note
User selected the zip file. However, it was already unzipped before
enter to this subroutine The folder only have pdf files. But usually
have more than 1000 to 5xxx and the total folder size can be upto 500MB
Could you please share me some light on what should I do regarding to this problem?
Thanks in advance!
The folder does not have only pdf files, since the folder path is extracted from a Zip one, but this is not an issue since the retrieved files by Dir are filtered according to their extension.
If you move the first Dir after source = Replace(zipFile, ".zip", "\") it will be better. Only in this way the folder path is a correct one.
Try transforming it in fileName = Dir(source & "*.pdf"). In this way, it will return only the pdf files in the directory and you can comment the line If Right(FileName, 3) = "pdf" Then, not being necessary, anymore.
Dir does not belong to FileSystemObject.
I (only) suppose that not Dir is 'guilty'. It correctly retrieves all files until the code crushes. Try using DoEvents after the line FileName = Dir(). And maybe after, too...
There are multiple Excel files on a server (or network shared storage location).
I have an Access document that needs access to these Excel files to execute a certain function.
When one of these files is open I can not execute my VBA function.
I check if someone is using the file. This is in the code below.
Is it is possible to also find out who is using a file. I would notify them to close the file(s).
Some of the things I tried (these are not all, but I can’t find a few methods anymore that I tried too):
https://chandoo.org/forum/threads/return-user-name-who-has-file-open.31447/
https://www.ozgrid.com/forum/forum/help-forums/excel-general/87346-vba-code-to-determine-who-has-file-open
In the last one they get the owner of the file and that is not the same as the one that is using the file at that moment. I tried it, but even then I sometimes get a username, but the username of the one that created the file and sometimes I get a SID (Security Identifier?).
Code to find out if the file is in use. This does not include anything to see who is using the file.
Sub TestFileOpened()
Dim filesArray As Variant
filesArray = Array("Map1.xlsx", "Map2.xlsx")
Dim fileLocation As String
fileLocation = "\\DESKTOP-NETWORK\SharedFolder\NetwerkTest\"
Dim message As String
For Each file In filesArray
If IsFileOpen(fileLocation & file) Then
message = message & vbNewLine & "File '" & file & "' is open!"
'Else
' message = message & vbNewLine & "File '" & file & "' is closed!"
End If
Next file
MsgBox message
End Sub
Function to check if the file is in use:
Function IsFileOpen(filename As String)
Dim filenum As Integer, errnum As Integer
On Error Resume Next
filenum = FreeFile()
Open filename For Input Lock Read As #filenum
Close filenum
errnum = Err
On Error GoTo 0
Select Case errnum
Case 0
IsFileOpen = False
Case 70
IsFileOpen = True
Case Else
Error errnum
End Select
End Function
Access and Excel are able to do exactly that when you try to manually open the file. Superuser post: https://superuser.com/questions/845084/how-to-get-excel-to-show-username-of-person-that-has-file-open
Ok, i am not good in writing descent macro's, so modify code to suit your own needs!
This one should give the name of the user who has currently opened an Excel-sheet:
Sub InUse(filename As String)
Dim f
Dim i
Dim x
Dim inUseBy
Dim tempfile
tempfile = Environ("TEMP") + "\tempfile" + CStr(Int(Rnd * 1000))
f = FreeFile
i = InStrRev(filename, "\")
If (i > 0) Then
filename = Mid(filename, 1, i) + "~$" + Mid(filename, 1 + i)
Else
filename = "~$" + filename
End If
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
fso.CopyFile filename, tempfile
Open tempfile For Binary Access Read As #f
Input #f, x
Close (f)
inUseBy = Mid(x, 2, Asc(x))
fso.Deletefile tempfile
Set fso = Nothing
MsgBox "InUse by: " + inUseBy, vbOKOnly, "InUse"
End Sub
Example use:
InUse("T:\Book1.xlsx")
Things to note:
This should be used when opening of a sheet fails (because of bein in-use)
I did not find any documentation about this being the 'valid' way to do this.
I do not know if this also works with shared excel sheets
I have an Excel workbook that has an active data connection to a SharePoint list on a company server. The SP list is just a listing of all the files in an SP document library at that point in time. I have a VBA subroutine that is responsible for refreshing this data connection to see what is in the library at that time and then move some info from the list (document name, document author, submission timestamp, etc.) to a different workbook.
The SharePoint site uses Active Directory credentials to authenticate and the SharePoint is also mapped as a network drive on the PC running the code. But even so, refreshing this data connection sometimes results in a credential prompt that looks just like the image at the end of my post. If I manually enter the same AD credentials again, the connection request is authenticated and the list updates in Excel.
My question is this: how can I account for this in my code? Ideally, I would like for this to trigger an email alert or something, but the thing is that the line of code (ThisWorkbook.RefreshAll) that performs the connection refresh does not run to completion until the credential prompt is dealt with, so I can't set up any handlers in the lines of code that follow. I can't have this refresh potentially resulting in code that just hangs on this line until someone happens to notice something is wrong (it is running on an unattended PC). Anyone know anything that could help deal with my issue?
Since the drive is locally mapped, you should be able to just go directly to the file and manipulate it however you need, importing it, instead of having an active data connection. It would allow you more flexibility than a more rigid data connection.
This website has a good example showing how to do what you're looking for, but the way I'm imagining would be more efficient considering the circumstances.
This really depends on how you are doing your connection and in some instances it is not possible, but you can append Username and Password to a URL to pass your credentials, such as defined here (for other languages but you get the gist):
https://www.connectionstrings.com/sharepoint/
Now the reality is, you probably aren't doing a REST connection and you might have to as discussed here: https://www.experts-exchange.com/questions/28628642/Excel-VBA-code-using-authentication-to-SharePoint.html
They recommended:
Public Sub CopyToSharePoint()
On Error GoTo err_Copy
Dim xmlhttp
Dim sharepointUrl
Dim sharepointFileName
Dim tsIn
Dim sBody
Dim LlFileLength As Long
Dim Lvarbin() As Byte
Dim LobjXML As Object
Dim LstrFileName As String
Dim LvarBinData As Variant
Dim PstrFullfileName As String
Dim PstrTargetURL As String
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim fldr As Folder
Dim f As File
Dim pw As String
Dim UserName As String
Dim RetVal
Dim I As Integer
Dim totFiles As Integer
Dim Start As Date, Finish As Date
UserName = InputBox(Username?") pw = InputBox("Password?")
sharepointUrl = "[http path to server]/[server folder to write to]"
Set LobjXML = CreateObject("Microsoft.XMLHTTP")
Set fldr = fso.GetFolder(CurrentProject.Path & "\[folder with files to
upload]\") totFiles = fldr.Files.Count
For Each f In fldr.Files
sharepointFileName = sharepointUrl & f.Name
'**************************** Upload text files
**************************************************
If Not sharepointFileName Like "*.gif" And Not sharepointFileName
Like "*.xls" And Not sharepointFileName Like "*.mpp" Then
Set tsIn = f.OpenAsTextStream
sBody = tsIn.ReadAll
tsIn.Close
Set xmlhttp = CreateObject("MSXML2.XMLHTTP.4.0")
xmlhttp.Open "PUT", sharepointFileName, False, UserName, Password
xmlhttp.Send sBody
Else
'**************************** Upload binary files
**************************************************
PstrFullfileName = CurrentProject.Path & "\[folder with files to upload]\" & f.Name
LlFileLength = FileLen(PstrFullfileName) - 1
' Read the file into a byte array.
ReDim Lvarbin(LlFileLength)
Open PstrFullfileName For Binary As #1
Get #1, , Lvarbin
Close #1
' Convert to variant to PUT.
LvarBinData = Lvarbin
PstrTargetURL = sharepointUrl & f.Name
' Put the data to the server, false means synchronous.
LobjXML.Open "PUT", PstrTargetURL, False, Username, Password
' Send the file in.
LobjXML.Send LvarBinData
End If
I = I + 1 RetVal = SysCmd(acSysCmdSetStatus, "File " & I & " of " & totFiles & " copied...") Next f
RetVal = SysCmd(acSysCmdClearStatus) Set LobjXML = Nothing Set
fso = Nothing
err_Copy: If Err <> 0 Then MsgBox Err & " " & Err.Description End If
End Sub
Realistically, I think this answer may get you going down the right road: https://sharepoint.stackexchange.com/questions/255264/sharepoint-api-and-vba-access-denied
Regardless, this is a problem and good luck. I had better luck using MS Access to link the list as a table and then using Excel to just call Access and get what I needed.
Private Sub cmdSyncSP_Click()
On Error GoTo ErrorCode
Application.Cursor = xlWait
Dim app As New Access.Application
'Set app = CreateObject("Application.Access")
app.OpenCurrentDatabase Application.ActiveWorkbook.Path & "\SP_Sync.accdb"
app.Visible = False
app.Run "doManualCheck"
app.CloseCurrentDatabase
Set app = Nothing
MsgBox "Sync has finished. Refresh and proceed to copy your data.", vbInformation + vbOKOnly, "Success"
ExitCode:
On Error Resume Next
Application.Cursor = xlDefault
Exit Sub
ErrorCode:
MsgBox "Error " & Err.Number & ": " & Err.Description, vbCritical, "Sync Error"
Resume ExitCode
End Sub
Thanks for this excellent resource, it has been of great assistance to me, but I am having a problem using excel VBA to download excel files from a remote server. I suspect it is something obvious that my code is lacking.
The problem I am having is that all the downloaded files are always 15KB in size, regardless of the size or content of the original file and all bear the same content which appears to be text simply copied from the host website, rather than the file I am trying to download. I have tried using various file extensions including CSV but the results are the same.
When I open the downloaded file excel says the file format and extension don't match and then says that, due to problems during load, the file is "missing file C:\remote\css\logon.css" and "missing file C:\remote\javascript\ramjsfx.menu.css", which is Greek to me.
Sub DownloadFilefromWeb()
Const E_OUTOFMEMORY As Long = &H8007000E
Const E_DOWNLOAD_FAILURE As Long = &H800C0002
Dim InitialName As String
Dim Msg As String
Dim RegExp As Object
Dim RetVal As Long
Dim SaveName As String
Dim SavePath As String
Dim URL As String
URL = InputBox("Enter the download URL below.", "Download from Internet")
If URL = "" Then Exit Sub
Set RegExp = CreateObject("VBScript.RegExp")
RegExp.IgnoreCase = True
RegExp.Pattern = "^(.*\/)(.+)$"
InitialName = RegExp.Replace(URL, "$2")
Set RegExp = Nothing
If InitialName = "" Or InitialName = URL Then
MsgBox ("Error - Missing File Name")
Exit Sub
End If
SavePath = Application.GetSaveAsFilename(InitialName)
If SavePath = "" Then Exit Sub
'SavePath = "C:\Users\Rob's Laptop\Documents\Test\Test3.xls"
'URL = "https://remote.picosting.co.uk/Remote/fs/files.aspx?path=%5c%5cPISBS2011%5cfiles%5cRob% 20Shaw%27s%20test%20folder%5cTest1"
RetVal = URLDownloadToFile(0&, URL, SavePath, 0&, 0&)
Select Case RetVal
Case 0
Msg = "Download Successful"
Case E_OUTOFMEMORY
Msg = "Error - Out of Mmemory"
Case E_DOWNLOAD_FAILURE
Msg = "Error - Bad URL or Connection Interrupted"
Case Else
Msg = "Unknown Error - " & RetVal
End Select
MsgBox Msg
End Sub
Kind regards
Rob
URLDownloadToFile() is literally and simply downloading the .aspx page that is on the server - when accessed through a normal web broswer, that page does server side logic to obtain and download the Excel file you are trying to get. The css files it is complaining about are stylesheet files that are used to control the display of the .aspx page.
You will need to use something more complex than URLDownloadToFile() to save the file that you want, for example setting up an IE Application object as described here:
http://www.mrexcel.com/forum/excel-questions/502298-need-help-regarding-ie-automation-using-visual-basic-applications.html