Download data from hyperlinks into creating new folders using vba - vba

Image of data in excelI am downloading some data from net using hyperlinks and to put downloaded data into folders created with names listed in A column.
Right now data is successfully downloaded when there is only one hyperlink for one folder, but now I also wants to put more than 2 files data into same folder.
Can anyone suggest a way to enhance the code to allow that?
Option Explicit
Private Declare Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" (ByVal pCaller As Long, _
ByVal szURL As String, ByVal szFileName As String, _
ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Dim ret As Long
'> This is where the files will be saved. Change as applicable
Const FolderName As String = "C:\Users\a3rgcw\Downloads\"
Sub Download()
Dim ws As Worksheet
Dim lastRow As Long, i As Long
Dim strPath As String
Set ws = Sheets("Sheet1")
lastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To lastRow
strPath = FolderName & ws.Range("A" & i).Value & ".zip"
ret = URLDownloadToFile(0, ws.Range("D" & i).Value, strPath, 0, 0)
If ret = 0 Then
ws.Range("F" & i).Value = "PR data successfully downloaded"
Else
ws.Range("F" & i).Value = "Unable to download PR data"
End If
Next i
End Sub

edited after OP clarifications he doesn't have hyperlinks
as per your shown code and link, your code doesn't actually create new folders, rather it creates many new files in "C:\Users\a3rgcw\Downloads\" folder (i.e. your FolderName variable
and since those files names are built with ws.Range("A" & i).Value & ".zip", then for every same value in any column A cell it overwrites the existing file with the new one
furthermore your link shows column "C" with hyperlinks while your code read them from column "D" (ws.Range("D" & i).Value
to avoid files overwriting you could define zip name out of a combination of "folder" name (from column A cells) and file name (from corresponding hyperlink address) like follows (assuming your code assumption for hyperlinks column is the valid one)
Sub Download()
Dim ws As Worksheet
Dim LastRow As Long, i As Long
Dim strPath As String
Set ws = Sheets("Sheet1")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).row
For i = 1 To LastRow
strPath = FolderName & _
ws.Range("A" & i).Value & "-" & _
GetName(ws.Range("D" & i)) & ".zip"
ret = URLDownloadToFile(0, ws.Range("D" & i).Value, strPath, 0, 0)
If ret = 0 Then
ws.Range("F" & i).Value = "PR data successfully downloaded"
Else
ws.Range("F" & i).Value = "Unable to download PR data"
End If
Next i
End Sub
Function GetName(rng As Range) As String
With rng
GetName = Right(.Value, Len(.Value) - InStrRev(.Value, "/"))
End With
End Function
which could also be refactored as follows:
Sub Download()
Dim strPath As String
Dim cell As Range
With Sheets("Sheet1")
For Each cell In .Range("A1", .Cells(.Rows.Count, 1).End(xlUp))
strPath = FolderName & _
cell.Value & "-" & _
GetName(cell.Offset(, 3)) & ".zip"
ret = URLDownloadToFile(0, cell.Offset(, 3).Value, strPath, 0, 0)
cell.Offset(, 5).Value = IIf(ret = 0, "PR data successfully downloaded", "Unable to download PR data")
Next
End With
End Sub
Function GetName(rng As Range) As String
With rng
GetName = Right(.Value, Len(.Value) - InStrRev(.Value, "/"))
End With
End Function

Related

HOW TO USE SHELL COMMAND COPY IN VBA

I was trying to copy and paste files from a source folder to a destination folder in VBA using the fyle system object, but noticed that it is kind of slow, so I decided to use a shell command instead, but cannot make it work, it's probably something with text literals, here's the code
Dim sourceFolderName As String, destFolderName As String
Dim sourceFolderPath As String, destFolderPath As String
Dim filteredRange As Range, myRange As Range
Dim lastRowNumber As Integer
sourceFolderName = "SOURCE"
destFolderName = "DESTINATION"
sourceFolderPath = Application.ThisWorkbook.Path & _
Application.PathSeparator & sourceFolderName & Application.PathSeparator
destFolderPath = Application.ThisWorkbook.Path & _
Application.PathSeparator & destFolderName
On Error Resume Next
Kill destFolderPath & "\*.*"
lastRowNumber = ThisWorkbook.Sheets(1).Cells(Sheets(1).Rows.Count, 1).End(xlUp).Row
If lastRowNumber = 2 Then
lastRowNumber = 3
End If
Set filteredRange = ThisWorkbook.Sheets(1).Range("A2", "A" & lastRowNumber).SpecialCells(xlCellTypeVisible)
For Each myRange In filteredRange
Shell "cmd /c copy " & sourceFolderPath & myRange.Value & ".pdf " & destFolderPath, vbHide
Next

