PDA

View Full Version : infinite series for the sine using VBA command button and input boxes



fires21
11-06-2016, 04:47 PM
This is the assignment that I was given, I have tried to do it over and over and this is what I have so far, yet I do not know where I keep going wrong:




The infinite series for the sine of x is

or, in expanded form,

Write a command button event procedure and another procedure called Sine to do the following:
· The event procedure will obtain the angle from the user using an input box. The user will provide the angle in degrees.
· The event procedure will call Sine, sending it the value of x.
· The Sine sub procedure will evaluate the Sine, using a loop to implement the series shown above.
· The number of terms used in the infinite series will be determined by comparing the summation with the result of the VBA sin(x) function. When the difference between the two is less than 1·10-10, enough terms have been used.
· The Sine procedure then returns the sine value to the event procedure.
· The event procedure gives the answer to the user in a suitable format in a message box.


Option Explicit
Private Sub CommandButton1_Click()



' Local Variables
Dim Series As Integer
Dim sin As Double
Dim Add As Boolean
Dim val As Range
Dim answer As Double


val = InputBox("Please Enter an Angle in Degrees", "Angle", 1)
Call Sine(val, sin)


answer = MsgBox("The sine of angle " & val & " is " & sin, , "Sine")

End Sub







Public Function Sine(val As Range, sin As Double)






Add = False


Do While True
Series = Series + 1
If Series Mod 2 <> 0 And Series > 1 Then
If Add Then
sin = sin + (val ^ Series) / dev(CLng(Series))
blnAddTerm = False
Else
sin = sin - (val ^ Series) / dev(CLng(intSeries))
blnAddTerm = True
End If
End If
If (DegInRads ^ Series) / Factorial(CLng(Series)) < 0.0000000001 Then Exit Do
Loop


SinBySeries = sin









End Function

Private Function dev(intNumber As Long) As Long

Dim i As Long

For i = intNumber To 0 Step -1
dev = dev + i
Next i

End Function


















End Sub

Paul_Hossler
11-06-2016, 07:27 PM
Couple of suggestions for what is almost surely a homework assignment. Did not test it or worry about the math (otherwise it wouldn't be a homework assignment)

1. There is a difference between a Function and as Sub. Simple example to just double a number that shows the difference. Look where and how the result is returned to the upper level function that called it



Option Explicit
Sub Button_Click()
Dim NumberIn As Long, Result As Long

NumberIn = InputBox("Enter Number", "Number")

Call Double_As_Sub(NumberIn, Result)
MsgBox "The result using a sub is " & Result

MsgBox "The result using a function is " & Double_As_Function(NumberIn)
End Sub

Sub Double_As_Sub(N As Long, R As Long)
R = 2 * N
End Sub

Function Double_As_Function(N As Long) As Long
Double_As_Function = 2 * N
End Function




2. Variables have a scope, i.e. which subs or functions an see them. You had some Dim-ed in the Click sub, and so were not available to the others. Good idea to avoid global variables, and to Dim them 'local' to the sub or function that actually uses them

3. There were calls to functions that are not VBA functions

4. Some variables were never Dim-ed and/or were not ever given a value

5. Here's some annotations to (I hope) help you along



Option Explicit
Private Sub CommandButton1_Click()
' Local Variables
Dim sin As Double
Dim val As Double ' Not range

'wrong call to InputBox
val = InputBox("Please Enter an Angle in Degrees", "Angle")

Call Sine(val, sin)

'no need to return result
Call MsgBox("The sine of angle " & val & " is " & sin, , "Sine")

End Sub

'val is double not range, this seems like it should be a Sub, not Function
Public Sub Sine(val As Double, sin As Double)

'these were out of scope (= invisible) to this function since they were 'local' to the sub above
Dim Series As Integer
Dim Add As Boolean
Dim blnAddTerm As Boolean

'you use this but never Dim or set it
Dim DegInRads As Double

DegInRads = 360# / 6.28318530717958

Add = False


Do While True
Series = Series + 1
If Series Mod 2 <> 0 And Series > 1 Then
If Add Then
sin = sin + (val ^ Series) / dev(CLng(Series))
blnAddTerm = False
Else
sin = sin - (val ^ Series) / dev(CLng(Series)) ' intSeries should probably be 'Series'
blnAddTerm = True
End If
End If
'Factorial is not an intrinsic VBA function. To use the worksheet formula version ...
If (DegInRads ^ Series) / Application.WorksheetFunction.Fact(CLng(Series)) < 0.0000000001 Then Exit Do
Loop

'no idea, since SinBySeries is not defined
'SinBySeries = sin

'but since this is a sub, the value of 'sin' is returned in the calling parameter

End Sub

Private Function dev(intNumber As Long) As Long
Dim i As Long

For i = intNumber To 0 Step -1
dev = dev + I
Next i
End Function

SamT
11-06-2016, 11:43 PM
'but since this is a sub, the value of 'sin' is returned in the calling parameter

THanks for teaching me a new trick. :beerchug:

Paul_Hossler
11-07-2016, 09:37 AM
@SamT -- slightly expanded example showing difference in call using ByRef (default) and ByVal




Option Explicit
Sub Button_Click()
Dim NumberIn As Long, Result As Long

NumberIn = InputBox("Enter Number", "Number")

'default calling is ByRef
Call Double_As_Sub(NumberIn, Result)
MsgBox "The result using a sub is " & Result

Result = 0
Call Double_As_Sub_ByVal(NumberIn, Result)
MsgBox "The result using a sub called ByVal is " & Result


MsgBox "The result using a function is " & Double_As_Function(NumberIn)
End Sub

Sub Double_As_Sub(N As Long, R As Long)
'updated R is passed back
R = 2 * N
End Sub

Sub Double_As_Sub_ByVal(N As Long, ByVal R As Long)
'updated R is not passed back
R = 2 * N
End Sub



Function Double_As_Function(N As Long) As Long
Double_As_Function = 2 * N
End Function