Set Prompted Excel Spreadsheet to new Workbook Object - vba

I'm trying to assign a new excel worksheet that is being prompt to open as a new Workbook Object. I'm trying the below code, however it's not working
Option Explicit
Sub MoveGeneratedReport()
Dim newWbReport As Workbook
Dim MonthlyComplianceReport As Workbook
Set MonthlyComplianceReport = SelectWorkbook
End Sub
Private Function SelectWorkbook() As Workbook
Dim strFileToOpen As String
strFileToOpen = Application.GetOpenFilename(Title:="Select Compliancy Report for export", _
FileFilter:="Excel Files *.xls* (*.xls*),")
If strFileToOpen <> False Then '<---- Error Ocuring here
Workbooks.Open Filename:=strFileToOpen
End If
End Function
I'm receiving the
"Type Mismatch"
error, however if I just run the function SelectWorkbook() it works fine and opens the document.
My end goal here is to open the document and then assign it to a Workbook object. Any suggestions to fix this error?
EDIT:
I should clarify my question here too... How can I assign this newly opened Workbook via the prompt to a Workbook object so that the rest of my code can work with it?
EDIT 2:
This seems to be working really well
Option Explicit
Sub MoveGeneratedReport()
Dim newWbReport As Workbook
Dim MonthlyComplianceReport As Workbook
Set MonthlyComplianceReport = SelectWorkbook
Debug.Print MonthlyComplianceReport.Name
End Sub
Private Function SelectWorkbook() As Workbook
Dim strFileToOpen As String
strFileToOpen = Application.GetOpenFilename(Title:="Select Compliancy Report for export", _
FileFilter:="Excel Files *.xls* (*.xls*),")
If strFileToOpen <> "" Then
On Error GoTo ErrHandle
Set SelectWorkbook = Workbooks.Open(Filename:=strFileToOpen)
End If
Exit Function
ErrHandle:
If Err.Number <> 1004 Then
MsgBox "Error " & Str(Err.Number) & Chr(13) & _
"Error Line: " & Erl & Chr(13) & Chr(13) & _
Err.Description
End If
End Function

GetOpenFilename returns a String so it wont ever be true or false. Test for an empty string instead:
If strFileToOpen <> "" Then
Edit:
To set the workbook object change it to this:
Private Function SelectWorkbook() As Workbook
Dim strFileToOpen As String
strFileToOpen = Application.GetOpenFilename(Title:="Select Compliancy Report for export", _
FileFilter:="Excel Files *.xls* (*.xls*),")
If strFileToOpen <> "" Then
Set SelectWorkbook = Workbooks.Open(Filename:=strFileToOpen)
End If
End Function

Related

Combining macros in Excel

