Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am trying to convert an old Fortran program with a lot of nested goto statements to VBA but I am getting error mentioned in the title. The way I am converting is each statement, I made it a function and instead of goto then i call the function or statement, but apparently that's not a proper way of doing it. What else can I do? Thanks in advance.
If you cannot see where the endless loop is, try adding a public counter to all of the functions. If it exceeds a given value, stop the program. Then try to debug with F8 to see the endless loop. I mean something like this:
Option Explicit
Public counter As Long
Public Sub TestMe()
While True
FunctionSomething
Wend
End Sub
Public Function FunctionSomething()
counter = counter + 1
If counter > 100 Then Stop
End Function
Now if you run TestMe it would stop on the 100th iteration.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I Believe this question is very common but I am getting a very unique situation.
I have a code that I am using for delay delivery.
But the problem is I am unable to run the macro.
Public Sub Applicaion_Reminder(ByVal Item As Object)
Dim objPeriodicalMail As MailItem
If Item.Class = olTask Then
If InStr(LCase(Item.Subject), "send an email periodically") Then
Set objPeriodicalMail = Outlook.Application.CreateItem(olMailItem)
'Change the following email information as per your actual needs
With objPeriodicalMail
.Subject = "Email to Gmail"
.To = "bfarhan8#gmail.com"
.HTMLBody = "<HTML><BODY>It's a Test</HTML></BODY>"
.Importance = olImportanceHigh
.ReadReceiptRequested = True
.Send
End With
End If
End If
End Sub
When I hit on the run it asks me for Macro Name when I define a name it creates a new Sub.
If I remove the parameters of the
Application_Reminder()
to match the name with a macro name It gives an error on line number 3.
My question is how to run this Macro Properly. I searched the web but didn't find any useful help.
What you have missed is that macros can either be subroutines or functions and for each there are two major types.
A subroutine does something. Your Application_Reminder is a subroutine because it does something: send a reminder. A function can do something, but its real purpose is to return a value.
Some subroutines and functions need parameters, but some do not.
If I write a function Sqrt, the immediate question is: square root of what? I want to be able to write:
Answer = Sqrt(5)
That is, today I want the square root of 5. Tomorrow, I might want the square root of 7.
I would write:
Function Sqrt(ByVal Number as Double) as Double
‘ Code to calculate square root of Number
Sqrt = ResultOfCalculation
End Function
Almost all functions have parameters, but it is not essential. I could have a function, GetCurrentTemperature that reads a thermometer and returns a temperature. It would not need a parameter.
You have written a subroutine that has a parameter: Applicaion_Reminder(ByVal Item As Object). When you try to run Applicaion_Reminder, the interpreter wants to know what Item. I do not think the interpreter’s response is very sensible. It should have just told you, “You cannot run a subroutine with a parameter.”
You need a subroutine without a parameter that decides which Item is to be processed. With some computer languages, that subroutine must have the name Main. With VBA it can have any name.
That is, you need a subroutine like this:
Sub PickAnItemThatNeedsAReminder()
Dim Item as Object
‘ Code to set Item to the required MailItem
Call Applicaion_Reminder(Item)
End Sub
There are four distinct methods of selecting a MailItem. I imagine you scrolling down your Sent Items folder looking for emails to which you have not received a reply. When you find such an email, you run PickAnItemThatNeedsAReminderwhich sends a reminder.
Sub PickAnItemThatNeedsAReminder ()
Dim Exp As Explorer
Dim Item As Object
Set Exp = Outlook.Application.ActiveExplorer
If Exp.Selection.Count = 0 Then
Call MsgBox("Please select one or more emails then try again", vbOKOnly)
Exit Sub
Else
For Each Item In Exp.Selection
Call Applicaion_Reminder(Item)
Next
End If
End Sub
Exp.Selection is a list of all the currently selected emails. You can select as many emails as you want and them run PickAnItemThatNeedsAReminder. It will call Applicaion_Reminder for every selected email.
Additional Background
My belief is you have found a routine that runs off an event and have tried to adapt it to your requirements. Events are an incredibly useful feature of Outlook. However, if you do not yet understand that you cannot run a macro without a parameter, you are not yet ready for events. We say: walk before you run.
BraX and Super Symmetry would be correct in telling you to use ThisOutlookSession if you are going to use events. I have suggested you use Explorer (which is technically an event) but which is much easier for a beginner to understand than an application level event which is what you seemed to have found. With my approach, all your code can be in an ordinary module.
Application.Reminder event Occurs immediately before a reminder is displayed
set up Task Item with reminder then call your vba function - Applicaion_Reminder
See example on this answer
https://stackoverflow.com/a/40144594/4539709
if you want to call it with selected email then see Tony's answer
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I know this is a dumb question probably already answered, but I can't find an easy to search for it. My question is should I be using "else" when I don't need to? Using VB.NET...
Function IsHappy(hasBeer As Boolean)
If hasBeer = True Then Return "Happy"
msgbox("I'm sad")
Return "Sad"
End Function
Or...
Function IsHappy(hasBeer As Boolean)
If hasBeer = True Then
Return "Happy"
Else
msgbox("I'm sad")
Return "Sad"
End If
End Function
These look the same to me, except that the first one is just a bit less code to look, but the second one is a bit clearer though more verbose. Is there a reason to pick one of these over the other?
Edit: Removed the obvious short cut of just returning hasBeer and made it slightly more complex
To clarify, I'm just trying to figure out if there is a good reason to use an else statement when the IF is going to exit your early if you don't. Is it just a style choice with no clear preference?
It depends.
Here, I'd use an early exit:
Function IsHappy(hasBeer As Boolean) as Boolean
If hasBeer Then
Return True
End If
' Complicated logic to determine whether another reason
' for being happy can be determined
...
Return False ' No reason found
End Function
Here, I'd use If and Else:
Function IsHappy(hasBeer As Boolean) As Boolean
If hasBeer Then
' Do some side effects
...
Return True
Else
' Do other side effects
...
Return False
End If
End Function
In your example, I'd simply use
Function IsHappy(hasBeer As Boolean) As Boolean
Return hasBeer
End Function
I know your hasBeer flag is just an example - the logic is likely to be much more complex.
I prefer the first option because there is less visual clutter. I might add whitespace before the last line - it makes it very clear that any path that gets this far returns false.
Verbosity is not, in and of itself, a problem. Performance being equal, clarity almost always trumps clever code in real world applications.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have a textbox of maxLength 8. the 1st two characters must be "PM" or "00". I tried split(), but didnt work.
Use substring() method
Dim s As String = TextBox1.Text.Substring(0, 2)
If s = "PM" Or s = "00" Then
MessageBox.Show("good!")
Else
MessageBox.Show("bad!")
End If
Or you can use StartsWith()
If TextBox1.Text.StartsWith("PM") OR TextBox1.Text.StartsWith("00") Then
'Do something
End If
Another option is to use regular expressions:
Dim re As New Regex("PM|00")
If re.IsMatch(TextBox1.Text) Then
'do something
End If
The benefit is that when you decide what to do with the other 6 characters, you can modify the above to capture and return those (in full or part), without having to rewrite your code. You can even process multiple occurrences of PM|00 in one string and capture them all.
Useful resource, a Regex sandbox:
https://www.regex101.com/
Maybe you can try this:
if textbox1.text like "PM*" or textbox1.text like "00*" then
Do something
else msgbox("You don't have pm or 00 to start with!")
end if
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Many of the applications I develop tap into the databases of pre-existing applications (I develop largely for small businesses that are trying to expand cheaply); A lot of this kind of work involves grabbing information out of other applications' databases (for example "site name", etc).
I normally have class libraries to do this kind of work, saving on database calls where possible. For example I might have a function like the below:
Private Function GetSiteName(ByVal dbPath As String) As String
Dim returned As String
Dim conn As New AdsConnection("data source = " & Path & "; ServerType=remote|local; TableType=CDX")
Dim cmd As AdsCommand
Try
conn.Open()
cmd = conn.CreateCommand()
cmd.CommandText = "select stSiteName from Sites;"
returned = cmd.ExecuteScalar
conn.Close()
Return returned
Catch e As AdsException
' write to log here
End Try
End Function
(For those not familiar, in the particular example above I'm accessing a database from Advantage Database Server).
In the above example, I would get a warning saying not all code paths return a value. If I move the Return statement to just before the End Function (outside the Try...Catch block, I would get a warning saying the variable may not be initialised.
Is there a standard/preferred way of handling this? At the moment I generally handle by putting the error message into the returned value, then testing for it from the calling code but it feels clunky to me.
The problem is that you handled the exception in your function. A handled exception is transparent to the caller, i.e. code outside this function will have no way of determining whether the exception was raised. This design is only correct when your function behaves correctly even when a exception is raised (hence can be handled).
When the catch statement is executed, the function does not know what value to return. That is the problem. You should not catch the exception at this level. You should let the exception raise, then past it to the upper level, where you can show appropriate error messages to the user.
The problem you are facing has nothing to do with Error Handling in particular. The compiler issues a warning if a function doesn't return something on all code paths, and you can choose it ignore it, since it is not categorized as an Error.
e.g. You will get the same warnings with If...Else if the code inside either If or Else doesn't return a value. Similarly you will get the warning in a Select..Case block if at least one of the Case blocks don't return a value.
It is however good to pay attention to what warnings the compiler issues and minimize the number of such warnings.
There are two approaches around this problem.
Keep multiple exit points in your function and ensure that all the exit points return some value.
Initialize your variable with some default value, and keep only one exit point for the function.
While it is debatable which one of the above is better, I personally like the second approach. It is better from code maintenance perspective too (when the function is too large).
For Example, you can initialize the variable with empty value or nothing to get rid of that warning.
Dim returned As String = String.Empty
...
Try
...
Catch e As AdsException
...
End Try
...
Return returned
In this example, you have 4 code paths from where the function can exit out (shown by ... in the example above). Assume that you had 10 or 15. You get a warning if you do not set the return value on any of the code paths. The above solution solves the problem by initializing the variable at the beginning, and return it at the end. Then you need not worry which code path sets the variable and which doesn't.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I would like to add a counter to a power point presentation. Someone mentioned to me that this might be doable in VBA. Do you know if this could be done in VBA and how?
Basically here is what I would like to do:
display a counter representing for example the number of cars rented since the beginning of my presentation. So for example, at the start the counter is at 0 and every minute is incremented of 2000 (this is just an example). We can see the counter on every slide, so at the end of my talk people can see (and I'll tell them) that since the beginning of the talk X(large number) cars have been rented.
I tried to find something on the internet but without success... I hope someone will be able to help me?
I give you some ideas. Possibly they will be helpful even I do not provide any code.
Generally you need to have something like 'timer' in your presentation which would start with your presentation and count the time used. Unfortunately there is nothing like this in PowerPoint. You could possibly use some external solution like C# COM add-in but it's rather very complicated.
You could use PP application events but value of the car will not change every minute but every new slide you enter or any other event fires (like moving reverse, etc). It's a bit complicated but within our (StackOverflow users) knowledge.
You could possible search or ask under that link where I used to find lot's of interesting ideas.
I promised to provide solution therefore I'd like to do it even the question is closed. Therefore I do it by re-edition of that answer which I hope is allowed.
We have to be sure that there is a 'text box' where 'count value' would be placed on each slide. Add the following code into Module1 and run it.
Sub Add_CarValue_Text()
Dim SLD As Slide, SHP As Shape, shCarValue As Shape
Dim boCarValue As Boolean
For Each SLD In ActivePresentation.Slides
For Each SHP In SLD.Shapes
If SHP.Name = "CarValue" Then
boCarValue = True
Exit For
End If
Next
If Not boCarValue Then
Set shCarValue = SLD.Shapes.AddTextbox(msoTextOrientationHorizontal, 0, 0, 150, 50)
With shCarValue
.Name = "CarValue"
.TextFrame.TextRange.Text = "Cars counter: "
End With
End If
boCarValue = False
Next
End Sub
Add new Class Module and place below code there. Change if necessary.
Public WithEvents PPApp As Application
Private TimerStart As Long
Private Const increasePerMinute = 1000
Private Sub PPApp_SlideShowBegin(ByVal Wn As SlideShowWindow)
TimerStart = Int(Timer)
End Sub
Private Sub PPApp_SlideShowNextSlide(ByVal Wn As SlideShowWindow)
If Not Wn.View.Slide.Shapes("CarValue") Is Nothing Then
Dim Lap As Integer
Lap = (Int(Timer) - TimerStart) / 10 'change for 60 to change from 10sec to 1 min
Wn.View.Slide.Shapes("CarValue").TextFrame.TextRange = "Cars volume: " & Lap * increasePerMinute
End If
End Sub
Add the following code to Module2 and run the procedure.
Public tmpPPApp As New AppClass
Sub StartUp()
Set tmpPPApp.PPApp = PowerPoint.Application
End Sub
Start your presentation.
Important! If you change anything in code please run step 3 again. Moreover, just in case, you need to run procedure 3 always before you lunch the presentation.