VBA Function to return the value only when File can be opened without any error - vba

I'm writing an Excel VBA code to Check how many files in a folder are corrupt.
A folder named as 'Folder' in 'E' drive has these pdf files.
In my workbook; Column A of Sheet1 has fileNames from this folder.
I have a code which loops through the filesNames from column A and opens those.
My objective is : If the file can be opened; then don't print anything in the adjacent cell (of column B) else print as 'Corrupt'.
But, when I run this VBA code; as each time loop goes to the Function OpenPDFPage(), it do not print anything in the adjacent cell of column B.
(I want to print it only when the file is corrupt and I get message box saying "There was an error opening this document. The file is damaged and could not be repaired")
Can I know what change I've to make to the Function OpenPDFPage() so that, when there is a corrupt file (or the file which can't be opened) in folder; then only code will print "corrupt" in the adjacent cell of column B.
The code is as below:
Option Explicit
Function OpenPDFPage(PDFPath As String) As Boolean
On Error GoTo Error_OpenPDFPage
ThisWorkbook.FollowHyperlink PDFPath, NewWindow:=True
OpenPDFPage = True
Exit_OpenPDFPage:
Exit Function
Error_OpenPDFPage:
MsgBox Err & ": " & Err.Description
OpenPDFPage = False
Resume Exit_OpenPDFPage
End Function
Sub Test()
Dim MyFolder As String
Dim filename As Range
Dim MyFile As String
Dim lastRow As Long
lastRow = Sheets("Sheet1").UsedRange.Rows.Count
MyFolder = "E:\Folder"
For Each filename In Worksheets("Sheet1").Range("A2:A" & lastRow)
MyFile = MyFolder & "\" & filename
If OpenPDFPage(MyFile) = True Then
'Do Nothing
Else
filename.Offset(0, 1).Value = "Corrupt"
End If
Next
End Sub

Added another macro to the above; to check whether the file is opened;
If it's not opened through previous macro, then am assuming it's corrupt;
and printing in adjacent cell of column B as 'Corrupt'.
Sub IsFileOpened()
Dim MyFolder As String
Dim filename As Range
Dim MyFile As String
Dim lastRow As Long
lastRow = Sheets("Sheet1").UsedRange.Rows.Count
MyFolder = "E:\Folder"
For Each filename In Worksheets("Sheet1").Range("A1:A" & lastRow)
MyFile = MyFolder & "\" & filename
If IsFileOpen(MyFile) = True Then
' Do Nothing
Else
filename.Offset(0, 1).Value = "Corrupt"
End If
Next
End Sub
Function IsFileOpen(filename As String) As Boolean
Dim filenum As Integer, errnum As Integer
On Error Resume Next
filenum = FreeFile()
'Attempt to open the file and lock it.
Open filename For Input Lock Read As #filenum
Close filenum ' Close the file.
errnum = Err ' Save the error number that occurred.
On Error GoTo 0 ' Turn error checking back on.
' Check to see which error occurred.
Select Case errnum
Case 0
IsFileOpen = False
Case 70
IsFileOpen = True
' Another error occurred.
'Case Else
'Error errnum
End Select
End Function

Related

Error: -2147188160 Slides.Item: Integer out of range.2 is not in in index's valid range of 1 to 1 VBA power point error

