function return 0 value in Ms Access - ms-access

I created a function in Ms Access and called it to the sub procedure in the form, but it returns 0.
This is the code in the function:
Public Function Sum(a, b) As Double
Dim total
total = a + b
End Function
The code in the sub procedure in the form is:
Private Sub cmdDisplay_Click()
Dim a As Double
Dim b As Double
a = Val(Text0)
b = Val(Text2)
MsgBox (Sum(a, b))
End Sub
it displays 0 in every time I tested the button which it should have been added a and b together. Please help

To return a value you must assign to the function name, which behaves just like a local variable typed to the functions return type;
Public Function Sum(a, b) As Double
Dim total
total = a + b
Sum = total '//sum is the function name and a variable of type double
End Function
or better (if you really need a sum function):
Public Function Sum(a as double, b as double) As Double
Sum = a + b
End Function

Related

In SSRS custom code, can we create a function that call another function?

In the Custom code section, if I defined function 1 first, in the next line, can I define function 2 that calling function 1? If not, how can I get around it?
Yes, you can. Artificially simple example:
Function SumSum(a as decimal, b as decimal) as decimal
Dim c as Decimal
c = a + b
Return c
End Function
Function OtherFunction(a as decimal, b as decimal) as decimal
Dim c as Decimal
c = SumSum(a,b)
Return c
End Function
OtherFunction will use the SumSum function to sum a and b.

SSRS Display Totals by Group