I'm trying to combine/nest 3 different functions in Excel VBE: open, loop, and click. I have them written out separately, but am unsure of how to combine them. I've tried the "call macro" function but got a compile error returned to me.
The goal is to open a bunch of files within a certain folder and click on the URL in all of them (the URL will not always be the same, so I need a click function that targets any unknown URL within a sheet).
Open macro:
Sub openMyfile()
Dim Source As String
Dim StrFile As String
Source = "/users/kmogilevsky/Desktop/IC_new/"
StrFile = Dir("/users/kmogilevsky/Desktop/IC_new/")
Do While Len(StrFile) > 0
Workbooks.Open Filename:=Source & StrFile
StrFile = Dir("/users/kmogilevsky/Desktop/IC_new/")
Loop
End Sub
Loop macro:
Sub LoopThroughFiles()
Dim MyObj As Object, MySource As Object, file As Variant
Set MySource = MyObj.GetFolder("/users/kmogilevsky/Desktop/IC_new/")
For Each file In MySource.Files
If InStr(file.Name, "test") > 0 Then
End If
Next file
End Sub
Click macro (this needs some work):
Private Sub CommandButton1_Click()
Call NewSub
End Sub
Sub ReadWorkbooksInCurrentFolder()
Dim wbDst As Workbook
Dim wbSrc As Workbook
Dim MyPath As String
Dim strFilename As String
'Stop annoying popups while macro is running
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
'When working with many open workbooks its good to explicitly reference all workbooks, makes sure your code works and easier to read, understand and remember which workbook is which.
Set wbDst = ThisWorkbook
srcSheetName = "Data"
dstSheetName = "Results"
'I want to loop through all .xlsx files in the folder
MyPath = ThisWorkbook.Path
strFilename = Dir(MyPath & "\*.xlsx", vbNormal)
If Len(strFilename) = 0 Then
MsgBox "No workbooks found ending in .xlsx in current folder"
Exit Sub
End If
Do Until strFilename = ""
Set wbSrc = Workbooks.Open(Filename:=MyPath & "\" & strFilename)
Call CollectData(wbDst, wbSrc, dstSheetName, srcSheetName)
wbSrc.Close
strFilename = Dir()
Loop
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Sub CollectData(ByRef wbDst as Workbook, ByRef wbSrc as Workbook, dstSheetName as String, srcSheetName as String)
'Copy cell A1 contents in source workbook to destination workbook cell A1
wbDst.Sheets(dstSheetName).Range("A1") = wbSrc.Sheets(srcSheetName).Range("A1")
End Sub
Please edit the subroutine CollectData() so that it suits your needs, i.e. performs the click / url open. (I am not familiar with opening urls from excel, but I loop through workbooks often)
This code will open all Excel files in the IC_New folder on the desktop.
It will then look at each sheet and follow any hyperlinks that are on the sheet.
Sub Open_ClickHyperlinks()
Dim sPath As String
Dim vFiles As Variant
Dim vFile As Variant
Dim wrkBk As Workbook
Dim wrkSht As Worksheet
Dim HLink As Hyperlink
sPath = CreateObject("WScript.Shell").SpecialFolders("Desktop") & Application.PathSeparator & _
"IC_New" & Application.PathSeparator
'Return all files that have an extension starting with xls.
vFiles = EnumerateFiles(sPath, "xls*")
'Loop through each file.
For Each vFile In vFiles
'Open the file
Set wrkBk = Workbooks.Open(Filename:=vFile, UpdateLinks:=False)
With wrkBk
'Loop through each worksheet in the file.
For Each wrkSht In .Worksheets
'Loop through each hyperlink on the worksheet.
For Each HLink In wrkSht.Hyperlinks
HLink.Follow
Next HLink
Next wrkSht
.Close SaveChanges:=False
End With
Next vFile
End Sub
'Get all files in the specified folder, default to include all subfolders as well.
Public Function EnumerateFiles(sDirectory As String, _
Optional sFileSpec As String = "*", _
Optional InclSubFolders As Boolean = True) As Variant
EnumerateFiles = Filter(Split(CreateObject("WScript.Shell").Exec _
("CMD /C DIR """ & sDirectory & "*." & sFileSpec & """ " & _
IIf(InclSubFolders, "/S ", "") & "/B /A:-D").StdOut.ReadAll, vbCrLf), ".")
End Function

Reference Excel cell in PowerPoint macro for filename

I can't get SaveAsFixedFormat working from Excel VBA to export a PowerPoint file as PDF. I have resorted to starting a macro in the preset-powerpoint from Excel VBA that exports the presentation as pdf directly from PowerPoint.
Is there any way to reference a cell in the Excel file in this macro that is running in PowerPoint to get the filename?
Sub pppdf()
ActivePresentation.ExportAsFixedFormat "M:\random\test.pdf", 32
End Sub
I can save the PowerPoint file as .pptx from Excel and use varying filenames and paths but now I would like to reference those same paths and filenames in the PowerPoint macro that is exporting to pdf.
In the end I'd like the code to look somewhat like this but this obviously needs some work to function from PowerPoint:
Dim FName As String
Dim FPath As String
FPath = Range("SavingPath").Value
FName = Sheets("randomworksheet").Range("A1").Text
ActivePresentation.ExportAsFixedFormat FPath & FName & " Development" & ".pdf", 32
This PowerPoint macro would be started from Excel and both the PowerPoint file and the Excel Workbook and sheet will be open when this is executed.
Why not open the presentation and save it as a PDF from Excel if the main bulk of the code is in Excel anyway?
Sub SavePPTXasPDF()
Dim PPT As Object
Dim PP As Object
Set PPT = CreatePPT
Set PP = PPT.Presentations.Open("<FullPathToPresentation>")
PP.SaveAs ThisWorkbook.Path & Application.PathSeparator & "ABC", 32 'ppSaveAsPDF
End Sub
Public Function CreatePPT(Optional bVisible As Boolean = True) As Object
Dim oTmpPPT As Object
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Defer error trapping in case Powerpoint is not running. '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
On Error Resume Next
Set oTmpPPT = GetObject(, "Powerpoint.Application")
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'If an error occurs then create an instance of Powerpoint. '
'Reinstate error handling. '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If Err.Number <> 0 Then
Err.Clear
On Error GoTo ERROR_HANDLER
Set oTmpPPT = CreateObject("Powerpoint.Application")
End If
oTmpPPT.Visible = bVisible
Set CreatePPT = oTmpPPT
On Error GoTo 0
Exit Function
ERROR_HANDLER:
Select Case Err.Number
Case Else
MsgBox "Error " & Err.Number & vbCr & _
" (" & Err.Description & ") in procedure CreatePPT."
Err.Clear
End Select
End Function
or if you want to run the code in Powerpoint:
Public Sub Test()
Dim oXL As Object
Dim oWB As Object
Dim FName As String
Dim FPath As String
Set oXL = CreateXL
Set oWB = oXL.workbooks.Open("<Path&FileName>")
'Or if Workbook is already open:
'Set oWB = oXL.workbooks("<FileName>")
FPath = oWB.worksheets("Sheet1").Range("A1")
FName = oWB.worksheets("Sheet1").Range("A3")
ActivePresentation.ExportAsFixedFormat FPath & FName & " Development" & ".pdf", 32
End Sub
Public Function CreateXL(Optional bVisible As Boolean = True) As Object
Dim oTmpXL As Object
'''''''''''''''''''''''''''''''''''''''''''''''''''''
'Defer error trapping in case Excel is not running. '
'''''''''''''''''''''''''''''''''''''''''''''''''''''
On Error Resume Next
Set oTmpXL = GetObject(, "Excel.Application")
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
'If an error occurs then create an instance of Excel. '
'Reinstate error handling. '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
If Err.Number <> 0 Then
Err.Clear
On Error GoTo ERROR_HANDLER
Set oTmpXL = CreateObject("Excel.Application")
End If
oTmpXL.Visible = bVisible
Set CreateXL = oTmpXL
On Error GoTo 0
Exit Function
ERROR_HANDLER:
Select Case Err.Number
Case Else
MsgBox "Error " & Err.Number & vbCr & _
" (" & Err.Description & ") in procedure CreateXL."
Err.Clear
End Select
End Function
Or you could, as you requested, open the presentation from within Excel and execute code stored in the presentation:
Sub SavePPTXasPDF()
Dim PPT As Object
Dim PP As Object
Set PPT = CreatePPT
Set PP = PPT.Presentations.Open("<FullPath>")
PPT.Run PP.Name & "!Test"
End Sub
This would use the Test macro and use the Set oWB = oXL.workbooks("<FileName>") line of code which is currently commented out in my example above.
What problem are you facing using ExportAsFixedFormat directly from the Excel VBE? According to the documentation (which seems to be incorrect) and the PowerPoint VBE IntelliSense, the second argument, FixedFormatType can only be one of two values:
ExportAsFixedFormat(Path, FixedFormatType, Intent, FrameSlides, _
HandoutOrder, OutputType, PrintHiddenSlides, PrintRange, _
RangeType, SlideShowName, IncludeDocProperties, KeepIRMSettings)
FixedFormatType:
ppFixedFormatTypePDF = 2
ppFixedFormatTypeXPS = 1

Tell if a workbook with a specific string in the name is open

I have a project where I have a dropdown filled with names of clients. If they select client "Anna" and there is a workbook that has "Anna" in the name, that workbook is opened. If not I want a msgbox to pop up saying "that client doesnt exist"
How can I tell if there is currently a workbook with instr("anna") open ?
Here is my current code which just looks at if there is only one workbook open (control workbook) but obviously they could have other stuff open so this isnt a long term solution. Thanks
strCurrPath = Application.ThisWorkbook.Path
lenStrCurrPath = Len(strCurrPath) + 9
lenstrCurrNameSelect = Len(strCurrNameSelect)
intTotal = lenStrCurrPath + lenstrCurrNameSelect
file = Dir(strCurrPath & "\Clients\")
While (file <> "")
If InStr(file, Sheet1.strCurrNameSelect) > 0 Then
Workbooks.Open (strCurrPath & "\Clients\" & file)
End If
file = Dir
Wend
If Workbooks.Count <= 1 Then
MsgBox ("Could not find that client workbook. Check folder.")
Else 'DoNothing
End If
Simple example:
Sub Tester()
Dim wb As Workbook
Set wb = ClientWorkbook("anna")
If Not wb Is Nothing Then
MsgBox "Found matching workbook: " & wb.Name
Else
MsgBox "No matching workbook"
End If
End Sub
Function ClientWorkbook(clientName As String) As Workbook
Dim wb As Workbook, rv As Workbook
For Each wb In Application.Workbooks
If UCase(wb.Name) Like "*" & UCase(clientName) & "*" Then
Set rv = wb
Exit For
End If
Next wb
Set ClientWorkbook = rv
End Function

Excel VBA - save as with .xlsx extension

Here's the code I have for renaming a file. It does a SaveAs and then deletes the original. This needs to be ran on different types of workbooks: some have a .xls extension, others have a .xlsx extension. If it has a .xls extension, I need to force it to have a .xlsx extension somehow.
How can I do this other than by manually typing an "x" at the end of the blank in the InputBox when it pops up?
Or maybe there's a different solution to this problem? My goal is to force the InputBox to show the current filename with a .xlsx extension regardless of what is currently is.
Sub RenameFile()
Dim myValue As Variant
Dim thisWb As Workbook
Set thisWb = ActiveWorkbook
MyOldName2 = ActiveWorkbook.Name
MyOldName = ActiveWorkbook.FullName
MyNewName = InputBox("Do you want to rename this file?", "File Name", _
ActiveWorkbook.Name)
If MyNewName = vbNullString Then Exit Sub
If MyOldName2 = MyNewName Then Exit Sub
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=thisWb.Path & "\" & MyNewName, _
FileFormat:=51
Kill MyOldName
End Sub
If the new extension is always going to be .xlsx, why not leave the extension out of the input box entirely:
Dim fso As New Scripting.FileSystemObject
MyNewName = InputBox("Do you want to rename this file?", "File Name", _
fso.GetBaseName(ActiveWorkbook.Name)) & ".xlsx"
Note that this requires a refernece to Microsoft Scripting Runtime.
Do you want to present the extension at the point of the MsgBox or after? The following code will force the extension to be changed to whatever type you specify. Just add code for other conversions you want to handle. If you want to present the new extension in the Msgbox, copy the code I added and place before the MsgBox. If you want to 'guarantee' new extension, you need to keep the code after the Msgbox in case user overrules your suggestion.
Sub RenameFile()
Dim myValue As Variant
Dim thisWb As Workbook
Dim iOld As Integer
Dim iNew As Integer
Dim iType As Integer
Set thisWb = ActiveWorkbook
Dim MyOldName2, MyOldName, MyNewName As String
MyOldName2 = ActiveWorkbook.Name
MyOldName = ActiveWorkbook.FullName
MyNewName = InputBox("Do you want to rename this file?", "File Name", _
ActiveWorkbook.Name)
If MyNewName = vbNullString Then Exit Sub
If MyOldName2 = MyNewName Then Exit Sub
iOld = InStrRev(MyOldName, ".")
iNew = InStrRev(MyNewName, ".")
If LCase(Mid(MyOldName, iOld)) = ".xls" Then
MyNewName = Left(MyNewName, iNew - 1) & ".xlsx"
iType = 51
ElseIf LCase(Mid(MyOldName, iOld + 1)) = ".YYYY" Then ' Add lines as needed for other types
MyNewName = Left(MyNewName, iNew - 1) & ".ZZZZ" ' Must change type to match desired output type
iType = 9999
Else
MsgBox "Add code to handle extension name of '" & LCase(Mid(MyOldName, iOld)) & "'", vbOKOnly, "Add Code"
Exit Sub
End If
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=thisWb.Path & "\" & MyNewName, FileFormat:=iType
Kill MyOldName
End Sub

Visual Basic, Check if a sheet exists in another workbook

I'm really new to Visual Basic and I don't know any python either, I'm trying to write code that is able to check if a worksheet exists in a workbook...
Sub sheetexist()
If Len(Dir(("C:\My Data\Performance Spreadsheets\[ABCD - Performance.xls]Jun 14"))) Then
MsgBox "Sheet exist"
Else
MsgBox "Sheet does not exist"
End If
End Sub
ABCD does have the sheet for Jun 14 however the code only returns "Sheet does not exist", is there another way to check for worksheets in other workbooks?
I think you're mis-using the Dir function.
The easiest way to check if a sheet exists is with error-handling.
Function SheetExists(wbPath as String, shName as String)
Dim wb as Workbook
Dim val
'Assumes the workbook is NOT open
Set wb = Workbooks.Open(wbPath)
On Error Resume Next
val = wb.Worksheets(shName).Range("A1").Value
SheetExists = (Err = 0)
'Close the workbook
wb.Close
End Function
Call the function like this from a worksheet cell:
=SheetExists("C:\My Data\Performance Spreadsheets\ABCD - Performance.xls", "Jun 14")
Or from VBA like:
Debug.Print SheetExists("C:\My Data\Performance Spreadsheets\ABCD - Performance.xls", "Jun 14")
Without opening the workbook, you could use the code here.
This will raise an error if any part of the formula can't evaluate (e.g., if you pass the name of a non-existent sheet, a bad file path, etc., Error 2023:
Private Function GetInfoFromClosedFile(ByVal wbPath As String, _
wbName As String, wsName As String, cellRef As String) As Variant
Dim arg As String
GetInfoFromClosedFile = ""
If Right(wbPath, 1) <> "\" Then wbPath = wbPath & "\"
If Dir(wbPath & "\" & wbName) = "" Then Exit Function
arg = "'" & wbPath & "[" & wbName & "]" & _
wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1)
On Error Resume Next
GetInfoFromClosedFile = ExecuteExcel4Macro(arg)
End Function
Call it:
Sub Test()
Dim path As String
Dim filename As String
Dim sheetName As String
Dim cellAddress As String
path = "c:\users\you\desktop"
filename = "file.xlsx"
sheetName = "Jun 14"
cellAddress = "A1"
Dim v As Variant 'MUST BE VARIANT SO IT CAN CONTAIN AN ERROR VALUE
v = GetInfoFromClosedFile(path, filename, sheetName, cellAddress)
If IsError(v) Then MsgBox "Sheet or filename doesn't exist!"
End Sub