How do I sort an array of different times? - arrays

So I have an array of various timeslots, but I want to sort out the times from the earliest ones to the latest ones, however, I also want to delete any elements within the array that has the time value of 12:00am.
Appointment(0) = #10:45:00 AM#
Appointment(1) = #12:00:00 AM# 'My actual has up 80 elements of different timeslots but I'm using 3 elements as an example
Appointment(2) = #12:00:00 AM#
Is there anyone who can help me with this problem?

Using a string array is not a good idea if that's what you used just use a list of DateTime and the Sort method.
Dim list As List(of DateTime) = new List(of DateTime)
For Each val As String In Appointment
list.Add(val.replace(" ",""))
Next
list.Sort(New Comparison(Of Date)(Function(x As Date, y As Date) y.CompareTo(x)))

Nothing in .Net for removing specific items from array, but it can be "simplified" a bit with LINQ:
Dim Appointment = {#10:45#, #12AM#, #12AM#}
Appointment = (From a In Appointment Where a <> #12AM# Order By a).ToArray
or
Appointment = Appointment.Except({#12AM#}).ToArray
Array.Sort(Appointment)
A bit more efficient alternative can be to use generic collection like List or SortedSet instead:
Dim list = New List(Of Date) From {#10:45#, #12AM#} ' or Dim list = Appointment.ToList
list.Add(#12AM#)
list.RemoveAll(Function(a) a = #12AM#)
list.Sort()

Related

SSRS Median and drill down reports

I have a SQL Server Reporting Services report in which I calculate the median using an ArrayList in a custom code block as median is not a built in function in SSRS. The median and average are displayed in a column chart. The report includes a drilldown to a detail report. If I drill down to the detail report and then hit the back arrow in the browser to navigate back to the master report, the median on the master report is not being calculated. That column of the column chart is empty while the average is displayed as it should.
Does anyone have any thoughts on why this is happening or how I can fix it?
The code is below. AddValue() first creates a new SortedList of it doesn't already exist. It then adds the newValue to an ArrayList keyed by the string passed to the function, creating one if it didn't previously exist. Each ArrayList represents a different set of values for which we would want to calculate the median.
GetMedian() calculates the median for the ArrayList identified by the passed string. GetMedian() is used in the value for the column in the chart.
Public Dim ClearanceList As System.Collections.SortedList
Function AddValue(ByVal whichList As String, ByVal newValue As Integer) As Decimal
Dim thisList As System.Collections.ArrayList
If (ClearanceList is Nothing) Then
ClearanceList = New System.Collections.SortedList
End If
If (ClearanceList.ContainsKey(whichList)) Then
'Get a reference to the desired ArrayList and add the new value to it.
thisList = ClearanceList.GetByIndex(ClearanceList.IndexOfKey(whichList))
Else
thisList = New System.Collections.ArrayList()
' Create a new element in the SortedList
ClearanceList.Add(whichList, thisList)
End If
thisList.Add(newValue)
AddValue = thisList.Count
End Function
Function GetMedian(ByVal whichList As String) As Decimal
Dim thisList As System.Collections.ArrayList
Dim count As Integer
thisList = ClearanceList.GetByIndex(ClearanceList.IndexOfKey(whichList))
count = thisList.count
If (count > 0) Then
thisList.Sort()
If count Mod 2 = 1 Then
GetMedian = thisList((count - 1) / 2)
Else
GetMedian = (thisList((count / 2) - 1) + thisList((count / 2))) / 2
End If
Else
GetMedian = -1
End If
End Function

How do i pass values from view model to controller without use of list?

Continuing from my previous question, i pass the id value from 'Lookup' controller to another controller method 'Charges'.
Function Charges(id As String) As ActionResult
Dim Patient As New LookupVM()
Patient.GetHistory(paid)
Return View(Patient)
End Function
In the view model, i have the GetHistory(id) list method, and listProcedure is the list holding the values that i want to pass back to the controller to be displayed in the view.
Public Property listProcedure As List(Of LookupVM)
Public Function GetHistory(id As String) As List(Of LookupVM)
Using db As New DbContext()
' SQL query
'====================
Dim idd = New SqlParameter("#id", "%" & id & "%")
Dim query As String = "select p.id id, pv.pvid pvid
from patient p
join patient_visit pv on p.id = pv.id
where p.paid like #id"
Dim Results = db.Database.SqlQuery(Of LookupVM)(query, idd).ToList()
For Each item In Results
Dim pvid = New SqlParameter("#pvid", "%" & item.pvid & "%")
Dim query2 As String = "select po.remarks remarks, po.entereddt entereddt, po.Consultant Consultant
from procedure_order po
join procedures p on po.pdid = p.pdid
where po.pvid like #pvid
order by po.entereddt desc"
Dim Results2 = db.Database.SqlQuery(Of LookupVM)(query2, pvid).ToList()
For Each item2 In Results2
Dim ProcedureList2 As New LookupVM()
ProcedureList2.remarks = item2.remarks
ProcedureList2.entereddt = item2.entereddt
ProcedureList2.ForConsultant = item2.ForConsultant
listProcedure.Add(ProcedureList2)
Next
Next
Return listProcedure
End Using
End Function
I'm wondering if i'm able to pass those values to the controller through something else other than a list. if possible, what could it be? Because if its a list, i can't display them on the page without the use of foreach loop.
Another question is, is my code conceptually correct or wrong? Because when i run, it took me 5 minutes to display a list of 72 values which involves the code above. I think it took way too long. Is there any way to make it load faster?
About the List, there is nothing wrong with doing For Each in a View. If it is needed then it is needed, and no reason to avoid it.
Some query tips (it is hard to do better for lack of details):
If your paid and pvid columns are INT, then do not query them using LIKE #id but using = #id (without % in it). Even if they are (N)VARCHAR then using LIKE would need to be justified and explicit. If done by accident then output will often be wrong.
LIKE '%value%' causes indexes to be ignored, possibly leading to bad performance.
Make sure that you have indexes on the columns that you use to JOIN on.
Try combining the two queries into one, to limit the number of .NET/DB roundtrips.

Correspond first line of arrays with second line VB

I have a file that shows A song name on the first line, then the genre on the second, and the time on the third.
Example
All You Need is Love-Beatles
Rock
4.25
This goes on. I need some way of corresponding the songs with the genres and then display them in a list box called lstPlayList using Arrays
I have
strSongs(intCount) = objReader.ReadLine()
strGenre(intCount) = objReader.ReadLine()
dblLength(intCount) = Convert.ToDouble(objReader.ReadLine())
For storing every variable but I can't append songs to genres
Instead of having three separate arrays for one item, you could indeed as other commenters have said, create a database, but if you don't want to go that far try this.
Create a structure at the top of your Form's class definition list this :-
Structure Song
Dim Name As String
Dim Genre As String
Dim Duration As Single
End Structure
This effectively creates a new Datatype.
Next create a list of this datatype like this :-
Dim Songs As New List(Of Song)
When you read your data from the file, instead of what you've included in your question, you can add the data to the list like this :-
Dim newSong As Song
newSong.Name = objReader.ReadLine()
newSong.Genre = objReader.ReadLine()
newSong.Duration = Convert.ToDouble(objReader.ReadLine())
Now that you have one list of all the data, you can search the list and return results as a new list of all the results. This is the function that does the searching and returning of a list :-
Private Function SearchSongsByGenre(searchGenre As String) As List(Of Song)
Dim returnList As New List(Of Song)
For Each searchSong As Song In Songs
If searchSong.Genre = searchGenre Then
returnList.Add(searchSong)
End If
Next
Return returnList
End Function
To use it in another sub, just create a list in the sub called.. say.. SearchResults :-
Dim SearchResults As New List(of Song)
Searchresults = SearchSongsByGenre("Rock")
Now you have a list of all the Songs that have the genre Rock
A lot safer than searching an array and getting data from 3 arrays that could become desynchronised.

reference dictionary within array output to listbox

Title kind of states my problem.
I'm using an Api (For Vertical Response, an email list manager) which works fine. But for a particular method returns an Array where the information I need to reference is within a Dictionary inside that Array.
Array[list_id, list_name, list_type, member_data] <- member_data being the dictionary housing all my goodies.
Best I've managed to get is the listbox outputting "com.verticalresponse.api.NVPair[]" for each member.
Code
Protected Sub GetBounces()
Dim listID As Integer = 284662333
Dim isMember As Boolean = False
Dim newSession As New loginArgs()
newSession.username = username
' Your VerticalResponse username
newSession.password = password
newSession.session_duration_minutes = "120"
Dim VRUser As New VRAPI()
Try
sessionID = VRUser.login(newSession)
Dim GetMembers As New getListMembersArgs()
Try
GetMembers.session_id = sessionID
GetMembers.list_id = listID
GetMembers.max_records = 8
Try
Dim listmembers As Array = VRUser.getListMembers(GetMembers)
lstBounces.DataSource = listmembers
lstBounces.DataValueField = ("member_data").ToString()
lstBounces.DataBind()
Catch ex As Exception
lstBounces.Text = "One: " + ex.ToString()
End Try
Catch listex As Exception
lstBounces.Text = "Two: " + listex.ToString()
End Try
Catch ex As System.Exception
lstBounces.Text = "Three: " + ex.ToString()
End Try
End Sub
Edit
I have taken the suggestion of Keith Mifsud and added a breakpoint just before the Databind. It shows me that "listmembers" has eight indices (currently only testing by searching for 8 (total list will be close to 8000, of which about 1900 are needed.))
Each of those 8 indices contains the 4 columns I am looking at, so when I use listmembers(3) as the datasource I'm really only searching the fourth result, not the member_data column...
Is there a correct way to reference the column of results?
Something like:
lstbounces.DataSource = listmembers( ,3)
But instead of that, a correct one?
I think you should set the datasource as the dictionary not the array holding it
Try
Dim listmembers As Array = VRUser.getListMembers(GetMembers)
lstBounces.DataSource = listmembers(3)
'As the datasource is a dictionary, I don't think you have to set up the display and value fields
'lstBounces.DataValueField = ("member_data").ToString()
lstBounces.DataBind()
Catch ex As Exception
lstBounces.Text = "One: " + ex.ToString()
End Try
UPDATE
Based on what the collection type (dictionary within every element of an array) I would recommend you use the .net DataView with allows for expandable rows. There are some very good tutorials which can guide you to create your view

Orderby with a string that contains part numbers and part letters

I am using MSSQL ADO.NET and I need to sort order by employer code numercially although each order code has 2X letters in front of it.
For example:
HP1234
HP1233
HP1236
Essentially I am trying to seperate the numbers from the letters and order by either asc or desc just with the numbers to give some order. I wondered if anyone can advise on a good approach to do this withing an orderby clause.
SELECT *
FROM YourTable
ORDER BY CONVERT(int, RIGHT(employer_code, LEN(employer_code) - 2))
Note I did not add any erro checking, but this would help if the pattern changed etc. Even though this is C#, you can convert the code to VB.
void Main()
{
var arrayOfString = new string []{"HP1234","HP1233","HP1236"};
var pat =#"(?<name>\d+)";
Regex r = new Regex(pat, RegexOptions.IgnoreCase);
var orderedItems = arrayOfString.OrderBy(x=>{
var match = r.Match(x);
return match.Groups["name"].Value;
});
foreach (var item in orderedItems)
{
Console.WriteLine(item);
}
}
VB Code
Private Sub Main()
Dim arrayOfString = New String() {"HP1234", "HP1233", "HP1236"}
Dim pat = "(?<name>\d+)"
Dim r As New Regex(pat, RegexOptions.IgnoreCase)
Dim orderedItems = arrayOfString.OrderBy(Function(x) GetSortOrder(x,r))
For Each item As string In orderedItems
Console.WriteLine(item)
Next
End Sub
Function GetSortOrder(x , r)
Dim match = r.Match(x)
Return match.Groups("name").Value
End Function

Resources