I am creating a spreadsheet which links my customers to their regular orders.
For example: John Smith has eight different orders. So I have one workbook for John Smith and eight sheets within the workbook (one for each order). It needs to be like this because the orders are lengthy and require simple editing.
The spreadsheet in construction has a drop down list for the customers (B3), a drop down list for orders (F3) and a print button (Button10). Therefore you select a customer, select an order and hit print. I want this to then go to the directory (C:\Users\Julian\Documents\Customers), find the correct workbook and sheet, then go to print preview mode of the correct order.
I have very average VBA knowledge (I know how to make a button print preview the current worksheet, but that’s about it). I already have a cell which automatically shows the workbook name (T6) in the right format and automatically shows the worksheet name (T7) in the right format based on drop down selections.
I was wondering if someone could help me with some code to print the correct sheet from the correct workbook based on the drop down selections. If it can’t find the workbook or sheet, I wanted a pop-up message that says “There is no workbook or sheet under this search criteria” or something along those lines instead of a generic coding error.
Any help would be appreciated! Thank you!
Julian.
This is my first answer on Stack Overflow so please bear with me.
I work with databases for a living and I believe there is always a way to make things simpler, especially when you're using Excel, and even more so when you're open to using VBA. I suggest you upload a sample John Smith file and I can show you how to set up a more efficient way for what you're trying to do.
If you just need a quick answer, try the following suggestions.
Error Trapping When Workbook Does Not Exist
'Open the VBA Editor (Alt+F11) and create a new Module and paste the following code in:
Sub PrintOrder()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'-----------'
' VARIABLES '
'-----------'
Dim wb As Workbook, _
ws As Worksheet, _
wb_Client As Workbook, _
ws_Order As Worksheet, _
blOrder As Boolean, _
filDir As String, _
client As String, _
order As String, _
sht As Worksheet, _
xtsn As String
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Sheet1")
'Insert your actual sheet name in place of "Sheet1" or use the worksheet number such as wb.Worksheets(1)
filDir = "C:\Users\Julian\Documents\Customers\"
ChDrive "C"
ChDir filDir
client = Trim(LTrim(ws.Range("T6").Value))
order = Trim(LTrim(ws.Range("T7").Value))
xtsn = ".xlsx" 'Replace the extension below with whatever format your file is in or simply use xtsn = "" if you've already included the file extension in the T6 cell
'---------------------------------'
' CHECK IF CLIENT WORKBOOK EXISTS '
'---------------------------------'
If Dir(client & xtsn) <> "" Then 'the workbook exists so open it
Workbooks.Open Filename:=filDir & client & xtsn
Set wb_Client = ActiveWorkbook
'---------------------------------'
' CHECK IS ORDER WORKSHEET EXISTS '
'---------------------------------'
blOrder = False
For Each sht In Worksheets
If sht.Name = order Then
blOrder = True
Exit For
End If
Next
If blOrder Then 'worksheet exists so open its print preview window
'EDIT// I originally set ws_Order to wb.Worksheets(order) but the proper workbook should be the customer workbook that just opened
Set ws_Order = wb_Client.Worksheets(order)
ws_Order.PrintPreview
Else 'worksheet does not exist so throw into error
'//EDIT// I forgot the ampersand before the 'customer' string variable, which ruined the concatenation
Call MsgBox(prompt:="Order No. " & order & " has not been created for " & customer & "." & _
Chr(13) & "Please create a new order worksheet before continuing." & _
Chr(13) & Chr(13) & " Error Code: A002", _
Buttons:=vbOkOnly, Title:="ERROR: Missing Order Worksheet")
GoTo endProc
End If
Else 'workbook does not exist so throw into error
Call MsgBox(prompt:="No client workbook was found for " & customer & "." & _
Chr(13) & "Please create a new client workbook before continuing." & _
Chr(13) & Chr(13) & " Error Code: A001", _
Buttons:=vbOkOnly, Title:="ERROR: Missing Client Workbook")
GoTo endProc
End If
endProc:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Related
I need your help. I found the attached vba code but when I run the code I am getting a very strange 1004 error. Could you please give an explanation or try to fix this error?
Thank you so much all!
' Module to remove all hidden names on active workbook
Sub Remove_Hidden_Names()
' Dimension variables.
Dim xName As Variant
Dim Result As Variant
Dim Vis As Variant
' Loop once for each name in the workbook.
For Each xName In ActiveWorkbook.Names
'If a name is not visible (it is hidden)...
If xName.Visible = True Then
Vis = "Visible"
Else
Vis = "Hidden"
End If
' ...ask whether or not to delete the name.
Result = MsgBox(prompt:="Delete " & Vis & " Name " & _
Chr(10) & xName.Name & "?" & Chr(10) & _
"Which refers to: " & Chr(10) & xName.RefersTo, _
Buttons:=vbYesNo)
' If the result is true, then delete the name.
If Result = vbYes Then xName.Delete
' Loop to the next name.
Next xName
End Sub
These Excel built-in range names appear in the Excel name manager when using SUMIFS,IFERROR, COUNTIFS and other formulas.
There are a lot of ways around this, as suggested in the comments.
You can add either of these:
If Not xName.Name Like "_xlfn*" Then
'Or
If InStr(xName.Name, "_xlfn") = 0 Then
first thing in the loop (don't forget to close it), or something similar.
If you for some reason still want to see it, you can add it to the delete if:
If Result = vbYes And Not xName.Name Like "_xlfn*" Then xName.Delete
I would like to save file in a "CONSOLIDATE FOLDER". But the file path should depend on staff working number ID (00639) where they input it in the "TEMPLATE" worksheet cell "N3". And in case staff forgot to input their working ID, there'll be a pop up box telling them to fill in their ID.
Any help really appreciated.
Sub MergeFile ()
Dim WB As Workbook
Dim WS as Worksheet
Dim FileName as String
Dim FilePath as String
Set WB = Workbook.Add
FilePath = "C:\Users\KGA00639\Desktop\CONSOLIDATE FOLDER"
FileName = ThisWorkbook.Worksheets("TEMPLATE").Range("L15").Value
For Each WS in ThisWorkbook.Worksheets
If WS.Name <> "TEMPLATE" Then
WS.Copy before:=WB.Sheets(1)
End if
If FileName = "" Then
FileName = InputBox ("You did not name the workbook" & vbCrLf & _
"Please write the name and press OK.:,"Setting the workbook name")
If FileName = "" Then Exit sub
ThisWorkbook.Worksheets("TEMPLATE").Range("L15").Value = FileName
End If
Next
ActiveWorkbook.SaveAs FileName:=FilePath & "\" & FileName
MsgBox ("Done"!)
ActiveWorkbook.Close
End Sub
This solution should come rather close to what you want. Please take a look.
Sub MergeFile()
' 056
Dim Wb As Workbook
Dim Ws As Worksheet
Dim FileName As String
Dim FilePath As String
Dim UserID As String
With ThisWorkbook.Worksheets("TEMPLATE")
UserID = .Cells(1, "A").Value ' change address to suit
FileName = .Range("L15").Value
If Left(UserID, 2) <> "ID" Then
MsgBox "You must enter your valid user ID in" & vbCr & _
"cell A1 of the 'Template' tab." & vbCr & _
"This program will now be terminated.", _
vbInformation, "Incomplete preparation"
.Activate
.Cells(1, "A").Select ' change to match above
Exit Sub
End If
End With
Application.ScreenUpdating = False
' use the UserID variable in whichever way you wish
FilePath = Environ("UserProfile") & "\" & UserID & "\Desktop\CONSOLIDATE FOLDER"
Set Wb = Workbooks.Add
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "TEMPLATE" Then
Ws.Copy Before:=Wb.Sheets(1)
End If
Next Ws
Wb.SaveAs FilePath & FileName, xlOpenXMLWorkbook
Application.ScreenUpdating = True
End Sub
You didn't specify where on the 'Template' tab the user ID would be found. The above code looks for it in cell A1. That cell is mentioned in 3 locations in the code (once in the message text). Please modify the code to match your facts.
You also didn't say where the UserID should appear in the FilePath. I placed it before the Desktop. I'm sure you will know how to amend that bit of code to suit you better.
When saving the workbook my code specifies an xlsx format. If this isn't what you want change the file format constant in the SaveAs line. I didn't think it a good idea to specify the extension in the 'Template'. You may like to move it to the code.
Finally, you didn't specify the next step after creation of the new workbook. So the code ends in the middle of nowhere. Excel made the new workbook the active one but you may like to close it, or ThisWorkbook, and determine what to do with the blank worksheet(s) still contained in the new book. There are a lot of lose ends still to tidy up. Good luck!
I'm trying to insert formulas into my worksheet, but my first and second attempts haven't gone so well.
So, first I thought it would be better to use the GetOpenFilename feature for accuracy's sake, rather than having the user input the name of the workbook themselves. I used this page and this answer while writing it. When I run the code, the Open dialogue box opens, but when I select a workbook I keep getting a:
"Runtime Error '424': object required".
I'm not sure what it's asking for? At first I had just Application.GetOpenFilename(), so I thought I needed to add the filter, but it didn't help.
Sub openfile()
Dim mainwb As Workbook
Set mainwb = Application.GetOpenFilename("Microsoft Excel Files, *.xls*")
Dim mainws As Worksheet
mainws = InputBox("Please enter the name of the worksheet")
Dim rdsMonthly As Variant
rdsMonthly = InputBox("Please insert current month column in format $A:$A")
Dim rdsID As Variant
rdsID = InputBox("Please insert ID column in format $A:$A")
Cells(8, 14) = "=IFERROR(SUMIFS('[" & mainwb & "]" & mainws & "'!" & rdsMonthly & ", '[" & mainwb & "]" & mainws & "'!" & rdsID & ", $C55), " & Chr(34) & Chr(34) & ")"
End Sub
After, I tried using an Input box instead
Dim mainwb As Workbook
mainwb = InputBox("Please enter the name of the workbook, including file extension")
But that's giving me a:
"Runtime error '91': Object variable or With block variable not set".
I have no idea what it wants from me, and I'd really appreciate any help!
To get the name of the workbook, indicated with .GetOpenFileName, you may split once the big string through / and then get the last item. Then, split again by .xls and take the 0th item. With 1 line this 2 operations look like this:
Sub TestMe()
Dim filePath As String
filePath = Application.GetOpenFilename("Microsoft Excel Files, *.xls*")
Dim nameOfWb As String
'do not do this at production, but split it to variables:
nameOfWb = Split(Split(filePath, "\")(UBound(Split(filePath, "\"))), ".xls")(0)
Debug.Print nameOfWb
End Sub
Application.GetOpenFilename("Microsoft Excel Files, *.xls*") returns a string of the workbook path. And Workbooks() needs a workbook name, which is already opened.
Try this:
Sub TestMe()
Dim mainwb As Workbook
Set mainwb = Workbooks.Open(Application.GetOpenFilename("Microsoft Excel Files, *.xls*"))
MsgBox mainwb.Name
End Sub
Application.GetOpenFileName
I have a Workbook with multiple sheets which I want to select and convert to a single PDF file.
I have written the following code which works fine and creates the file:
Sub Print_Project_Report_To_PDF
Dim FilePathandName As String
MyDate = Format(DateSerial(Year(Now), Month(Now) - 1, 1), "mmmm yyyy")
MyPath = ThisWorkbook.Path & "\"
MyFile = "Project Progress Report - " & MyDate & ".pdf"
FilePathandName = MyPath & MyFile
ThisWorkbook.Sheets(Array("PR_COVER_PAGE", "PR_SUMMARY", _
"PR_PROJECT_DETAILS", "PR_INTERNAL RESOURCES", "PR_TIME", _
"PR_REVENUE_FORECAST_SUMMARY", "PR_ORIGINAL_REVENUE_FORECAST", _
"PR_ACTUAL_REVENUE_FORECAST", "PR_COSTS", "PR_ISSUES", "MONTHLY FINANCIAL REPORT", _
"PG-SC_COVER_LETTER", "PG-SC_CLAIM_SUMMARY", "PG-SC_TRADE", "PG-SC_HYDRAULICS", _
"PG-SC_MECHANICAL", "PG-SC_MEDICAL_GASES", "PG-SC_ELECTRICAL", "PG-SC_VARIATION", _
"PG-SC_MONTHLY_CASHFLOW", "PG-MH_COVER_LETTER", "PG-MH_CLAIM_SUMMARY", _
"PG-MH_TRADE", "PG-MH_HYDRAULICS", "PG-MH_MECHANICAL", "PG-MH_MEDICAL_GASES", _
"PG-MH_ELECTRICAL", "PG-MH_VARIATION", "PG-MH_MONTHLY_CASHFLOW", "CLIENT_COVER", _
"CLIENT_SUMMARY", "CLIENT_ISSUES")).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=FilePathandName, _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=True
ThisWorkbook.Sheets("Dashboard").Select
End Sub
The problem is that the PDF file is not created with the sheets in order which I have specified in the array. They are in the order which they appear in the Workbook (Left to right). It correctly only includes the sheets I want but not in the order i want.
I dont want to change the order of the sheets in the Workbook either because it is setup in a specific, progressive way.
Can anyone help me with code which will allow me to be specific with the order of the sheets when the document is published?
Any help would be greatly appreciated.
I agree with #SiddharthRout in first idea/comment below the question. However, in quite similar situation when I print complicated PowerPoint presentation I use
PDFCreator application
At the first step I run that software and set 'stop printing' option. Than you could send to that software (in the way you print worksheet) each worksheet separately which would be separate document stacked in the list in the right order at the beginning. Using special feature you can match them into one document then and print it. It's very useful and quite reliable solution.
Here is some sample VBA code how copy the current workbook into a temp file and reorder a list of sheets. Use such a routine before printing:
Sub CopyAndReorder()
Dim wbCopy As Workbook
ThisWorkbook.SaveCopyAs "C:\TEMP\XXXX.XLS"
Set wbCopy = Workbooks.Open("C:\TEMP\XXXX.XLS")
ReorderSheets wbCopy
End Sub
Sub ReorderSheets(wb As Workbook)
Dim shNames As Variant, shName As Variant, sh As Worksheet
shNames = Array("Table3", "Table2", "Table1")
For Each shName In shNames
Set sh = wb.Sheets(shName)
sh.Move After:=wb.Sheets(wb.Sheets.Count)
Next
End Sub
(You have to adapt this code snippet to your needs, of course, use a better temp file name, delete the new file afterwards, provide the list of sheets from outside, etc, but I think you get the idea).
I have this little VBA module that I call from one workbook to update all Excel Workbooks in a given folder. By update I mean it copies a module called GetActiveXControlValues and then runs this macro on each workbook in that folder. Now when I run this on my machine everything works fine. When my co-worker runs this same code with the same files, they gets a surprise after copying the module. When you go to look at the workbook that should have the new module called 'GetActiveXControlValues', instead there is no module by that name, instead it is called 'Module1'. In addition, when you look inside the new module it says 'Attachment has been removed' in red. I checked and my co-worker has the exact same Security Settings in Excel 2010 as I have.
I have enable all Macros and Trust VBA Project Object Model. I have Prompt me for enabling all ActiveX controls. I have Disable Trusted Documents unchecked and all the boxes on the Protected View tab. Anyone seen this before or have an idea what I can try to troubleshoot?
Sample Code:
Sub CopyModuleAndExecuteIt()
Dim wb As Workbook
Dim sFile As String
Dim sPath As String
Dim sFullMacroName As String
SetFolder
sPath = sExcelFolder
ChDir sPath
sFile = Dir("*.xls") ' File Naming Convention
Do While sFile <> "" ' Start of LOOP
' Open each Excel File in the specified folder
Set wb = Workbooks.Open(sPath & "\" & sFile) ' SET BP HERE!
Sleep (1000)
' Unprotect the Documents using SendKeys Hack
UnprotectVBADocument
' Import the GetActiveXControlValues Module into the Workbook
wb.VBProject.VBComponents.Import ("D:\GetActiveXControlValues.bas") ' SET BP HERE!
sFullMacroName = "'" & wb.Name & "'" & "!" & wb.VBProject.VBComponents.Item("GetActiveXControlValues").Name & ".GetActiveXControlValues"
' Run the GetActiveXControlValues Macro
Application.Run (sFullMacroName)
' Close the Workbook Saving Changes
wb.Close True
sFile = Dir
Loop ' End of LOOP
End Sub
If your co-worker has the exact same Security Settings in Excel 2010 as you have then the next thing that comes to my mind is the "Firewall". Check his firewall settings.
I was working to create an AddIn trough VBA code, i wrote the code in a Excel worksheet when i save it, i saved as text like this:
Attribute VB_Name = "Module_Name"
And you have to be sure that you .bas file is actualy is plain text.
I was working to create an AddIn with VBA code, i wrote the code in a Excel worksheet when i save it, i saved as text like this:
Sub Superheroes()
Dim sBeg as string, sEnd as String, sCatwoman as String, sAntMan as String
Dim vCode As Variant
'' Here is where i put the name i want to call my module
sBeg = "Attribute VB_Name = ""VBA_BasFile""" + vbCrLf + _
"Private Function fMix(sAnimal as String)as String "
sCatwoman = "Select case sAnimal"+ vbCrLf+ vbTab+"case ""cat"""+ _
vbCrLf+ vbTab+ "fMix = ""Catwoman"""
sAntMan = vbCrLf+ vbTab+"case ""Ant"""+ vbCrLf+ vbTab+ "fMix = ""AntMan"""+ _
vbCrLf+ "End Select"
sEnd = vbCrLf+ "End Sub"
vCode = Array(sBeg, sCatwoman, sAntMan, sEnd)
Workbooks.add
Range("A1").Resize(UBound(vCode) + 1, 1) = Application.Transpose(vCode)
With ActiveWorkbook
.SaveAs path + "VBA_BasFile.bas", xlTextPrinter
.Close False
End With
End Sub
With this i can Call any procedure or function in the VBA_BasFile when i importe to another Excel Workbook.