Error iterating a Multi Value Parameter in SSRS Custom Code - vb.net

I have a Multi value parameter in SSRS 2016 populated by a dataset. I have set the parameter properties as follows Data type 'Date/time', 'Allow multiple values', visibility is Internal and I've pointed Available and Default values to my dataset which is a simple select query returning dates. Using a for loop in custom code, I want to check if a given date is equal to any of the dates in the parameter. Whenever I use the index in the For Loop to index the parameter value I get #Error however
when I hard code the index with a any number I get the desired result
While (dt < endDate)
For i As Integer = 0 To Report.Parameters!parameter.Count()
If Report.Parameters!parameter.Value(i) = dt Then
count = count +1
Exit For
End If
Next i
dt = dt.AddDays(1)
End While
I expect 1 to be added count every time there's a match

Related

Replace a range of values in an SQL table to a single value

I am trying to replace a range of values with a string. I know how to do it with the replace function but that, as far as I know, requires them to be done one at a time.
Is there a way to select a range of values, for example (1-200), and replace them with a singular string value say "BLANK"?
I have tried WHEN, THEN and SET but get a syntax error near WHEN or SET as I try these.
Base Code Idea
Select DATA
WHEN DATA >= 1 THEN 'BLANK'
WHEN DATA <200 THEN 'BLANK
END
FROM DATABANK
Thanks!
Is this what you want?
select data,
case when data not between 1 and 200 then data end as new_data
from databank
What this does is take the integer value of data, and replace any value that's in the 1-200 range with null values, while leaving other values unchanged. The result goes into column new_data.
The assumption here is that data is a number - so the alternative value has to be consistent with that datatype (string 'BLANK' isn't): I went for null, which is consistent with any datatype, and is the default value returned by a case expression when no branch matches.
If you wanted something else, say 0, you would do:
select data,
case when data between 1 and 200 then 0 else data end as new_data
from databank

SQL: Replacing dates contained within a text string

I am using SQL Server Management Studio 2012. I work with medical records and need to de-identify reports. The reports are structured in a table with columns Report_Date, Report_Subject, Report_Text, etc... The string I need to update is in report_text and there are ~700,000 records.
So if I have:
"patient had an EKG on 04/09/2012"
I need to replace that with:
"patient had an EKG on [DEIDENTIFIED]"
I tried
UPDATE table
SET Report_Text = REPLACE(Report_Text, '____/___/____', '[DEIDENTIFED]')
because I need to replace anything in there that looks like a date, and it runs but doesn't actually replace anything, because apparently I can't use the _ wildcard in this command.
Any recommendations on this? Advance thanks!
You can use PATINDEX to find the location of Date and then use SUBSTRING and REPLACE to replace the dates.
Since there may be multiple dates in the Text you have to run a while loop to replace all the dates.
Below sql will work for all dates in the form of MM/DD/YYYY
WHILE EXISTS( SELECT 1 FROM dbo.MyTable WHERE PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%',Report_Text) > 0 )
BEGIN
UPDATE t
SET Report_Text = REPLACE(Report_Text, DateToBeReplaced, '[DEIDENTIFIED]')
FROM ( SELECT * ,
SUBSTRING(Report_Text,PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%',Report_Text), 10) AS DateToBeReplaced
FROM dbo.MyTable AS a
WHERE PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%',Report_Text) > 0
) AS t
END
I have tested the above sql on a dummy table with few rows.I don't know how it will scale for your data but recommend you to give it a try.
To keep it simple, assume that a number represents an identifying element in the string so look for the position of the first number in the string and the position of the last number in the string. Not sure if this will apply to your entire set of records but here is the code ...
I created two test strings ... the one you supplied and one with the date at the beginning of the string.
Declare #tstString varchar(100)
Set #tstString = 'patient had an EKG on 04/09/2012'
Set #tstString = '04/09/2012 EKG for patient'
Select #tstString
-- Calculate 1st Occurrence of a Number
,PATINDEX('%[0-9]%',#tstString)
-- Calculate last Occurrence of a Number
,LEN(#tstString) - PATINDEX('%[0-9]%',REVERSE(#tstString))
,CASE
-- No numbers in the string, return the string
WHEN PATINDEX('%[0-9]%',#tstString) = 0 THEN #tstString
-- Number is the first character to find the last position and remove front
WHEN PATINDEX('%[0-9]%',#tstString) = 1 THEN
CONCAT('[DEIDENTIFIED]',SUBSTRING(#tstString, LEN(#tstString)-PATINDEX('%[0-9]%',REVERSE(#tstString))+2,LEN(#tstString)))
-- Just select string up to the first number
ELSE CONCAT(SUBSTRING(#tstString,1,PATINDEX('%[0-9]%',#tstString)-1),'[DEIDENTIFIED]')
END AS 'newString'
As you can see, this is messy in SQL.
I would rather achieve this with a parser service and move the data with SSIS and call the service.

How to add Values of multiple Select Cases

I have a vb.net program that runs a stored procedure on a database. After I build the dataset, i'm scanning the table inside the dataset searching for specific information. I used Select Case statements to find the correct info. The problem i'm running into is I can't figure out how to display my results as a "sum". I know that it's because i'm using "For Each" but i'm unsure how to assign "Result" to ds.tables(0).Rows
Code:
For Each Result As DataRow In ds.Tables(0).Rows
Select Case Result("Report")
Case "TOTALS"
Select Case Result("Description")
Case "Coupons", "Coupons Tax-Free", "GC"
MsgBox(Result("netAmt"))
End Select
End Select
Next
As coded i'm receiving 3 message boxes. The first one:
"15"
The Second One:
"10"
The Third:
"5"
I'd prefer to see the sum of all 3 found:
"30"
How can I retrieve the sum of these, keeping in mind it's possible that one of the 3 comes back as 0 in some cases
You need an additional variable which will store a sum e.g.:
Dim numberOfStudents As Integer = 0
Then instead of displaying the current net amount add it to the current sum:
sum = sum + FoundRow("netAmt")
To simplify I assumed that FoundRow returns a number. However, if it returns for example a string you will have to parse it in the following way: Integer.Parse(FoundRow("netAmt")).
Finally, after the for each loop, display the result:
MsgBox(sum)

Procedure not automatically generating number as coded

My code is:
Private Function CreateID() As Integer
'finds the current highest ID
For Each row As DataRow In MedDT.Rows
If row.Item("MedicineID") > CreateID Then
CreateID = row.Item("MedicineID")
End If
Next
'returns a value for eventID that is unused as its higher then the current highest
Return CreateID
End Function
It should automatically generate a number which is one higher than the highest value in the DataTable but for some reason it isn't working
I call the procedure in the Form_Load procedure to fill a text box.
You are scanning a DataSet for the highest MedicineID number but you forgot to increment that value by 1 before returning, just change your return statement to:
Return CreateID + 1
You should just mark the ID column as IDENTITY and forget about that trivial thing though
Just to add to what Machinarius has said, Data Table itself has an auto Increment option on a column
DataColumn.AutoIncrement = true;
DataColumn.AutoIncrementSeed = 1;
DataColumn.AutoIncrementStep = 1;
so if you are not loading the data from a database you could also use this option.

Empty date/time field in a query using a VBA Function outputs #Error

In a query I have (among others) two columns: start_date_time and end_date_time. In the next column I want to calculate the duration ( = end_date_time - start_date_time). For this calculation I am using VBA (I use VBA because I calculate the duration only if it falls between beggining date and finish date arbitrary defined by the user in two fields in the main form).
Now when there are dates and times defined in the columns start_date_time and end_date_time the calculation is OK. The problem comes up when these two fields are empty. In this case I get the "#error" sign in the "duration" field.
I already tried to make a condition to get rid of this "#error" and change it to 0. I tried to find out wheather the empty field is a null or missing or empty but with no success. Whenever there is no data in these fields I get the "#error" sign in the field of the "duration" column.
Am I missing something? How can I change this "#error" sign to e.g. 0.
Thank you in advance
The function I use for the calculation is:
Function DurationInterval(BegginingDate As Date, FinishDate As Date, start_date_time As Double, end_date_time As Double) As Double
If start_date_time >= BegginingDate And start_date_time <= FinishDate Then
DurationInterval = end_date_time - start_date_time
End If
End Function
then I call this function in the builder in the query with:
trajanje: DurationInterval([Forms]![Glavna stran]![Besedilo39];[Forms]![Glavna stran]![Besedilo43];[Zacetek sestanka];[Konec sestanka])
You are receiving #Error results because your function declaration specifies your times as Double, so they cannot receive Null values. If you want to be able to pass Null values to your function you need to declare the parameters As Variant and then check if they are null by using the IsNull() function.
For example, if I have the following function
Option Compare Database
Option Explicit
Public Function TimesTwo(SourceValue As Long) As Long
TimesTwo = SourceValue * 2
End Function
and I use it in a query where the source column can have null values
SELECT thing, TimesTwo(thing) AS thing2 FROM table1
then the rows with null values will return #Error
thing thing2
----- ------
1 2
2 4
#Error
4 8
However, if I change the function to
Option Compare Database
Option Explicit
Public Function TimesTwo(SourceValue As Variant) As Variant
If IsNull(SourceValue) Then
TimesTwo = Null
Else
TimesTwo = SourceValue * 2
End If
End Function
then I get
thing thing2
----- ------
1 2
2 4
4 8