Running two if statements in the same Sub - ms-access

I have been trying to figure out how to run two If statements in one sub. These If statements are completely different from each other. They are not one action based off multiple conditions. They are two actions affecting two button labels.
If x > 0 Then
Me.isResolved.backcolor = "5921504"
Me.isResolved.Caption = X & " Notes need reviewed."
If Y > 0 Then
Me.unfinished.backcolor = "5921504"
Me.unfinished.Caption = "You have " & Y & " unfinished orders"
Else
(Do this just changing captions and colors of me.unfinished)
End If
Else
(Do change color and caption of me.isResolved.)
End If
I tried Else if and some other ways, but when I run a debug stop on any line if the first condition is met, it just ends the Sub.
Working on Access

You could just have them follow each other:
Sub MySub()
If x > 0 Then
' Code if x is positive
Else
' Code if x is not positive
End If
If y > 0 Then
' Code if y is positive
Else
' Code if y is not positive
End If
End Sub

Related

microsoft access Field must be blank or have a value that is a specific length

I have a field on a form and I need the user to leave it blank or enter a value that is a specific length (20 characters). Does anyone have code that may solve this need?
I have tried:
(Len([SIM / ENGRV]) = 20) or (isnull([SIM / ENGRV])) or ([SIM / ENGRV]="")
I assume the control (field) name in the form is Text1.
So you can use this code in the before update event .
Of course, the code can be much shorter,
But I think that's the clearest way to understand the logic.
Private Sub Text1_BeforeUpdate(Cancel As Integer)
Dim varTmp As Variant
' first check if [ENGRV] > 0 to avoid devision by zero error
If Not IsNumeric([ENGRV]) And [ENGRV] = 0 Then
Text1.Undo
Cancel = True
Else
' now avoid [SIM] is null error
If Nz([SIM], "") = "" Then
Text1.Undo
Cancel = True
Else
varTmp = [SIM] / [ENGRV]
' now we know that varTmp is somthing and not empty then check the length
If Len(Trim(str(varTmp))) <= 20 Then
Text1.Undo
Cancel = True
End If
End If
End If
End Sub
You can do that at the table level. Set the Validation Rule of the field to:
Len([SIM / ENGRV])=20 Or [SIM / ENGRV] Is Null

Access: Increment/Decrement a number with 2 dots

I have two fields for current version number and previous version number in a form. What I want to do is when I enter the current version number (which is written like this 18.04.15), the previous version number on the next text box to automatically fill itself with 18.04.14.
I tried:
=[txtCurrentVersion]-1 in the control source, but obviously because I'm not decrementing by one, it didn't work.
Would appreciate some guidance, thanks :)
Below code splits the text based on dot and subracts one from last item.
Private Sub txtCurrentVersion_AfterUpdate()
If Nz(Me.txtCurrentVersion, "") <> "" Then
Me.txtPrevVersion.Value = Split(Me.txtCurrentVersion, ".")(0) & "." & Split(Me.txtCurrentVersion, ".")(1) & "." & Split(Me.txtCurrentVersion, ".")(2) - 1
End If
End Sub
I would suggest creating a function where you give the function 3 parameters, the 1st is the current version number string, the 2nd is the version number level (0 for major number, 1 for subversion number and 2 for minor version number) and the value to increase or decrease.
for example:
Function ModifyVersion(VersionNumber, NumberLevel, Number)
If VersionNumber <> "" AND NumberLevel >= 0 AND NumberLevel < 3 Then
dim VersionArray
VersionArray = Split(VersionNumber, ".")
Select Case NumberLevel
Case 0
VersionArray(0) = VersionArray(0) + Number
Case 1
VersionArray(1) = VersionArray(1) + Number
Case 2
VersionArray(2) = VersionArray(2) + Number
End Select
ModifyVersion = VersionArray(0) & "." & VersionArray(1) & "." & VersionArray(2)
End If
End Function
Then to decrease one from the minor version number use:
VersionNumber = [txtCurrentVersion]
Dim UpdateVersion
UpdateVersion = ModifyVersion(VersionNumber, 2, -1)

Incrementing textbox value up and down in vba does not cancel evenly