I'm trying to extract few specific slide numbers from each ppt and trying to paste them into a single ppt using VBA.But Im facing this error.Im quite new to VBA ,so it would be of great help how to proceed further.
Tried with the suggestions given in the link https://support.microsoft.com/en-us/help/285472/run-time-error-2147188160-on-activewindow-or-activepresentation-call-i#:~:text=This%20behavior%20is%20caused%20by,code%20will%20cause%20this%20error.
But it is not working
Thanks in Advance
My code is as follows:
Sub sample()
Dim objPresentation As Presentation
On Error GoTo ErrorHandler
Dim sListFileName As String
Dim sListFilePath As String
Dim iListFileNum As Integer
Dim sBuf As String
' EDIT THESE AS NEEDED
' name of file containing files to be inserted
sListFileName = "LIST2.TXT"
' backslash terminated path to folder containing list file:
sListFilePath = "path"
' Do we have a file open already?
If Not Presentations.Count > 0 Then
Exit Sub
End If
' If LIST.TXT file doesn't exist, create it
If Len(Dir$(sListFilePath & sListFileName)) = 0 Then
iListFileNum = FreeFile()
Open sListFilePath & sListFileName For Output As iListFileNum
' get file names
sBuf = Dir$(sListFilePath & "*.PPT")
While Not sBuf = ""
Print #iListFileNum, sBuf
sBuf = Dir$
Wend
Close #iListFileNum
End If
iListFileNum = FreeFile()
Open sListFilePath & sListFileName For Input As iListFileNum
' Process the list
While Not EOF(iListFileNum)
' Get a line from the list file
Line Input #iListFileNum, sBuf
' Verify that the file named on the line exists
If Dir$(sBuf) <> "" Then
Dim SlideArray As Variant
'Set variable to Active Presentation
Set OldPPT = ActivePresentation
'Create a brand new PowerPoint presentation
If PowerPoint.Application.Version >= 9 Then
'window must be visible
PowerPoint.Application.Visible = msoTrue
End If
Set NewPPT = Presentations.Add
InSlides = InputBox("List the slide numbers separated by commas:", "Slides", 2)
SlideArray = Split(InSlides, ",")
For x = 0 To UBound(SlideArray)
sld = CInt(SlideArray(x))
'Set variable to a specific slide
Set Old_sld = OldPPT.Slides(sld)
'Copy Old Slide
y = Old_sld.SlideIndex
Old_sld.Copy
'Paste Slide in new PowerPoint
NewPPT.Slides.Paste
Set New_sld = Application.ActiveWindow.View.Slide
'Bring over slides design
New_sld.Design = Old_sld.Design
'Bring over slides custom color formatting
New_sld.ColorScheme = Old_sld.ColorScheme
'Bring over whether or not slide follows Master Slide Layout (True/False)
New_sld.FollowMasterBackground = Old_sld.FollowMasterBackground
Next x
End If
Wend
Close #iListFileNum
MsgBox "DONE!"
NormalExit:
Exit Sub
ErrorHandler:
Call MsgBox("Error:" & vbCrLf & Err.Number & vbCrLf & Err.Description, _
vbOKOnly, "Error inserting files")
Resume NormalExit
End Sub

Check which file is open VBA