Create folders using 2 column values from Excel

So I need to make a whole bunch of folders from a spreadsheet.
I have in column A the Surname and in Column B the name of a person, I need to generate folders based on this.
I have found a bit of code that someone else posted, that works, but I need to add a space between the name and surname in the created folder.
The original poster said that they did manage to add a space, but never indicated how.
Sub MakeFoldersForEachRow()
Dim Rng As Range
Dim maxRows, maxCols, r, c As Integer
Dim s As String
Set Rng = Selection
maxRows = Rng.Rows.Count
maxCols = Rng.Columns.Count
For r = 1 To maxRows
s = ""
For c = 1 To maxCols
s = s & Rng(r, c)
Next c
If Len(Dir(ActiveWorkbook.Path & "\" & s, vbDirectory)) = 0 Then
MkDir (ActiveWorkbook.Path & "\" & s)
On Error Resume Next
End If
Next r
End Sub
Please, try the next code:
Sub createFoldNamesFromTwoColumns()
Dim sh As Worksheet, lastR As Long, fldName As String, i As Long
Set sh = ActiveSheet 'use here your necessary sheet
lastR = sh.Range("A" & sh.Rows.count).End(xlUp).row
For i = 1 To lastR
fldName = sh.Range("A" & i) & " " & sh.Range("B" & i)
If Dir(ActiveWorkbook.Path & "\" & fldName, vbDirectory) = "" Then
MkDir ActiveWorkbook.Path & "\" & fldName
End If
Next i
End Sub
Edited:
I could see now your last request, meaning to process the selected columns:
Sub createFoldNamesFromTwoSelectedColumns()
Dim sh As Worksheet, rngSel As Range, C1 As Long, lastR As Long, fldName As String, i As Long
Set sh = ActiveSheet
Set rngSel = Selection
If rngSel.Columns.count <> 2 Then MsgBox "You must select two columns!": Exit Sub
C1 = rngSel.cells(1).Column: Stop
lastR = sh.cells(sh.Rows.count, C1).End(xlUp).row
For i = 1 To lastR
fldName = sh.cells(i, C1) & " " & sh.cells(i, C1 + 1)
If Dir(ActiveWorkbook.Path & "\" & fldName, vbDirectory) = "" Then
MkDir ActiveWorkbook.Path & "\" & fldName
End If
Next i
End Sub

Excel downloading pictures from hyperlink

I am currently using this code using the developer console to try to mass download all of the images off the hyperlinks I have in my excel document.
Option Explicit
Private Declare Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" (ByVal pCaller As Long, _
ByVal szURL As String, ByVal szFileName As String, _
ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Dim Ret As Long
'~~> This is where the images will be saved. Change as applicable
Const FolderName As String = "C:\Temp\"
Sub Sample()
Dim ws As Worksheet
Dim LastRow As Long, i As Long
Dim strPath As String
'~~> Name of the sheet which has the list
Set ws = Sheets("Sheet1")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To LastRow '<~~ 2 because row 1 has headers
strPath = FolderName & ws.Range("A" & i).Value & ".jpg"
Ret = URLDownloadToFile(0, ws.Range("B" & i).Value, strPath, 0, 0)
If Ret = 0 Then
ws.Range("C" & i).Value = "File successfully downloaded"
Else
ws.Range("C" & i).Value = "Unable to download the file"
End If
Next i
End Sub
It seems that it will download the images if the pic name column I have in column A is something like this - "calculator.jpg"
However, I would like the picture name to be the hyperlink I am using to download the images, aka something like www.hyperlink.com/calculator.jpg
My code seems to not download the images when the hyperlink is in the picture name column, even though it does print in column C "download successful."
If someone could help me I would really appreciate it!
However, I would like the picture name to be the hyperlink I am using to download the images, aka something like www.hyperlink.com/calculator.jpg
Like I said in the comments above, "You can't have the pic name as hyperlink as "/" is not a valid character for a file name. You have to extract "calculator.jpg" from col A and then use it in the code"
Is this what you are trying?
Option Explicit
Private Declare Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" (ByVal pCaller As Long, _
ByVal szURL As String, ByVal szFileName As String, _
ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Dim Ret As Long
'~~> This is where the images will be saved. Change as applicable
Const FolderName As String = "D:\Temp\"
Sub Sample()
Dim ws As Worksheet
Dim LastRow As Long, i As Long
Dim strPath As String
Dim MyAr
'~~> Name of the sheet which has the list
Set ws = Sheets("Sheet1")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To LastRow '<~~ 2 because row 1 has headers
MyAr = Split(ws.Range("A" & i).Value, "/")
'~~> C:\Temp\Calculator.jpg
strPath = FolderName & MyAr(UBound(MyAr))
Ret = URLDownloadToFile(0, ws.Range("B" & i).Value, strPath, 0, 0)
If Ret = 0 Then
ws.Range("C" & i).Value = "File successfully downloaded"
Else
ws.Range("C" & i).Value = "Unable to download the file"
End If
Next i
End Sub

VBA - Trouble with Loop Structure for File Searching and Copying

I'm trying to develop a macro on one of my spreadsheets that will take the value of Column B (2502-13892-33 for example), starting at Row 3, and search the source folder listed in column A for that file (using Wildcards before and after the value in column B. Once it finds that file, it needs to use FileCopy to copy the file into the Destination Folder listed in Column C, but only after renaming the file in the form of "Column E"_"Original Filename (A252_2502-13892-33 for example).
I think I have worked out the code to make this work because when I tested it, it functioned exactly like I expected it to, found the file, copied it to the new destination with the PREFIX from column E and the underscore added to the filename. The problem is that it just stops after the first file, which leads me to believe something is wrong with the structure of my loop.
My code is as follows:
Sub MoveFiles()
Dim SourcePath As String
Dim DestPath As String
Dim PartNum As String
Dim PLISN As String
Dim LastRow As Long
Dim i As Long
Dim filename As String
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i = 3 To LastRow
PLISN = Cells(i, "E").Value
PartNum = Cells(i, "B").Value
If Right(Cells(i, "A").Value, 1) <> Application.PathSeparator Then
SourcePath = Cells(i, "A").Value & Application.PathSeparator
Else
SourcePath = Cells(i, "A").Value
End If
If Right(Cells(i, "C").Value, 1) <> Application.PathSeparator Then
DestPath = Cells(i, "C").Value & Application.PathSeparator
Else
DestPath = Cells(i, "C").Value
End If
If Dir$(SourcePath & "*" & PartNum & "*") = "" Then
Cells(i, "D").Value = "Source file does not exist."
ElseIf Dir$(DestPath & PLISN & "_" & "*" & PartNum & ".pdf") <> "" Then
Cells(i, "D").Value = "File already exists."
Else
filename = Dir$(SourcePath & "*" & PartNum & "*" & ".pdf")
'Copy the file
FileCopy SourcePath & filename, DestPath & PLISN & "_" & filename
Cells(i, "D").Value = "File Copied to new location"
End If
Next i
End Sub
I had accidentally left my DestinationPath blank for the 2nd and 3rd lines of the excel sheet. That was what was giving me just the "\" as the destination path. Seems to be working properly now.
As someone mentioned below in one of the comments, stepping through my code in the debugger was extremely helpful to solving this problem. My final code has some structural changes, in that I no longer have columns for SourcePath and DestPath, and instead use a folder dialog box to have the user select both of those.
The code for selecting my Source and Destination Folders:
Sub SourceFolder()
Dim lCount As Long
Dim rCount As Long
SourcePath = vbNullString
DestPath = vbNullString
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = OpenAt
.Title = "Source Path"
.Show
For lCount = 1 To .SelectedItems.Count
SourcePath = .SelectedItems(lCount)
MsgBox (SourcePath)
Next lCount
End With
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = OpenAt
.Title = "Destination Path"
.Show
For rCount = 1 To .SelectedItems.Count
DestPath = .SelectedItems(rCount)
MsgBox (DestPath)
Next rCount
End With
End Sub
The code for actually going out to the SourcePath, searching for the filename located in Column A (including with wildcards before and after), copying it to the DestinationPath, and renaming it with ColumnB's Value, followed by an underscore, and then ColumnA's Value is as follows:
Option Explicit
Public SourcePath As String
Public DestPath As String
Dim PartNum As String
Dim PLISN As String
Sub MoveFiles()
Dim LastRow As Long
Dim i As Long
Dim filename As String
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i = 3 To LastRow
PLISN = Cells(i, "B").Value
PartNum = Cells(i, "A").Value
If Right(SourcePath, 1) <> Application.PathSeparator Then
SourcePath = SourcePath & Application.PathSeparator
Else
SourcePath = SourcePath
End If
If Right(DestPath, 1) <> Application.PathSeparator Then
DestPath = DestPath & Application.PathSeparator
Else
DestPath = DestPath
End If
If Dir$(SourcePath & "*" & "*" & PartNum & "*") = "" Then
Cells(i, "C").Value = "Source file does not exist."
ElseIf Dir$(DestPath & PLISN & "_" & "*" & PartNum & "*" & ".pdf") <> "" Then
Cells(i, "C").Value = "File already exists."
Else
filename = Dir$(SourcePath & "*" & PartNum & "*" & ".pdf")
'Copy the file
FileCopy SourcePath & filename, DestPath & PLISN & "_" & filename
Cells(i, "C").Value = "File Copied to new location"
End If
Next i
End Sub

Download pictures from hyperlink to specific folder

I have an excel file with folder names(col A), picture names (col B) and hyperlinks (col C) I want to download pictures to a disc from hyperlinks to specific folder (indicated in col A).
FolderName ImageName URL
folder1 image1 hyperlink 1
folder2 image2 hyperlink 2
folder3 image3 hyperlink 3
I have found this code:
Option Explicit
Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" (ByVal pCaller As Long, _
ByVal szURL As String, ByVal szFileName As String, _
ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Dim Ret As Long
'~~> This is where the images will be saved. Change as applicable
Const FolderName As String = "c:\TEMP\"
Sub Sample()
Dim ws As Worksheet
Dim LastRow As Long, i As Long
Dim strPath As String
'~~> Name of the sheet which has the list
Set ws = Sheets("Sheet1")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To LastRow '<~~ 2 because row 1 has headers
strPath = FolderName & ws.Range("B" & i).Value & ".jpg"
Ret = URLDownloadToFile(0, ws.Range("C" & i).Value, strPath, 0, 0)
If Len(Dir(FolderName, vbDirectory)) = 0 Then
MkDir FolderName
End If
If Ret = 0 Then
ws.Range("C" & i).Value = "File successfully downloaded"
Else
ws.Range("C" & i).Value = "Unable to download the file"
End If
Next i
End Sub
It download the files to C:\TMP\ but I would like it to download each file in a row to corresponding folder (col A)
That is quite simple.
Since you are using a CONSTANT as a saving directory Const FolderName As String = "c:\TEMP\" you are not going far if you copy-paste your code insde your workbook.
You should try first of all to understand how the code works and give it a try, but anyway...
Without inserting the Const line, you have to Dim a variable that is going to contain a string of your directory and that will change every time you change row. Basically here:
For i = 2 To LastRow
FolderName = ws.Range("A" & i).text ' this is how you get the folder name from column "A" every line
strPath = FolderName & ws.Range("B" & i).Value & ".jpg"
Ret = URLDownloadToFile(0, ws.Range("C" & i).Value, strPath, 0, 0)
If Len(Dir(FolderName, vbDirectory)) = 0 Then
MkDir FolderName
End If
If Ret = 0 Then
ws.Range("C" & i).Value = "File successfully downloaded"
Else
ws.Range("C" & i).Value = "Unable to download the file"
End If
Next i