I can't figure out why my code isn't maintaining significant digits when incrementing a textbox value.
I have a spin control (textbox plus two small command buttons to move textbox value up or down in value) on a form.
The textbox default value is zero.
The up arrow command button should increment the textbox value by + 0.1. Here is the code:
Private Sub cmdIndexSpinUp_Click()
If Me!txtIndexSpin >= 1.5 Then
MsgBox "The maximum Index adjustment has been reached."
Exit Sub
Else
Me!txtIndexSpin = Me!txtIndexSpin + 0.1
End If
End Sub
The down arrow command button should increment the textbox value by -0.1. Here is the code:
Private Sub cmdIndexSpinDown_Click()
If Me!txtIndexSpin <= -1.5 Then
MsgBox "The minimum Index adjustment has been reached."
Exit Sub
Else
Me!txtIndexSpin = Me!txtIndexSpin - 0.1
End If
End Sub
So I would expect that from the default value of 0, if I spin up once and down once, I should return to 0. That works fine. If I spin up twice and then down twice, my textbox value suddenly becomes 2.77555756156289E-17 instead of 0.
After more testing, it does not consistently happen based on the number of clicks, but it may be related to the time between clicks. The more rapid, the more prone to this error it seems.
How could this be happening?
I am going to code around it, since I see nothing wrong, but am curious what I am missing.
As #HansUp says floating points aren't precise. Source. An easy solution that you could use is to round the number before putting it in the text box.
Example :
Private Sub cmdIndexSpinDown_Click()
Dim value As Double
value = Me!txtIndexSpin
If value <= -1.5 Then
MsgBox "The minimum Index adjustment has been reached."
Exit Sub
Else
value = Round(value - 0.1, 1)
Me!txtIndexSpin = value
End If
End Sub
Private Sub cmdIndexSpinUp_Click()
Dim value As Double
value = Me!txtIndexSpin
If value >= 1.5 Then
MsgBox "The maximum Index adjustment has been reached."
Exit Sub
Else
value = Round(value + 0.1,1)
Me!txtIndexSpin = value
End If
End Sub
Round() is a reasonable solution for your floating point precision problem. And it may well be exactly what you want. However, be aware that you will be using "banker's rounding", sometimes called "round to even". So you might not get what you expect from rounding to 1 decimal place when the second decimal place is 5:
? Round(1.15, 1)
1.2
? Round(1.25, 1)
1.2
If that is not what you want, you could use a different rounding strategy. Or you could switch to integer math instead of floating point math ... and then the floating point precision challenge goes away. That might sound challenging, but it's actually simple to implement. Add a hidden text box to your form and use it like this ...
Private Sub cmdIndexSpinDown_Click()
With Me!txtHidden
If .Value <= -15 Then
MsgBox "The minimum Index adjustment has been reached."
Else
.Value = .Value - 1
Me!txtIndexSpin.Value = .Value / 10
End If
End With
End Sub
If txtIndexSpin is bound to a field in the form's Record Source, you can load txtHidden from the form's Current event:
Me!txtHidden.Value = Me!txtIndexSpin.Value * 10
And if you also allow the users to edit txtIndexSpin directly (not just via those command buttons), do that again from its After Update event.

Tips for function inside while loop and i=i+1, Matlab