I am trying to display the total for records that are grouped together.
I am using the code below under Report Properties -> Code
Dim public totalBalance as Integer
Dim public Cnt as Integer
Public Function AddTotal(ByVal balance AS Integer ) AS Integer
totalBalance = totalBalance + balance
Cnt=Cnt+1
return balance
End Function
Public Function GetTotal()
return totalBalance
End Function
[Expression A is =Code.AddTotal(sum(DateDiff(dateinterval.Second, Lookup(Fields!dg_InteractionId.Value, Fields!Id.Value, Fields!StartDate.Value, "DataSet1"), Lookup(Fields!dg_InteractionId.Value, Fields!Id.Value, Fields!EndDate.Value, "DataSet1")))/CountRows())
While Expression B is =Code.GetTotal()
AS you can see the total 1651 for the top group is correct but the total for the second group 2597 is incorrect as it includes the total of the first group together. The correct result desired is 946 for the second group total.
Kindly advise.
You can change your GetTotal() to reset the totalBalance variable when is called to display the group total
Public Function GetTotal()
Dim bal AS integer
bal = totalBalance
totalBalance = 0
return bal
End Function
Because of this change, you should also create a separate variable for the grand total which will be updated in the AddTotal() function, and create a GetGrandTotal() function which will return its value.
Also since you have declared your variables as public you can display them directly without functions like =Code.totalBalance

SSRS distinct lookupset function

I'm using Join(Lookupset) to find unique group values which returns a sequence number. This is my function:
Join(LookupSet(Fields!itemId.Value & Fields!UseByDate.Value & Fields!rackId.Value
, Fields!itemId.Value & Fields!UseByDate.Value & Fields!rackId.Value
, Fields!CustomerSeqNo.Value
, "PickingList"), ",")
The problem is on some items there are multiple transactions. I want to remove the duplicates.
I found a blog http://blogs.msdn.com/b/bobmeyers/archive/2012/06/18/creating-short-lists-using-the-lookupset-function.aspx but could not get SSRS Report Builder to reference Linq assembly. My issue is
How can I just show the unique values?
You don't need Linq, but you do still need custom code (in BIDS go to Report -> Report Properties -> Code)
You can put a RemoveDuplicates function in here, something like this:
Public Shared Function RemoveDuplicates(m_Array As Object()) As String()
System.Array.Sort(m_Array)
Dim k As Integer = 0
For i As Integer = 0 To m_Array.Length - 1
If i > 0 AndAlso m_Array(i).Equals(m_Array(i - 1)) Then
Continue For
End If
m_Array(k) = m_Array(i)
k += 1
Next
Dim unique As [String]() = New [String](k - 1) {}
System.Array.Copy(m_Array, 0, unique, 0, k)
Return unique
End Function
To use it in your Join:
Join(Code.RemoveDuplicates(LookupSet(...)),",")
I agree with #user3697615 that Report Code is best. However, I prefer to build it straight into a string:
public shared function JoinDistinct(
dups as object(),
delimiter as string
) as string
dim result as string = ""
system.array.sort(dups)
for i as integer = 0 to dups.length - 1
if i <> 0 then result += delimiter
if i = 0 orElse dups(i) <> dups(i-1) then result += dups(i)
next i
return result
end function
This way, we eliminate one nested function on the call:
=Code.JoinDistinct(LookupSet(...), ",")
If you're like me, you also want the elements in order based on frequency (descending order).
I created the following VisualBasic code to do so
Public Shared Function RemoveDuplicates(dataset As Object()) As String()
Dim unique As New System.Collections.Generic.List(Of String)
Dim frequency As New System.Collections.Generic.List(Of Integer)
For i As Integer = 0 To dataset.Length - 1
Dim index As Integer = -1
For j As Integer = 0 To unique.Count - 1
If dataset(i).Equals(unique(j)) Then
index = j
Exit For
End If
Next
If index < 0 Then
unique.Add(dataset(i))
frequency.Add(1)
Else
frequency(index) += 1
End If
Next
Dim uniqueArray As [String]() = unique.ToArray()
Array.Sort(frequency.ToArray(), uniqueArray)
Array.Reverse(uniqueArray)
return uniqueArray
End Function
This is based off others' answers where the SSRS expression is the following
Join(Code.RemoveDuplicates(LookupSet(...)),",")
Note: I learned VisualBasic in about an hour to solve this problem, so my algorithm probably isn't the most efficient.
I liked pwilcox's idea, so I wrote this one which filters out null and blank values.
Public Function JoinDistinct(arr As Object(), delimiter As String) As String
System.Array.Sort(arr)
Dim result As String = String.Empty
Dim lastvalue As String = String.Empty
For i As Integer = 0 To arr.Length - 1
If Not arr(i) Is Nothing And arr(i) <> lastvalue And arr(i) <> String.Empty Then
If result = String.Empty Then
result = arr(i)
Else
result = result + delimiter + arr(i)
End If
End If
lastvalue = arr(i)
Next
Return result
End Function
Usage:
=Code.JoinDistinct(LookupSet(...), ",")

disctinctcount from another dataset having multiple grouping

i have report that generates number of policies from 2 datasets.
the table is linked to dataset1.
i used the formula
CountDistinct(Fields!Policy_ID.Value)
my problem is how to get distinct count for the field Policy_ID from the second dataset "AccountingV10Dataset", specially that i have grouping Contract_Start_Month, Contract_Cover_Type, and Primary_LOB.
below a screen shot to the report design to help you to understand my request
the report should be generated as below:
I would derive the Distinct Count back in the Dataset layer e.g. in SQL. The SSRS Aggregate Functions only go so far.
I managed to solved this way:
i created the below code to calculate disting count from another dataset:
Dim suma As Decimal = New Decimal()
Public Function SumLookup(ByVal items As Object(),ByVal CountSum As String) As Decimal
If items Is Nothing Then
Return Nothing
End If
Dim ct as Integer = New Integer()
Dim PolId as Integer = New Integer()
suma = 0
ct = 0
PolId = 0
For Each item As Object In items
suma += Convert.ToDecimal(item)
If (CountSum = "SUM") then
ct += 1
Else If (PolID <> Convert.ToInt32(item)) then
ct += 1
END If
PolId = Convert.ToInt32(item)
Next
If (ct = 0) Then return 0 else If(CountSum = "SUM") then return suma else return ct
End Function
Public Function GetMyVal() as Decimal
GetMyVal = suma
End Function
and i call this function by:
=code.SumLookup(Lookupset(Fields!Contract_Start_Month.Value & "-" & Fields!Contract_Cover_Type.Value & "-" & Fields!Primary_LOB.Value,Fields!Contract_Year_Start_Month.Value & "-" & Fields!Cover_Type.Value & "-" & Fields!LOB.Value,Fields!Layer_ID.Value, "AccountingV10Dataset"),"COUNT")
Hope my solution will helpfull for other users as it did for me.
Regards,

VBA data type error - bad syntax?

Hopefully someone can help me out with this. I have written a query in Access 2003 that combines a linked table "taxon_group_max_per_site" and a cross tab query "Distinct Species by group_Crosstab".
From the table I have the field "Taxonomic Group" and "Max", and from the cross tab the fields "Total_Of_Species_S".
The table and the cross tab are linked and the query works fine until I add in some VBA to give each Taxonomic group a score based on "Max" and "Total_Of_Species_S".
The code below brings up "Error 13: type mismatch"
Public Function Invert_Diversity_Score (Total_Of_Species_S As Integer) As Integer
If Total_Of_Species_S < Round("[Max]*0.5", 0) Then
Invert_Diversity_Score = 0
Else
If Total_Of_Species_S < Round("[Max] * 0.75", 0) Then
Invert_Diversity_Score = 1
Else
If Total_Of_Species_S < Round("[Max] * 0.875", 0) Then
Invert_Diversity_Score = 2
Else
Invert_Diversity_Score = 3
End If
End If
End If
End Function
The debugger shows that "[Max]*0.5" and the other multiplications do not produce a number it says "[Max] * 0.5"= "[Max] * 0.5", which I think is the source of the type mismatch. How do I get the field to multiple properly? It looks exactly like the format shown in the VBA help.
The round function is expecting a number as parameter, not a string! Assuming (max) is a number, you can then calculate:
Round([Max] * 0.75, 0)
But
Round("[Max] * 0.75", 0)
Will definitely not return anything viable
"[Max] * 0.875" is just a string, how is VBA supposed to know that you are referring to the column [Max] from one of your tables?
Shouldn't [Max] be passed into the function as a second integer parameter? Something like this:
Public Function Invert_Diversity_Score (Total_Of_Species_S As Integer,
MaxVal as Integer) As Integer
We need the code that shows how you are calling the function to really sort this out ...
For one, you should use the ElseIf keyword, there is no need to stack the Ifs here.
Second - what is "[Max]*0.5" supposed to mean? To VB, it is a string, which unsurprisingly you can't multiply with an integer.
Assuming Max is some kind of global constant:
Public Function Invert_Diversity_Score(Total_Of_Species_S As Integer) As Integer
If Total_Of_Species_S < Round(Max * 0.5, 0) Then
Invert_Diversity_Score = 0
ElseIf Total_Of_Species_S < Round(Max * 0.75, 0) Then
Invert_Diversity_Score = 1
ElseIf Total_Of_Species_S < Round(Max * 0.875, 0) Then
Invert_Diversity_Score = 2
Else
Invert_Diversity_Score = 3
End If
End Function
If it is not a constant, then you must pass it into the function as well:
Public Function Invert_Diversity_Score( _
Total_Of_Species_S As Integer, _
Max as Integer _
) As Integer