All,
I have a large module which in the earlier part checks whether a files is in use (Readonly) format and if it is in use to open the next file. I.e. if file one is in use open file two etc..
In a later part of the module I wish to use the file which has been opened. However I am struggling to identify the file which is opened in the earlier part of the automation and set is as WB.
The code I am currently using is;
Dim wb As Object
On Error Resume Next
Workbooks("\\Csdatg04\psproject\Robot\Project Preload\Transactions\Transactions1.csv").Activate
If Err.Number = 0 Then
wb = GetObject("\\Csdatg04\psproject\Robot\Project Preload\Transactions\Transactions1.csv")
GoTo skipline
End If
On Error GoTo 0
On Error Resume Next
Workbooks("\\Csdatg04\psproject\Robot\Project Preload\Transactions\Transactions2.csv").Activate
If Err.Number = 0 Then
wb = GetObject("\\Csdatg04\psproject\Robot\Project Preload\Transactions\Transactions2.csv")
GoTo skipline
End If
On Error GoTo 0
On Error Resume Next
Workbooks("\\Csdatg04\psproject\Robot\Project Preload\Transactions\Transactions3.csv").Activate
If Err.Number = 0 Then
wb = GetObject("\\Csdatg04\psproject\Robot\Project Preload\Transactions\Transactions3.csv")
GoTo skipline
End If
On Error GoTo 0
On Error Resume Next
Workbooks("\\Csdatg04\psproject\Robot\Project Preload\Transactions\Transactions4.csv").Activate
If Err.Number = 0 Then
wb = GetObject("\\Csdatg04\psproject\Robot\Project Preload\Transactions\Transactions4.csv")
GoTo skipline
End If
skipline:
On Error GoTo 0
Can anyone recommend how I can identify which file is open and set is as WB
Any help would be much appreciated.
Thanks
Don't try to match the path: mapped drives and aliases will spoof your matches.
Your match term is the file name, with the extension, and you can iterate the Excel workbooks collection to see if there's a matching name:
Option Explicit
Public Function WorkbookIsOpen(WorkBookName As String) As Boolean
' Returns TRUE if a workbook (or csv file open in Excel) is open
Dim wbk As Excel.Workbook
WorkbookIsOpen = False
If IsError(WorkBookName) Then
WorkbookIsOpen = False
ElseIf WorkBookName = "" Then
WorkbookIsOpen = False
Else
For Each wbk In Application.Workbooks
If wbk.Name = WorkBookName Then
WorkbookIsOpen = True
Exit For
End If
Next wbk
End If
End Function
Public Function FileName(FilePath As String) As String
' Returns the last element of a network path
' This is usually the file name, but it mat be a folder name if FilePath is a folder path:
' FileName("C:\Temp\Readme.txt") returns "ReadMe.txt"
' ?FileName("C:\Temp") returns "Temp"
' FileName("C:\Temp\") returns ""
' This function does not perform any file checking - the file need not exist, the path
' can be invali or inaccessible. All we're doing is String-handling.
Dim arr() As String
Dim i As Integer
If IsError(FilePath) Then
FileName = "#ERROR"
ElseIf FilePath = "" Then
FileName = ""
Else
arr = Split(Trim(FilePath), "\")
i = UBound(arr)
FileName = arr(i)
Erase arr
End If
End Function
Then it's just a matter of checking if the open workbook is open read-only:
Dim bReadOnly As Boolean
If WorkbookIsOpen("C:Temp\Brian.csv") Then
bReadOnly = Application.WorkBooks(FileName("C:Temp\Brian.csv")).ReadOnly
End If
Things get a lot more interesting if you need to check that the file isn't open in another session of Excel, or another application: this code won't test that for you.
I need to answer the other point in your question: opening the file in Excel if it isn't already open in this session.
I would recommend using Application.Workbooks.Open(FileName) for that, as it's smarter than GetObject() and will open the file - csv, xml, xls, xlsx - in Excel, as a workbook, with Excel guessing the necessary format parameters. Also,the native 'open' function allows you to specify additional parameters, like Read-Only.

Is there method similar to 'Find' available when we Loop through folder (of files) using Dir Function in excel vba?

As we know, we use Find() method to find whether a string or any Microsoft Excel data type exists in an excel.
(Usually we do it on set of data)
I want to know if any such method available when we loop through folder(of files) using Dir function.
Situation:
I have an excel - 'FileNames.xlsx' in which 'Sheet1' has names of files having extensions .pdf/.jpg/.jpeg/.xls/.xlsx/.png./.txt/.docx/ .rtf in column A.
I have a folder named 'Folder' which has most(or all) of the files from 'FileNames.xlsx'.
I have to check whether all the file-names mentioned in the 'FileNames.xlsx' exist in 'Folder'.
For this I have written the below VBScript(.vbs):
strMessage =Inputbox("Enter No. of Files in Folder","Input Required")
set xlinput = createobject("excel.application")
set wb123 =xlinput.workbooks.Open("E:\FileNames.xlsx")
set sh1 =wb123.worksheets("Sheet1")
For i = 2 to strMessage +1
namei = sh1.cells(i,1).value
yesi = "E:\Folder"+ namei +
If namei <> yesi Then
sh1.cells(i,1).Interior.Color = vbRed
Else
End If
Next
msgbox "Success"
xlinput.quit
As I wasn't able to get the required Output I tried it recording a small Excel VBA Macro. (Changed FileNames.xlsx to FileNames.xlsm)
Sub LoopThroughFiles()
Dim lastRow As Long
lastRow = Sheets("Sheet1").UsedRange.Rows.Count
Dim MyFolder As String
Dim filename As Range
Dim MyFile As String
MyFolder = "E:\Folder"
For Each filename In Worksheets("Sheet1").Range("A2A:" & lastRow)
MyFile = Dir(MyFolder & "\*.xlsx")
'Here I actually need to pass all file extensions to Dir
Do While MyFile <> ""
If filename = MyFile Then
'Do Nothing
Else
filename.Interior.Color = vbRed
MyFile = Dir
Next
End Sub
The above is a failed attempt.
I thought of trying it with method similar to Find()
Sub LoopThroughFiles()
Dim lastRow As Long
'Dim LastFile As Long
'Is there need of it (LastFile variable)? I kept this variable
'to save (prior known) count of files in folder.
lastRow = Sheets("Sheet1").UsedRange.Rows.Count
'LastFile = 'Pass count of Files in folder to this variable.
Dim fileName As Range
For Each fileName In Worksheets("Sheet1").Range("A2:A" & lastRow)
Dim rngFnder As Range
On Error Resume Next
'Error at below line.
Set rngFnder = Dir("E:\Folder\").Find(filename)
'This line gives me error 'Invalid Qualifier'
'I am trying to use method similar to Find()
If rngFnder Is Nothing Then
filename.Interior.Color = vbRed
End If
Next
End Sub
But, I couldn't achieve the result. Can anyone tell me is there any such function available to 'Find' whether all filenames in an excel exist in a folder after looping through folder using Dir?
As per my knowledge, Dir function works with only one file extension at a time.
Is it possible to use Dir function for multiple file extensions at a time?
Expected Output:
Assume I have 8 filenames in 'FileNames(.xlsx/.xlsm)'. Out of which Arabella.pdf and Clover.png are not found in 'Folder', Then I want to color cells for these filenames in red background in excel as in below image.
Sub LoopThroughFiles()
Dim lastRow As Long
lastRow = Sheets("Sheet1").UsedRange.Rows.Count
Dim MyFolder As String
Dim filename As Range
Dim MyFile As String
MyFolder = "E:\Folder"
For Each filename In Worksheets("Sheet1").Range("A2:A" & lastRow)
MyFile = MyFolder & "\" & filename
If Not FileExists(MyFile) Then
filename.Interior.Color = vbRed
End If
Next
End Sub
Public Function FileExists(strFullpathName As String) As Boolean
If Dir(strFullpathName) <> "" Then
FileExists = True
Else
FileExists = False
End If
End Function
You can output a list of the files that are contained in the folder. I found a really helpful tutorial on that here: http://software-solutions-online.com/2014/03/05/list-files-and-folders-in-a-directory/#Jump1
If you then loop through both the original and the output lists and look for a match. Easiest is to first colour them all red, and un-colour the matches. Else you would need an additional if-statement that states: When you reach the last element in the original list, and no match has been found, then colour red.
Edit: For continuity's sake I copied the code bits of the link I mentioned above:
Getting all file names form within 1 folder:
Sub Example1()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder("D:StuffFreelancesWebsiteBlogArraysPics")
i = 1
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'print file name
Cells(i + 1, 1) = objFile.Name
'print file path
Cells(i + 1, 2) = objFile.Path
i = i + 1
Next objFile
End Sub

VBA code to open a changing file name

I'm trying to figure out a line of code to open a file.
The path is constant, that is
"H:\silly\goose\*filename.xlsm*"
However, this file name will change each time I try to run this macro. This is because I will be using this macro to automate a report which I run weekly. Each report is saved with the date in the title and all reports are kept in the same folder, meaning I can't just start naming them all the same.
Examples:
H:\silly\goose\Report 06-03-15.xlsm
H:\silly\goose\Report 05-27-15.xlsm
The only helping piece of information is that this report is to be run every Wednesday. Therefore, each filename will have a difference of 7 days. I don't know if there is anything I can do with the Date method here, though.
What you need to do is re-construct your file name first.
Const fpath As String = "H:\silly\goose\" ' your fixed folder
Dim fname As String
' Below gives you the Wednesday of the week
fname = Format(Date - (Weekday(Date) - 1) + 3, "mm-dd-yy") ' returns 06-03-15 if run today
fname = "Report " & fname & ".xlsm" ' returns Report 06-03-15.xlsm
fname = fpath & fname ' returns H:\silly\goose\Report 06-03-15.xlsm
Then execute opening of the file:
Dim wb As Workbook
Set wb = Workbooks.Open(fname)
If wb Is Nothing Then MsgBox "File does not exist": Exit Sub
' Rest of your code goes here which works on wb Object
This reference has this function:
Function GetFileList(FileSpec As String) As Variant
' Returns an array of filenames that match FileSpec
' If no matching files are found, it returns False
Dim FileArray() As Variant
Dim FileCount As Integer
Dim FileName As String
On Error GoTo NoFilesFound
FileCount = 0
FileName = Dir(FileSpec)
If FileName = "" Then GoTo NoFilesFound
' Loop until no more matching files are found
Do While FileName <> ""
FileCount = FileCount + 1
ReDim Preserve FileArray(1 To FileCount)
FileArray(FileCount) = FileName
FileName = Dir()
Loop
GetFileList = FileArray
Exit Function
' Error handler
NoFilesFound:
GetFileList = False
End Function
Now you can do:
p = "H:\silly\goose\*.xlsm"
x = GetFileList(p)
And get the file you want

VB macro Excel script should copy entire folder data

Background : approx. 300 Excel surveys (with multiple sheets) should be centralized in 1 single excel.The macro is ready.
Goal : although the Macro is ready and able to copy the desired data from the Survey excel,I do not have the possibility to copy all 300 surveys at once ( I have to go 1 by 1 through all the surveys)
Question : is it possible to ask the macro to target copy from a specific network path and hereby to copy all the 300 excel workbooks?
Macro script :
Function bIsBookOpen(ByRef szBookName As String) As Boolean
On Error Resume Next
bIsBookOpen = Not (Application.Workbooks(szBookName) Is Nothing)
End Function
Sub Start()
currwb = ActiveWorkbook.Name
If bIsBookOpen("PERSONAL.XLSB") Then
Windows("PERSONAL.XLSB").Visible = True
ActiveWindow.Close
End If
If Workbooks.Count > 1 Then
MsgBox " To many files open... " & Workbooks(1).Name
Else
Application.Dialogs(xlDialogOpen).Show
Response = MsgBox("Weiter mit 'IT-Personal'?", vbYesNo)
If Response = vbYes Then
Windows(currwb).Activate
Call CopyForm
End If
End If
End Sub
To loop through files in a folder,
Sub LoopThroughFiles()
Dim path As String
Dim filename As String
Dim wb As Workbook
path = "" 'your folder path here
filename = Dir(path & "*.xls")
While (filename <> "")
Set wb = Workbooks.Open(path & filename)
'Your code goes here
wb.Close
filename = Dir
Wend
End Sub