I have a problem with a function in matlab. This specific function is for filtering light signals. As you can see below I added the coding I’ve used in the function and in the while loop itself. The code is written for a NXT Lego robot.
Is there any tip how to get the count variable ( i = i + 1 ) to work in the function, so we can plot Light(i)? Because we’re getting a bunch of error messages when we try different codes to make it work.
function [light] = filter_func( i)
lightI(i) = GetLight(SENSOR_3);
if i==1
light(i)=lightI(i)
elseif i==2
light(i) = 0.55*lightI(i) + 0.45*lightI(i-1)
else
light(i) = 0.4*lightI(i) + 0.3*lightI(i-1) + 0.3*lightI(i-2);
end
end
i=1
while true
lightI(i) = GetLight(SENSOR_3); % Get’s a lightvalue between 0 and 1024.
if i>2
light =filter_func(i)
light=round(light);
else
light(i) = GetLight(SENSOR_3);;
end
i=1+i
plot(light(end-90:end), 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
end
You probably mainly get errors because you are not allowed to mix script and functions like this in MATLAB (like you are in Python).
Your filter function is only used when i>2 so why are you doing the first 2 tests? It seems like you want lightI as a global variable, but that is not what you have done. The lightI inside the function is not the same as the one in the while loop.
Since your while loop runs forever, maybe you don't need to worry about updating the plot the first two times. In that case you can do this:
filter = [0.4 0.3 0.3]';
latest_filtered_light = nan(90,1);
lightI = [];
p = plot(latest_filtered_light, 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
while True
lightI(end+1,1) = rand*1024; % Get’s a lightvalue between 0 and 1024.
if i>=3
new_val = lightI(end-2:end,1)'*filter;
latest_filtered_light = [latest_filtered_light(2:end);...
new_val];
set(p, 'ydata', latest_filtered_light)
drawnow
end
end
I think it is an important point to not call plot every time - at least if you are the least concerned about performance.

Access VBA - How is this code grouping all info for one policy together?

So, I inherited some code (below) from someone else and I'm trying to understand how it works. I understand msot of the code (though I'm pretty new to Access VBA) but the one part I don't get is how this code groups all the info for one policy together.
The situation is as follows. To get premium data for a specific policy, from our company database, we have to get it one coverage per line. But, I want all premiums, one for each coverage, all on the same line. So, this code puts it all together from many lines into one line. For simplicity, I knocked it down to 3 total coverages, though there are many more. As I read the code, it seems to assume that all the info for one policy is together, like the 1, 2, or 3 rows for a specific policy are in order. But, even when I, for example, order the table by the premium (amount) column, it still gets all the premium for one policy on one line. I don't see anywhere in the code that should make this work. The code is comparing the policy number on one line to the policy number on the next. If they are the same, group the premium together. If they are different, don't. Again, I could order the table so that the records for one policy are not together, but the end result still comes out right. Am I missing something? Is it something in Access doing it? Thanks for any help!
Option Compare Database
Option Explicit
' Premium is imported with one row for each coverage per policy, so possibly several rows per policy.
' This procedure takes several rows per policy and makes them into one row.
Sub ScrubPremium()
Dim i As Long, j As Long, k As Long
Dim NumRecords As Long, found As Long, UniqueCount As Long
Dim tempPolicyNum As String, tempCoverage As String, tempPremium As Single
Dim PolicyNumArray() As String, PremiumArray() As Single, TotalPremiumArray() As Single
Dim db As DAO.Database
Set db = CurrentDb
Dim infile As Variant, outfile As Variant
Set infile = db.OpenRecordset("Imported Premium")
CurrentDb.Execute "DELETE * FROM [Finalized Premium]"
Set outfile = db.OpenRecordset("Finalized Premium")
NumRecords = infile.RecordCount
ReDim PolicyNumArray(NumRecords)
ReDim PremiumArray(NumRecords, 3)
ReDim TotalPremiumArray(NumRecords)
infile.MoveFirst
'initialize PremiumArray
For i = 1 To NumRecords
For j = 1 To NumPremiums
PremiumArray(i, j) = 0
Next j
Next i
'populate arrays
UniqueCount = 0
For i = 1 To NumRecords
tempPolicyNum = infile![Policy_Number]
tempCoverage = infile![Coverage]
tempPremium = infile![Premium]
k = 0
found = 0
Do Until k = UniqueCount Or found = 1 'check for unique policy
If tempPolicyNum = PolicyNumArray(k + 1) Then
found = 1
Else
k = k + 1
End If
Loop
If found = 0 Then
UniqueCount = UniqueCount + 1
PolicyNumArray(k + 1) = tempPolicyNum
End If
Select Case tempCoverage
Case "Comprehensive"
j = 1
Case "Collision"
j = 2
Case Else
j = 3
End Select
PremiumArray(k + 1, j) = PremiumArray(k + 1, j) + tempPremium
TotalPremiumArray(k + 1) = TotalPremiumArray(k + 1) + tempPremium
infile.MoveNext
Next i
'Populate table
For i = 1 To UniqueCount
outfile.AddNew
outfile![Full Policy Number] = PolicyNumArray(i)
outfile![Comp Premium] = PremiumArray(i, 1)
outfile![Coll Premium] = PremiumArray(i, 2)
outfile![Other Premium] = PremiumArray(i, 3)
outfile![Total Premium] = TotalPremiumArray(i)
outfile.Update
Next i
infile.Close
outfile.Close
End Sub
The code is comparing the policy number on one line to the policy
number on the next. If they are the same, group the premium together.
If they are different, don't.
Almost.
There are two loops here. One walks through each row of your input file. On each row of the input file, a second loop walks through (potentially all of) PolicyNumArray, looking for policy numbers that match the number taken from the input file.
If I were you, I'd step through this with the debugger. Make sure it's doing what you expect it to do. I'd want to look closely at this part (some lines snipped).
UniqueCount = 0
For i = 1 To NumRecords
k = 0
Do Until k = UniqueCount