I have several commandbuttons in different sheet. Now I want the user to be able to run all at once if wanted. Therefore I want to use a new CommandButton that runs all CommandButtons in all Worksheets. However I allways get a error message..I have to approaches and have not worked out for me:
running the subs:
Private Sub CommandButtonX_Click()
run CommandButtonY_Click
run CommandButtonZ_Click
etc.
end sub
..Nothing happens
My other Approach is to select all worksheets and "activate the commmand button", which is always called CommandButton1_Click however I still donĀ“t know how to do it
This was my approach:
Sheets(Array("AA", "BB", "CC",etc.).Select
Sheets("AA").ActivateCall
Call CommandButton1_Click
End Sub
I am new at this, so I would really apreciate your Help!
Thanks!
Jens
This is purely a design opinion, but I would try and tackle this problem a different way.
My preference would be to have my subroutines in a separate module and simply call them from a button. That is, the _Click event simply looks something like this:
Private Sub Command1_Click()
Call DoSomeStuff
End Sub
While in a separate module all of my subs are grouped accordingly:
Sub DoSomeStuff()
Sheet1.Range("A1").Value = "Hooray for VBA"
End Sub
Using this method you avoid having to work with VBA's sometimes wonky (In my opinion) event handler and you can re-use subs with the appropriate arguments if they're called by several different buttons.
Then your "Master Button" just calls all the subs:
Private Sub Command1_Click()
Call DoSomeStuff
Call DoSomeMoreStuff
Call DoTheFinalStuff
End Sub
What error message do you get?
What version of Excel are you running?
This code runs fine in Excel 2007 on Windows 7:
Sub Button1_Click()
MsgBox ("Hey there, I'm button 1")
End Sub
Sub Button2_Click()
MsgBox ("Hey there, I'm button 2")
End Sub
Sub Button3_Click()
MsgBox ("Hey there, I'm button 3")
End Sub
Sub Button4_Click()
Button1_Click
Button2_Click
Button3_Click
End Sub
I have 3 buttons, each on a different worksheet, and they all display a message that identifies them. The 4th button is also on a separate worksheet and it displays the other 3 messages one after the other as would be expected.
Can you attach the error message to your post?
Related
I have a form which have referenced to previous form variable in the following code. I have change the scope to Public for the variable WorkflowName, however, error still happened.
Form 1:
Option Compare Database
Option Explicit
Public WorkflowName As String
Private Sub btn_CreditControlEmail_Click()
WorkflowName = "Email to Credit Control"
DoCmd.OpenForm "WorkFlow Email Preview"
End Sub
Form 2:
Option Compare Database
Dim frmPrevious As Form
Dim WorkflowName As String
Private Sub btn_ToOutlook_Click()
'update workflow status to Renewal Table
MsgBox frmPrevious![WorkflowName]
End Sub
Private Sub Form_Load()
Set frmPrevious = Screen.ActiveForm
End Sub
However, when run to second form
MsgBox frmPrevious![WorkflowName]
The following error happened.
In watching the value of frmPrevious in second form, I can see the "WorkflowName" value of frmPrevious.
If you want to refere to a variable in another form you can't use frmPrevious![WorkflowName], because that refers to a field in the first form that does not exist.
But use this: a dot and without brackets:
MsgBox frmPrevious.WorkflowName
Edit:
Another way to do this, and get the Intelisense to work, is by using the Form_ syntax.
Lets say Form 1 is named "WorkflowStart"
MsgBox Form_WorkflowStart.WorkflowName
I'm using PowerPoint 2016 for a Wallboard display and I'd like it to pull a number from an MSSQL-Server table. I can get the SQL data into Powerpoint easily enough but I would like the data to refresh every day automatically and leave the wallboard running continuously.
I have a textbox on a slide that pulls data from an SQL VBA script. Is there a way to automatically run the script each time the slide is shown while the presentation is running or have the script run once every 24 hours to refresh the textbox?
This is a tricky and interesting problem and I'll admit that this is most of the solution, but there is a missing part. I haven't done much programming in Powerpoint, so it was a challenge. When you open the VBE, there are no modules, classes, or objects of any kind available. This is quite different from Word and Excel. This means we're all on our own...
I created a Presentation with five slides. On the third slide, I inserted some objects so it looked like this:
For the VBA part, the first thing I had to learn was to create a class module that will catch all of the events for the presentation. My very simple class is called EventClassModule and looks like this:
Option Explicit
Public WithEvents App As Application
Private Sub App_SlideShowNextSlide(ByVal Wn As SlideShowWindow)
If Wn.View.CurrentShowPosition = 3 Then
UpdateTheCount Wn.View.Slide
End If
End Sub
So now in a regular module, you have to run something to create and initialize this class as a global object.
Option Explicit
Dim eventClass As EventClassModule
Sub InitializeApp()
Set eventClass = New EventClassModule
Set eventClass.App = Application
End Sub
In my testing, I just manually ran the InitializeApp procedure to create the global object. This is the missing part of my solution... - I don't know how to automatically run this initialization to create the object. Maybe a ribbon button?
Then, also in the regular code module is the procedure to update the textbox:
Public Sub UpdateTheCount(ByRef thisSlide As Slide)
'--- loop through all the shapes to find the correct textbox,
' then update the value for display
Const LABEL_TEXT As String = "Value to update:"
Dim shp As Shape
For Each shp In thisSlide.Shapes
If shp.Type = msoTextBox Then
Dim theText As String
theText = shp.TextFrame.TextRange.Text
If InStr(1, theText, LABEL_TEXT, vbTextCompare) = 1 Then
Dim colonPos As Long
Dim theValue As Long
colonPos = InStr(1, theText, ":", vbTextCompare)
theValue = CLng(Right$(theText, Len(theText) - colonPos))
theValue = theValue + 1
theText = LABEL_TEXT & " " & theValue
shp.TextFrame.TextRange.Text = theText
End If
End If
Next shp
End Sub
Once your code is in place and you've run the InitializeApp() sub manually, just start the slide show (and probably set it to loop from the end) and step through it. The textbox value will update and increment automatically.
I'm interested in learning how to kick this off automatically from someone who's got that experience.
I had a Run-time error
'-2147418105 (800100007)': Automation error The object invoked has disconnected from its clients.
which is raised once in a while. I can't relate it to a specific context for this error. The only clue I have is that before using ADO code I never had that error. The implemented pattern was used many times.
I use Excel 2016 32 bits on windows 7 with a vba code.
Private mForm As frmCfgPrjctTm
Public Sub U_CfgPrjctTm_OnOpen()
If (mForm Is Nothing) Then
Call U_UnlockTeam
Set mForm = New frmCfgPrjctTm
End If
'>>>>>> the error occurs after this comment
mForm.Show vbModeless
End Sub
The code to "close" the form is as following
Public Sub U_CfgPrjctTm_OnClose()
If (Not mForm Is Nothing) Then
mForm.Hide
Dim tmp As frmCfgPrjctTm
Set tmp = mForm
Set mForm = Nothing
Unload tmp
End If
End Sub
and in the form code (childCfgPrjctTmSettings and childCfgPrjctTmSettings are defined in an enum to falg a user action before closing the form)
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Call U_UnlockTeam
Select Case CloseMode
Case vbAppWindows, vbAppTaskManager
Call U_CfgPrjctTm_OnClose
Case vbFormControlMenu, vbFormCode
Call Save
Select Case mbOpenForm
Case childCfgPrjctTmSettings
' this opens another form
Call U_Sttngs_OnOpen(delUsr)
Case childCfgPrjctTmUsrId
' this opens another form
Call U_UsrLggd_OnOpen(dpyUsrLggdCfgPrjctTeam)
End Select
End Select
Cancel = False
End Sub
and in the form code
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Call U_UnlockTeam
Select Case CloseMode
Case vbAppWindows, vbAppTaskManager
Call U_CfgPrjctTm_OnClose
Case vbFormControlMenu, vbFormCode
Call Save
Select Case mbOpenForm
Case childCfgPrjctTmSettings
Call U_Sttngs_OnOpen(delUsr)
Case childCfgPrjctTmUsrId
Call U_UsrLggd_OnOpen(dpyUsrLggdCfgPrjctTeam)
End Select
End Select
Cancel = False
End Sub
This error is raised after creating a form and at the very moment to show it up.
The call U_UnlockTeam involves some ADO code called inside to retreive data from a data base. The form has no Activate event handler.
Did some one have the same issue and how did you cope with ?
I am able to reproduce the error. The issue is that you unload the form inside the form. Take just an empty userform and the following code in a module. Run the code and close the form by clicking on X. There should be no code behind the form! If you run the code a second time you will get the error mentioned.
Option Explicit
Private mForm As UserForm1
Public Sub U_CfgPrjctTm_OnOpen()
If mForm Is Nothing Then
'Call U_UnlockTeam
Set mForm = New UserForm1
End If
'>>>>>> the error occurs after this comment
mForm.Show vbModeless
End Sub
Reason of the behavior is that the class destroyed itself and mForm is a module wide variable which does not know it was destroyed when calling the code the second time.
Solution would be to avoid a self-destroing class/userform or as a workaround make mForm a local variable.
Here is a better explanation
https://excelmacromastery.com/vba-user-forms-1/#Cancelling_the_UserForm
I've seen a few other posts about this but I seem to be confused since I've seen it done several ways and haven't gotten it correct any of the ways, so I thought I would ask specifically for my case so I can learn what I am doing wrong. After learning and switching to C# for most of my programming, VB.net seems so clunky in its syntax with a lot of things, especially lambda and "on-the-fly" functions.
I have a long running task for a football game I am working on where it generates players. Its an async method utilizing the Task.Factory.StartNew method.
Here is the pertinent code:
Private Sub CreateDraft_Click(sender As Object, e As RoutedEventArgs) Handles CreateDraft.Click
TimeIt(Sub() ReallyGenNewPlayers())
End Sub
'Uses a stopwatch to time how long it takes and sends to console.
Private Sub TimeIt(MyAction As Action)
Dim SW As New Stopwatch
SW.Start()
MyAction()
Console.WriteLine($"Total Time Generating Players: {SW.Elapsed} seconds")
SW.Stop()
End Sub
Private Async Sub GenNewPlayersASync()
Dim myvalue = 0
'Generate the Players on an Async Thread
Dim x As Integer
For i As Integer = 1 To NumPlayers
x = i 'avoids issue with using the iteration variable inside the delegate
CollegePlayers.GenDraftPlayers(i, MyDraft, DraftDT, DraftClass, PosCount)
'Prog_ValueChanged(DBNull.Value, New RoutedPropertyChangedEventArgs(Of Double))
'Calls a delegate to update the progress bar to avoid having the variable locked by the background thread
Dispatcher.Invoke(Sub()
worker.ReportProgress((x / NumPlayers) * 100)
End Sub)
Next i
End Sub
'Creates a task to run the player generation code and wait til its finished
Private Sub ReallyGenNewPlayers()
Dim mytask = Task.Factory.StartNew(Sub() GenNewPlayersASync())
Task.WaitAll(mytask)
End Sub
So here is what I would like to do:
I have a progressbar I created in XAML that has a Progress_Changed Event. This is what I have for it so far based on another post, but the issue is when I have to call the function inside GenNewPlayersAsync() where it wants a RoutedPropertyChangeEventArgs as a double which I'm not exactly sure what to do...I tried creating one using .New(old value, new value) but that didn't work either and threw an error.
Public Async Sub Prog_ValueChanged(sender As Object, e As RoutedPropertyChangedEventArgs(Of Double))
Dim progress = New Progress(Of Integer)(Function(percent)
Prog.Value = e.NewValue
Return Prog.Value
End Function)
Await Task.Run(Sub() DoProcessing(progress))
End Sub
Public Sub DoProcessing(progress As IProgress(Of Integer))
Dim i As Integer = 0
While i <> 100
Thread.Sleep(100)
' CPU-bound work
If progress IsNot Nothing Then
progress.Report(i)
End If
End While
End Sub
I would like for the progressbar to be bound to an INotifyChanged Property and update itself automatically when the value gets changed. None of it seems to be working. The UI is still unresponsive and when I set different parts to ASync, I start getting Exceptions where it appears certain parts of the generation algorithm aren't working as they are returning null...very confused with all of this, and I am sure the answer is probably pretty simple...
If you guys could give several examples of different ways to get this to work so I can learn different methods and maybe state the pros and cons of the method I would greatly appreciate it...
I found an Excel VBA solution to allow users to expand/collapse grouped rows and columns, while keeping the worksheet protected, here: http://www.mrexcel.com/forum/excel-questions/711327-allow-users-click-group-ungroup-protected-sheet-visual-basic-applications.html
For a single worksheet my code looks like this:
Private Sub Workbook_Open()
With Worksheets("Master data")
.Protect Password:="", UserInterfaceOnly:=True
.EnableOutlining = True
End With
End Sub
Note: I left the password for the worksheet empty (string: "")
However, I need to allow users to do the same thing on another worksheet called "CPM" as well. To acheive this I came up with the following code:
Private Sub Workbook_Open()
Dim sheetsArray As Sheets
Set sheetsArray = ActiveWorkbook.Sheets(Array("Master data", "CPM"))
Dim sheetObject As Worksheet
For Each sheetObject In sheetsArray
With Worksheets(sheetObject)
.Protect Password:="", UserInterfaceOnly:=True
.EnableOutlining = True
End With
Next sheetObject
End Sub
The line
With Worksheets(sheetObject)
causes na error (Excel indicates the types don't match: I imagine Excel requires a string here).
Is there a quick fix to resolve this?
Kind regards,
Dennis
Use
With sheetObject
instead of
With Worksheets(sheetObject)