Input Box on workbook open - vba

I am trying to come up with some vba code to open an input box automatically as soon as the workbook is opened and have the user enter a date and then have the date placed in the A1 cell. I have written the code below but the input box is not pulling up at all it just opens the workbook and moves on.. not sure what is happening. Any and all help is appreciated.
Thanks!
Option Explicit
Private Sub workbook_open()
Dim cellvalue As Variant
Dim ws As Worksheet
Set ws = Worksheets("Workbench Report")
ReShowInputBox: cellvalue = Application.InputBox("Please Enter Todays Date (dd/mm/yyyy)")
If cellvalue = False Then Exit Sub
If IsDate(cellvalue) And CDate(cellvalue) < Date Then
ws.Range("A1").Value = DateValue(cellvalue)
Else: MsgBox ("Invalid Date!")
GoTo ReShowInputBox
End If
End Sub

Your code triggers upon the Workbook opening for me. Try these steps.
Open up Excel and Save As, changing the extension to .XSLM
Open up the VBA Editor (ALT + F11)
In the left-hand window, locate your macro file (the one you just created and named - it's in brackets after "VBA Project"), drilldown to "This Workbook" and double-click it.
Paste your code into the right-hand window
Save the file and re-open.
See attached diagram.
By the way, "cellValue = false" should probably be cellValue = "" since InputBox is returning a string and not a boolean value.

For Workbook_Open events the script needs to reside in the private module (ThisWorkbook)
From Ozgrid:
the Workbook_Open event is a procedure of the Workbook Object and as
such, the Workbook_Open procedure MUST reside in the private module of
the Workbook Object (ThisWorkbook).

Related

VBA - Run-time error '1004'

A bit of context, this is my first time programming using VBA in excel,
and I'm trying to create a form that fills out a spreadsheet.
I'm currently getting the error message: "Run-time error '1004': Method 'Worksheets'of object '_Global' failed
I've searched online and have tried various solutions, but I think basically it comes down to a lack of understanding on my part.
Private Sub CommandButton1_Click()
'When pressing save, save values in spreedsheet locations
ActiveSheet.range("c8").Value = ContactName.Value
ActiveSheet.range("b19").Value = ModelNumber.Value
ActiveSheet.range("d19").Value = SerialNumber.Value
ActiveSheet.range("g19").Value = IncidentNumber.Value
ActiveSheet.range("j19").Value = Description.Value
ActiveSheet.range("c7").Value = PortLocation.Value
'save file
ActiveWorkbook.SaveAs Filename:= _
"D:\Users\611281\Downloads\Zebra\EmailMeToZebra.xlsx", FileFormat:=xlOpenXMLWorkbook, ReadOnlyRecommended:=False, CreateBackup:=False
End 'after pressing save, close down sheet.
End Sub
Private Sub UserForm_Initialize()
Me.PortLocation.List = Worksheets("Data lookup_ports").range("e3:e200").Value
Dim MyTempWkBk As Workbook
Dim MyCurrentWin As Window
Set MyCurrentWin = ActiveWindow
Set MyTempWkBk = Workbooks.Open("D:\Users\611281\Downloads\Zebra\GUI.xlsm")
MyCurrentWin.Activate 'Allows only a VERY brief flash of the opened workbook
MyTempWkBk.Windows.Visible = False 'Only necessary if you also need to prevent
'the user from manually accessing the opened
'workbook before it is closed.
'Operate on the new workbook, which is not visible to the user, then close it...
End Sub
Private Sub UserForm_Terminate()
End 'when pressing x, close down window, do not save.
End Sub
I'm getting the error on the code:
Me.PortLocation.List = Worksheets("Data lookup_ports").range("e3:e200").Value
Which is just me trying to populate a ListBox from a spreadsheet range
Have you tried naming the workbook? This is assuming the line with the error is referring to a cell range in thisworkbook. Also, make sure to check the name of the sheet you are referring to for exact spelling (if spelling appears correct, also check for lagging spaces.) Also, is the worksheet hidden? If so, this may need to be added before calling the sheet.
wb.sheets("Data lookup_ports").Visible = True
Can try the below edit in the meantime.
Private Sub UserForm_Initialize()
Dim MyTempWkBk As Workbook
Dim MyCurrentWin As Window
Dim WB as Workbook
Set WB = ThisWorkBook
wb.sheets("Data lookup_ports").Visible = True
Me.PortLocation.List = WB.Sheets("Data lookup_ports").Range("E3:E200").Value
Set MyCurrentWin = ActiveWindow
Set MyTempWkBk = Workbooks.Open("D:\Users\611281\Downloads\Zebra\GUI.xlsm")
MyCurrentWin.Activate
MyTempWkBk.Windows.Visible = False 'Only necessary if you also need to prevent
'the user from manually accessing the opened
'workbook before it is closed.
'Operate on the new workbook, which is not visible to the user, then close it...
End Sub
Private Sub UserForm_Terminate()
End 'when pressing x, close down window, do not save.
End Sub

VBA Excel | Submit information/modification to a worksheet before _Open Event executes

On its own workbook "A" starts with checking if there is a settings file saved locally, that stores the User's credentials for autologin.
If there is no such file, it will show a login form.
I would like to add now the functionality that if I open workbook"A" from workbook "B" it should try to fetch the logged in user of WorkBook"B" instead of starting with checking the local settings file first.
There is a variety of WB-s that could call "A", so i would not go for putting a code in A to check a cellvalue in B, instead I would like to have B modify something in A upon opening.
The problem is:
When i open "A" from "B", any modification is only implemented after every code executed from _Open macro, so it cannot recognize in time, that actually i would like to pass extra information to that process.
like this:
Sub Test 'In Wb"B"
Dim Wb as workbook
Set Wb = Workbooks.Open(path)
Wb.Sheets(1).Range("A1").Value = "NewValue"
End sub
'----
Private Sub workbook_open() ' In Wb"A"
MsgBox ThisWorkbook.Worksheets(1).Range("A1").Value
End Sub
MsgBox will show "OldValue", because the external change will take place after the _Open event.
I have also tried to pass a parameter like _Open(optional Modifier as variant), but as I suspected, Events cannot accept parameters like that, right?
So how to provide extra info to Wb"A" from Wb"B" upon opening, before anything else happens?
One possible, but not preferred method I can think of is via command line parameters, like discussed in here:
Passing a parameter to an Excel file when opening it
Is there any other solution to achieve the requied results?
you could use the last workbook opened before "A" as a "messenger"
for instance should "B" the last opened workbook, you would have the following Test() sub:
Sub Test() 'In Wb"B"
Dim Wb As Workbook
Sheets(1).Range("A1").Value = "NewValue" ' use a convenient sheet and cell in "B" workbook to store the value you want to "pass" to "to-be-opened-soon" workbook
Set Wb = Workbooks.Open(path)
End Sub
and in "A" ThisWorkbook code pane you would then place:
Private Sub workbook_open() ' In Wb"A"
ThisWorkbook.Worksheets(1).Range("A1").Value = Workbooks(Workbooks.Count - 1).Sheets(1).Range("A1").Value 'retrieve the value from the last opened workbook
MsgBox ThisWorkbook.Worksheets(1).Range("A1").Value
End Sub

Excel VBA - How to use worksheet event in add-in module?

I am new to Excel Add-ins and I am not sure how to write mi programm.
I would like to put in an add-in a code so that, when the workbook that uses the add-in is opened, it creates a sheet named "mainSheet".
I can use the event handler in the Workbook, but is it possible to put the code in the module of the add-in and still be able to run it?
I found this on the "Automate Excel" web site. Hope this helps
The following code works opening a workbook. It automatically adds a new sheet and labels it with the name. It also checks to see that the sheet doesn’t already exist – to allow for the possibility of it being opened more than once a day.
This code makes use of the Workbook Open Event and must be placed in the workbook module under the “Open work Book” event. The function Sheet_Exists must be placed in a module and this checks whether or not the sheet exists:
Private Sub Workbook_Open()
Dim New_Sheet_Name As String
New_Sheet_Name = "mainSheet"
If Sheet_Exists(New_Sheet_Name) = False Then
With Workbook
Worksheets.Add().Name = New_Sheet_Name
End With
End If
End Sub
==
Function Sheet_Exists(WorkSheet_Name As String) As Boolean
Dim Work_sheet As Worksheet
Sheet_Exists = False
For Each Work_sheet In ThisWorkbook.Worksheets
If Work_sheet.Name = WorkSheet_Name Then
Sheet_Exists = True
End If
Next
End Function

Running excel macros only on one sheet

Hi Iam new to writing VBA code and need assistance. My VBA code and Macro works fine as long as I am on the active sheet.
My Problem:
My VBA code and macro, stops running automatically, when i change from the active sheet to another within the same workbook and
My VBA code and macro, stops running automatically, when i open a new excel workbook
Solution required:
Run the VBA code and macro only on desired worksheet and prevent it from running on other worksheets and workbooks.
Background:
I have an excel file, named "Net Weight" with two sheets. sheet 1 is named : "weight", sheet 2: is named "base data".
sheet 1 is used as a user input form.
In sheet 1- cell B1 : user will type in a product code , in cell E1: a look up formula will place the description of the product code using the data from sheet 2
I have setup a VBA code and macro that does the following:
As soon as a user inputs a product code into cell B1, in sheet 1, sheet 1 is saved as PDF file into a predefined folder location data from cell B1 and E1
A macro saves and overwrties the PDF file every 10 seconds.
This process is repeated every time a new product code is entered
There are no buttons on sheet 1, everything is done automatically.
Here is my current code:
Sheet 1: set as Worksheet
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$1" Then
Call Macro1
End If
End Sub
Module 1 macro : set as general
Sub Macro1()
Application.DisplayAlerts = False
If ThisWorkbook.Name = "Nett Weight.xlsm" And ActiveSheet.Name = "Weight" Then
Sheets("Weight").ExportAsFixedFormat Type:=xlTypePDF, _
Filename:="C:\Nett weight\" & Range("B1 ").Text & Range(" E1").Text
Application.OnTime Now + TimeValue("00:00:10"), "Macro1"
Else
Exit Sub
End If
End Sub
First, you need to create a public variable to hold your timer, otherwise you'll never be able to cancel it so it will continue trying to fire even when your workbook is closed. You should also create a public variable to store when the timer is running, so you can check before creating a new timer.
At the top of a code module put:
Public nextTime As Date
Then in your Workbook_BeforeClose() event method (within ThisWorkbook), disable the existing timer so it doesn't keep trying to fire after the workbook is closed.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next ' Continue with next line of code if we encounter an error
Application.OnTime Earliesttime:=nextTime, Procedure:="Macro1", Schedule:=False
On Error GoTo 0 ' Resume error-trapping
End Sub
In Macro1() you should explicitly and directly reference your workbook components - ThisWorkbook always refers to the workbook the code is running from, so you don't need your If statement. Then you set the nextTime and activate the timer using that variable if it is not already running.
Sub Macro1()
Dim sht As Worksheet ' Creates a variable to hold your Weight worksheet
Set sht = ThisWorkbook.Sheets("Weight") ' Sets the reference
Application.DisplayAlerts = False
sht.ExportAsFixedFormat Type:=xlTypePDF, Filename:="C:\Nett weight\" & sht.Range("B1").Text & sht.Range("E1").Text ' Remember to preceed Range with sht. to explicitly reference the range of your Weight worksheet
On Error Resume Next ' Continue with next line of code if we encounter an error
Application.OnTime Earliesttime:=nextTime, Procedure:="Macro1", Schedule:=False
On Error GoTo 0 ' Resume error-trapping
nextTime = Now + TimeSerial(0, 0, 10) ' Adds 10 seconds to Now
Application.OnTime Earliesttime:=nextTime, Procedure:="Macro1", Schedule:=True
timerIsRunning = True
Application.DisplayAlerts = True ' Remember to enable alerts at the end of code
End Sub
Your Worksheet_Change() event method can stay as is. Now if there is a change in B1 it will call Macro1(). Macro1() will save the Weight worksheet as a PDF regardless of whether the workbook or worksheet is active, and create a new timer to re-run Macro1() every 10 seconds after deactivating an existing timer. When you're finished with the workbook, you close it and the existing timer is also deactivated.
EDIT:
Fortunately (as it fixes a spreadsheet of my own) I have figured out why the solution I originally provided wasn't working. Placing the Public variables under ThisWorkbook meant they no longer held their values after code execution. The remedy was to place them in a module instead. Once that was sorted out, I also realised that when the timer fires to call Macro1() it will throw an error when trying to unschedule the existing timer (as none exists unless Macro1() was called ad hoc by the Worksheet_Change() event).
Long story short: Public variables have been moved to a code module, and the timerIsRunning flag has been removed entirely and errors when attempting to unschedule the timer are simply ignored in the event that no timer exists.

VBA: Populating ListBox ActiveX control, on worksheet and not user form

I'm trying to populate a List Box (ActiveX control). This list box is on a sheet labeled "Dashboard" of my workbook, and not a user form. I want to populate it with a range from a sheet labeled "Data".
My problem is that if I populate it on the workbook open event procedure, I get an error when the workbook opens that it "Can't execute in break mode." However, there aren't breakpoints active at all.
If I populate it on the "Dashboard" worksheet active event procedure, it won't populate when the workbook is open. It only populates if I click on another worksheet, and then go back to the Dashboard worksheet, then it will populate.
Is there a better way to populate the list box so that it's always populated and ready to go? I have a lot of vLookup functions that are associated with the list box, and if the list box is not populated, then the rest of my code won't work.
I will post my codes that I have so far. The first is when I attempt to populate the listbox through the workbook_open even procedure. The second is through the "Dashboard" worksheet activate procedure.
Private Sub Workbook_Open()
Dim strName As String
Dim blDone As Boolean
Dim cPlanets As MSForms.ListBox
Dim vArray As Variant
Dim shtData As Worksheet
Dim wkbSolarSystem As Workbook
Set wkbSolarSystem = Application.Workbooks("workbookname.xlsm")
Set shtData = wkbSolarSystem.Worksheets("Data")
Set cPlanets = wkbSolarSystem.Worksheets("Dashboard").lstPlanets
vArray = shtData.Range("Planets").value
cPlanets.List = vArray
cPlanets.ListIndex = 3
'input box message for user when workbook opens up
strName = InputBox("Hello! Please enter your name", "Welcome!")
'check if there is a name entered via loop and if statement
Do
If Len(strName) = 0 Then
'if no name entered, ask user again
MsgBox ("Please enter a valid name to continue"), vbCritical, "Valid Name Required"
'ask user to type in name again
strName = InputBox("Hello! Please enter your name", "Welcome!")
Else
'display message with information for user
MsgBox ("Hello, " & strName)
blDone = True
End If
'finish loop statement
Loop Until blDone = True
This next code is the one I have on Sheet3 code worksheet activate procedure
Private Sub Worksheet_Activate()
Dim shtData As Worksheet
Dim wkbSolarSystem As Workbook
Set wkbSolarSystem = Application.Workbooks("workbookname.xlsm")
Set shtData = wkbSolarSystem.Worksheets("Data")
lstPlanets.List = shtData.Range("Planets").value
lstPlanets.ListIndex = 3
End Sub
You are declaring cPlanets as MSForms.ListBox, but in your question you say you are working with an ActiveX listbox on a sheet. So you should declare cPlanets as an Object, like:
Dim cPlanets As Object
Set cPlanets = wkbSolarSystem.Worksheets("Dashboard").lstPlanets
I tried this code on a different computer, and it works. It seems that it's the computer configuration that was causing the issue. The code works fine as it should on several different computers.