Index was out of range. Must be non-negative and less than the size of the collection - chart databind - asp.net

I'm trying to build a datatable and then bind it to a gridview and chart object. The gridview appears fine but when I build the x,y array and bind them to the chart object I get the error above.
I've read many forums to understand that the index is looking at a field that is out of range but I've queried in the immediate window all the fields and the are clearly values there. There error occurs as soon as I bind it to the chart object and I don't know why the chart object doesn't just display properly.
This is my aspx codebehind:
Dim dt As DataTable = New DataTable()
dt.Columns.Add("CompanyName")
dt.Columns.Add("Amount")
dt.Columns.Add("Proportion")
Using DBContext As New fundmatrixEntities
Dim queryUnits = (From c In DBContext.Units Where c.SavingApplicationId = savAppId Select New With {.LoanAppId = c.LoanApplicationId}).Distinct().ToList()
Dim companyName As String = ""
Dim savingsAmount As String = ""
Dim totalProportion As String = ""
Dim totalSavingsAmount As String = ""
For Each loan In queryUnits
If Not loan.LoanAppId Is Nothing Then
companyName = classSQLDirect.ExecQuery("SELECT companyname FROM companyprofile where loanapplicationid='" & loan.LoanAppId.ToString & "'")
savingsAmount = classSQLDirect.ExecQuery("SELECT SUM(Amount) from unit where SavingApplicationId='" & savAppId.ToString & "' and LoanApplicationId='" & loan.LoanAppId.ToString & "'")
totalSavingsAmount = classSQLDirect.ExecQuery("SELECT amount FROM SavingApplication WHERE SavingApplicationId='" & savAppId.ToString & "'")
totalProportion = ((savingsAmount / totalSavingsAmount) * 100) & "%"
dt.Rows.Add(companyName, savingsAmount, totalProportion)
End If
Next
gvwBusinesses.DataSource = dt
gvwBusinesses.DataBind()
End Using
Dim x As String() = New String(dt.Rows.Count - 1) {}
Dim y As String() = New String(dt.Rows.Count - 1) {}
For i As Integer = 0 To dt.Rows.Count - 1
x(i) = dt.Rows(i)(0).ToString()
y(i) = dt.Rows(i)(2).ToString()
Next
chart1.Series(0).Points.DataBindXY(x, y)
chart1.Series(0).ChartType = SeriesChartType.Pie
The code errors on the line
chart1.Series(0).Points.DataBindXY(x, y)

Related

How to separate group of line series in different panes in DevExpress BootstrapChart?

Right now, I'm developing web application using DevExpress BootstrapChart (v17.2.13.0) and I have binded the control with object datasource. Here is the example data used to be displayed in the graph:
Here is my objectives:
The graph will show the values of "ademand_im" and "rdemand_im" in different panes (I named them pane "A" and "B")
Each pane has "data_time" (date and time) as X-axis and the values ("ademand_im" or "rdemand_im") as Y-axis
Also, the values in each pane will be grouped by "hardware_id" so, in this case, there should be 2 line series of "83245551" and "88310991" in each pane (Note that "hardware_id" can be varied from time to time).
So the graph should look like this:
However, what I only acheive at this moment is that either the line series are shown in both panes but not grouped or not show anything in the graph.
Here is my code:
<dx:BootstrapChart ID="chart" ClientInstanceName="chart" runat="server"
DataSourceID="ods_ChartData" Height="640px" TitleText="Chart Data" CrosshairEnabled="true" Panes="A,B">
<ClientSideEvents Init="OnChartInit" />
<SettingsToolTip Shared="true" Enabled="true" OnClientCustomizeTooltip="ChartToolTip" />
<ArgumentAxis ArgumentType="System.DateTime" GridVisible="True" MinorGridVisible="True"
TickVisible="True" MinorTickVisible="True" TickInterval="1" MinorTickCount="3" TitleText="Date">
<Label DisplayMode="Rotate" RotationAngle="-0" Format-Formatter="FormatDate" />
</ArgumentAxis>
<ValueAxisCollection>
<dx:BootstrapChartValueAxis Pane="A" TitleText="ademand_im" />
<dx:BootstrapChartValueAxis Pane="B" TitleText="rdemand_im" />
</ValueAxisCollection>
<SettingsCommonSeries Type="Line" ArgumentField="data_time" Point-Size="0" />
<SettingsSeriesTemplate NameField="hardware_id" />
<SeriesCollection>
<dx:BootstrapChartLineSeries Pane="A" ValueField="ademand_im" />
<dx:BootstrapChartLineSeries Pane="B" ValueField="rdemand_im" />
</SeriesCollection>
</dx:BootstrapChart>
In this code, if I remove the "SettingsSeriesTemplate" line, the data will show in both panes but only in single line in each pane. However, if I keep this line the graph will not show anything.
After I tried to understand how this control works, the only solution I found is that I have to pivot "hardware_id" columns into "ademand_im" and "rdemand_im" values, which may be not the ideal one.
So instead of having "hardware_id", "ademand_im" and "rdemand_im" columns, the table should be transformed to have like "ademand_im_83245551", "ademand_im_88310991", "rdemand_im_83245551" and "rdemand_im_88310991" columns instead.
This is how the table after transforming looks like:
Here is the function codes that I used to transform the table (VB.NET):
<Extension()>
Public Function PivotDataTableColumnGroup(srcData As DataTable, rowGroupField As String, pivotColumnField As String, valueGroupFields As IEnumerable(Of String),
Optional ValueGroupColumnName As Func(Of String, String, String) = Nothing,
Optional otherFields As IEnumerable(Of String) = Nothing,
Optional GetOtherFieldValue As Func(Of DataTable, String, Object, Object) = Nothing
) As DataTable
Dim groupValueList As List(Of Object) = srcData.GetDistinctValuesByColumnName(rowGroupField)
Dim pivotValueList As List(Of Object) = srcData.GetDistinctValuesByColumnName(pivotColumnField)
Dim hasOtherFieldColumn As Boolean = Not (otherFields Is Nothing Or GetOtherFieldValue Is Nothing)
Dim dt As New DataTable
With dt
.Columns.Add(rowGroupField, srcData.Columns(rowGroupField).DataType)
For i As Integer = 0 To valueGroupFields.Count - 1
For j As Integer = 0 To pivotValueList.Count - 1
Dim columnName As String = GetColumnNameFromGroupFieldAndPivotValues(valueGroupFields(i), pivotValueList(j), ValueGroupColumnName)
dt.Columns.Add(columnName, srcData.Columns(valueGroupFields(i)).DataType)
Next
Next
If hasOtherFieldColumn Then
For i As Integer = 0 To otherFields.Count - 1
.Columns.Add(otherFields(i), srcData.Columns(otherFields(i)).DataType)
Next
End If
For i As Integer = 0 To groupValueList.Count - 1
Dim currentGroupValue As Object = groupValueList(i)
Dim dr As DataRow = dt.NewRow()
dr(rowGroupField) = currentGroupValue
If hasOtherFieldColumn Then
For j As Integer = 0 To otherFields.Count - 1
dr(otherFields(j)) = DBNullIfNothing(GetOtherFieldValue(srcData, otherFields(j), currentGroupValue))
Next
End If
For j As Integer = 0 To valueGroupFields.Count - 1
Dim currentField As String = valueGroupFields(j)
For k As Integer = 0 To pivotValueList.Count - 1
Dim currentPivotValue As Object = pivotValueList(k)
Dim columnName As String = GetColumnNameFromGroupFieldAndPivotValues(valueGroupFields(j), pivotValueList(k), ValueGroupColumnName)
Dim value As Object = (From row In srcData.AsEnumerable
Where row(rowGroupField) = currentGroupValue _
AndAlso row(pivotColumnField) = currentPivotValue
Select row(currentField)
).FirstOrDefault
dr(columnName) = DBNullIfNothing(value)
Next
Next
dt.Rows.Add(dr)
Next
End With
Return dt
End Function
<Extension()>
Public Function GetDistinctValuesByColumnName(dt As DataTable, columnName As String) As List(Of Object)
Dim valueList As List(Of Object) = (From row As DataRow In dt.AsEnumerable
Where Not IsDBNull(row(columnName))
Order By row(columnName)
Select row(columnName) Distinct
).ToList
Return valueList
End Function
Private Function GetColumnNameFromGroupFieldAndPivotValues(groupField As String, pivotValue As Object, Optional ValueGroupColumnName As Func(Of String, String, String) = Nothing) As String
Dim columnName As String = groupField & "_" & pivotValue.ToString()
If ValueGroupColumnName IsNot Nothing Then
columnName = ValueGroupColumnName(groupField, pivotValue)
End If
Return columnName
End Function
Public Function DBNullIfNothing(o As Object) As Object
If o Is Nothing Then Return DBNull.Value
Return o
End Function
And this is how I used the function to transform the table:
Dim chartData As DataTable = result.PivotDataTableColumnGroup("data_time", "hardware_id", {"ademand_im", "rdemand_im"}, Nothing, Nothing, Nothing)
ResultChartData = chartData 'Stored in ASPxHiddenField in JSON form
After that, instead of setting chart series properties in aspx file, I have to add chart series manually in code behind:
Private Sub chart_LoadProfile_DataBound(sender As Object, e As EventArgs) Handles chart_LoadProfile.DataBound
Using ResultChartData
Dim seriesList As List(Of String) = (From col As DataColumn In ResultChartData.Columns
Where col.ColumnName <> "data_time"
Order By col.ColumnName
Select col.ColumnName
).ToList
Dim hardWardCount As Integer = (From s In seriesList Where s.Contains("ademand_im_")).Count
Dim showInLegend As Boolean = hardWardCount > 1
With chart_LoadProfile.SeriesCollection
.Clear()
For i As Integer = 0 To seriesList.Count - 1
Dim fieldName As String = seriesList(i)
Dim hardwareId As String = seriesList(i).Split("_")(2)
Dim series As New BootstrapChartLineSeries
With series
.ArgumentField = "data_time"
.ValueField = fieldName
.Point.Size = 0
.ShowInLegend = showInLegend
If fieldName.Contains("ademand_im_") Then
.Pane = "A"
.Name = "kW - " & hardwareId
Else
.Pane = "B"
.Name = "kVar - " & hardwareId
End If
End With
.Add(series)
Next
End With
End Using
End Sub

ASP.NET MS chart control: Data points insertion error. Only 2 Y values can be set for this data series. Parameter name: dataSource

I'm getting this error on my MS Chart control:
Data points insertion error. Only 2 Y values can be set for this data series.
Parameter name: dataSource
It occurs on line chartPriceHistory_STATIC.DataBind() in my code below.
I think it has got something to do with the way I'm adding points (AddXY) but can't figure out what it is.
I tried these 2 code options:
Option 1
chartPriceHistory_STATIC.Series(seriesName).Points.AddXY(get3LetterMonth(CDate(row("createdate")).Month) + "-" + CDate(row("createdate")).Year.ToString, {CType(row("price"), Integer), totalobjects})
Option 2
chartPriceHistory_STATIC.Series(seriesName).Points.AddXY(get3LetterMonth(CDate(row("createdate")).Month) + "-" + CDate(row("createdate")).Year.ToString, CType(row("price"), Integer))
chartPriceHistory_STATIC.Series("totalobjects").Points.AddXY(get3LetterMonth(CDate(row("createdate")).Month) + "-" + CDate(row("createdate")).Year.ToString, totalobjects)
Both throw the same error...what am I missing?
Dim mycommand As New SqlCommand("SELECT avgprice, createdate, totalobjects FROM avgprices", myConnection)
Dim dtPrices As New System.Data.DataTable
dtPrices.Columns.Add("price", System.Type.GetType("System.Int32"))
dtPrices.Columns.Add("createdate", System.Type.GetType("System.DateTime"))
dtPrices.Columns.Add("totalobjects", System.Type.GetType("System.Int32"))
Dim dr As System.Data.DataRow
Try
Dim reader As SqlDataReader = mycommand.ExecuteReader()
While reader.Read
dr = dtPrices.NewRow()
dr("price") = reader("price")
dr("createdate") = reader("createdate")
dr("totalobjects") = reader("totalobjects")
dtPrices.Rows.Add(dr)
End While
Catch ex As Exception
End Try
' Initializes a New instance of the DataSet class
Dim myDataSet As DataSet = New DataSet()
'Adds rows in the DataSet
myDataSet.Tables.Add(dtPrices)
chartPriceHistory_STATIC.Series.Clear()
Dim seriesName As String = "Avg price"
chartPriceHistory_STATIC.Series.Add(seriesName)
chartPriceHistory_STATIC.Series(seriesName).XValueMember = "Date"
chartPriceHistory_STATIC.ChartAreas.Add("ChartArea1")
chartPriceHistory_STATIC.Series(seriesName).YValuesPerPoint = 2
chartPriceHistory_STATIC.ChartAreas(0).AxisY.MajorGrid.Enabled = True
chartPriceHistory_STATIC.ChartAreas(0).AxisY.Title = "Price"
Dim totalobjects As Integer = 1
chartPriceHistory_STATIC.Series.Add("Series2")
chartPriceHistory_STATIC.Series("Series2").YAxisType = AxisType.Secondary
chartPriceHistory_STATIC.Series("Series2").XValueMember = "Date"
chartPriceHistory_STATIC.Series("Series2").YValueMembers = "totalobjects"
chartPriceHistory_STATIC.Series("Series2").Name = "totalobjects"
chartPriceHistory_STATIC.Series("totalobjects").ChartType = SeriesChartType.Line
chartPriceHistory_STATIC.Series("totalobjects").ToolTip = "Total objects"
chartPriceHistory_STATIC.Series(0).YAxisType = AxisType.Primary
chartPriceHistory_STATIC.Series(1).YAxisType = AxisType.Secondary
For Each row As DataRow In myDataSet.Tables(0).Rows
totalobjects += 1
'I tried: these 2 options, both generate the same error
chartPriceHistory_STATIC.Series(seriesName).Points.AddXY(get3LetterMonth(CDate(row("createdate")).Month) + "-" + CDate(row("createdate")).Year.ToString, {CType(row("price"), Integer), totalobjects})
chartPriceHistory_STATIC.Series(seriesName).Points.AddXY(get3LetterMonth(CDate(row("createdate")).Month) + "-" + CDate(row("createdate")).Year.ToString, CType(row("price"), Integer))
chartPriceHistory_STATIC.Series("totalobjects").Points.AddXY(get3LetterMonth(CDate(row("createdate")).Month) + "-" + CDate(row("createdate")).Year.ToString, totalobjects)
Next
chartPriceHistory_STATIC.DataSource = myDataSet
chartPriceHistory_STATIC.DataBind()
You need to set the YValueMembers for the "Avg price" series, too.
Add this line (use whatever string you want to plot on Y axis):
chartPriceHistory_Static.Series(seriesName).YValueMembers = "totalobjects"
Add it just before this line:
chartPriceHistory_Static.Series(seriesName).YValuesPerPoint = 2
Also, your name of date/createdate column is inconsistent - you won't see the plots until you correct that.
If you are only adding 1 YValue, you can reduce the YValuesPerPoint down to 1 again, without error.
Tested. Works fine. Cheers!
Instead of using Points.AddXY method try to create point through new class and add them to chart
foreach (var result in data)
{
point = new DataPoint();
point.AxisLabel = result.XData;
point.YValues = new double[] { result.YData };
point.Color = result.Color;
seriesDetail.Points.Add(point);
}

Creating SQL query in VB.net from a Checkboxlist

I have a checkboxlist and I populate it dynamically from a database. For example after i populate the checkboxlist is like that:
Los Angeles
New York
London
Berlin
Amsterdam
I want to create a SQL query according to the checkboxes are checked. If i want to choose only one city (e.g. only New York) i want the result to be:
(City = 2)
Thats works properly but when i have multiple cities (e.g. New York, London and Amsterdam) i want the result to be for example:
(City = 2) OR (City = 3) OR (City = 5)
Or if i choose Los Angeles and Berlin I want the result to be like this:
(City = 1) OR (City = 4)
How can i achieve this? That's my code below but I am stacked. Any ideas?
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim var As String = ""
Dim counter As Integer = 0
Dim myList As New List(Of String)()
For i As Integer = 0 To CheckBoxList1.Items.Count - 1
If CheckBoxList1.Items(i).Selected Then
myList.Add(i + 1)
counter = counter + 1
If counter = 1 Then
var = "(City =" & i + 1 & ")"
Else
Console.WriteLine(myList(1))
Dim myArray As String() = myList.ToArray()
For j As Integer = 1 To myArray.Length
Dim var2 As String = " OR (City =" & counter & ")"
var = "(City =" & myArray(0) & ")" & var2
Next
End If
End If
Next
SQL = "SELECT * FROM Data1 WHERE (" & var & ") ORDER BY [ID]"
Session("Search") = SQL
Server.Transfer("Data_Form.aspx")
End Sub
What I recommend most strongly is to look into Table-value Parameters:
http://msdn.microsoft.com/en-us/library/bb675163(v=vs.110).aspx
This will fix your issue and help you avoid sql injection vulnerabilities.
But if you really insist on using string concatenation, try using an IN() condition, where you end up with something more like CITY IN (1,2) instead of (City = 1 OR City = 2). You can make this a bit easier to write by leading with an unused ID, like so:
Dim cityClause As String = " CITY IN (-1{0})" 'start with a valid clause
Dim cityIDs As String = ""
For Each box As ListItem In CheckBoxList1.Items.Where(Function(b) b.Selected)
'Try storing the ID for each city in the value part of each listitem,
' rather than using the index order
cityIDs = cityIDs & "," & box.Value
Next box
cityClause = string.Format(cityClause, cityIDs)
You can use City IN(2,3,5) instead of (City = 2) OR (City = 3) OR (City = 5):
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim condition As String = ""
For i As Integer = 0 To CheckBoxList1.Items.Count - 1
If CheckBoxList1.Items(i).Selected Then
condition = condition & "," & (i + 1)
End If
Next
SQL = "SELECT * FROM Data1 WHERE (" & condition.SubString(1) & ") ORDER BY [ID]"
Session("Search") = SQL
Server.Transfer("Data_Form.aspx")
End Sub

Looping through textboxes and labels

Im doing this project for an online test in ASP.NET in VB im using Microsoft visual studios 2012.
Im trying to get a loop going through my textboxes and check them against a word this will be change to be validated against a database to see if the answer are correct but when I do my loop I cannot get my text from the textbox.
Please see below
Private Sub GoGoGo()
Dim Textboxname As String '
Dim textbox As Object
Dim TextboxText As Object
Dim Labelname As String
Dim label As Object
Dim LabelText As Object
Dim Number As Integer = 1
Dim MaxTime As Integer = 9
Dim Currentloop As Integer = 1
For check As Integer = Currentloop To MaxTime
If Currentloop <= MaxTime Then
Textboxname = "TextQ" + Number
textbox = Textboxname
TextboxText = textbox
textbox.ReadOnly = True
End If
If Currentloop <= MaxTime Then
Labelname = "Label" + Number
label = Labelname
LabelText = label.Text
label.Visible = True
End If
Number = Number + 1
If TextboxText = "" Then
label.Text = "no imput"
label.ForeColor = Drawing.Color.Black
End If
If TextboxText = "server" Then
label.Text = "Correct"
label.ForeColor = Drawing.Color.Green
End If
If TextboxText = "Wrong" Then
label.Text = "Wrong"
label.ForeColor = Drawing.Color.Red
End If
If check = 9 Then
Exit For
End If
Next
End Sub
It looks like you are trying to use the string identifier of the control in place of the the actual control. Instead, you should take this identifier and search for the actual control on the page. You can do this using the FindControl method
Your function would therefore look something like (not compile tested):
Private Sub GoGoGo()
'
Dim oTextBox As TextBox
Dim oLabel As Label
Dim MaxTime As Integer = 9
Dim Currentloop As Integer = 1
For check As Integer = Currentloop To MaxTime
If Currentloop <= MaxTime Then
'NB You may have to use a recursive call to FindControl. See below.
oTextBox = CType(Page.FindControl("TextQ" & CStr(check)), TextBox)
OTextBox.ReadOnly = True;
End If
If Currentloop <= MaxTime Then
'NB You may have to use a recursive call to FindControl. See below.
oLabel = CType(Page.FindControl("Label" & CStr(check)), Label)
oLabel.Visible = True
End If
If oTextBox.Text = "" Then
oLabel.Text = "no imput"
oLabel.ForeColor = Drawing.Color.Black
End If
If oTextBox.Text = "server" Then
oLabel.Text = "Correct"
oLabel.ForeColor = Drawing.Color.Green
End If
If oTextBox.Text = "Wrong" Then
oLabel.Text = "Wrong"
oLabel.ForeColor = Drawing.Color.Red
End If
Next
End Sub
Some notes:
You don't need all of those variables. Instead, just find the actual controls, and interact with the properties directly - just check the TextBox.Text value when you need to, and set the Label.text property directly. The set is especially important as you want to update the original control property so it is shown on the page.
Similarly, you don't need Number - you can use check as this is your loop counting variable.
Whether you use the + operator or the & operator for string concatenation is up to you. There's already a good question and several answers here.
You also don't need the exit condition for the loop - the loop will exit as soon as you reach MaxTime. If you want it to exit early, just vary your To condition (e.g. Currentloop To MaxTime - 1)
UPDATE:
Page.FindControl will only work with controls that are immediate children of the root element on the page. Instead, you should try calling FindControl recursively. You should also make sure that a control with the id TextQ1 exists - look in the HTML source for the page on the client to make sure a TextBox with this id exists.
There are many examples of this on the net. Here's a VB.Net version (source: http://www.pavey.me/2007/09/recursive-pagefindcontrol-for-vbnet.html) that you can add to your page:
Public Function FindControlRecursive(Of ItemType)(ByVal Ctrl As Object, ByVal id As String) As ItemType
If String.Compare(Ctrl.ID, id, StringComparison.OrdinalIgnoreCase) = 0 AndAlso TypeOf Ctrl Is ItemType Then
Return CType(Ctrl, ItemType)
End If
For Each c As Control In Ctrl.Controls
Dim t As ItemType = FindControlRecursive(Of ItemType)(c, id)
If t IsNot Nothing Then
Return t
End If
Next
Return Nothing
End Function
Your line in the code above would then become:
oTextBox = FindControlRecursive(of TextBox)(Page.Controls(0), "TextQ" & CStr(check))
You'd also need to do the same for the Label control.
It Look like you are using only name istead of textbox try with the code below
Private Sub GoGoGo()
Dim Textboxname As String '
Dim textbox As TextBox
Dim TextboxText As Object
Dim Labelname As String
Dim label As Object
Dim LabelText As Object
Dim Number As Integer = 1
Dim MaxTime As Integer = 9
Dim Currentloop As Integer = 1
For check As Integer = Currentloop To MaxTime
If Currentloop <= MaxTime Then
Textboxname = "TextQ" + Number
textbox = Ctype(Me.Controls(Textboxname), TextBox)
TextboxText = textbox.Text
textbox.ReadOnly = True
End If
If Currentloop <= MaxTime Then
Labelname = "Label" + Number
label = Labelname
LabelText = label.Text
label.Visible = True
End If
Number = Number + 1
If TextboxText = "" Then
label.Text = "no imput"
label.ForeColor = Drawing.Color.Black
End If
If TextboxText = "server" Then
label.Text = "Correct"
label.ForeColor = Drawing.Color.Green
End If
If TextboxText = "Wrong" Then
label.Text = "Wrong"
label.ForeColor = Drawing.Color.Red
End If
If check = 9 Then
Exit For
End If
Next
End Sub

Array list error second array replace the first array

I have a problem.
Dim Maxis As String
'Dim MaxisExtra As String
Dim b As New ArrayList
Dim WS As New WebService1.Service1
Dim cnt As String
Dim MRWS As New MobileReload_WS.MobileReload_WS
cnt = WS.StockCountTelco(1, Session("Maxis"))
If CInt(cnt) >= CInt(DropDownList1.SelectedItem.Text) Then
Dim sLock As String
sLock = MRWS.LockAStock(1, 1, "Online", Session("Maxis"), DropDownList1.SelectedItem.Text)
Session("sLock") = sLock
If sLock = "" Then
PopupMsgBox("Unable to allocate Stock")
Else
Maxis = "Maxis" & ";" & Session("Maxis") & ";" & DropDownList1.SelectedItem.Text & ";" & Session("Cost")
'If MaxisExtra = "" Then
' b.Add(Maxis)
' Elseif
' MaxisExtra = MaxisExtra + Maxis
' b.Add(MaxisExtra)
'End If
End If
Else
PopupMsgBox("Not enough stock")
End If
b.Add(Maxis)
Session("Transaction") = b
End Sub
The first time i enter the string into the arraylist it is okay. But when the user press the button add again the second time, it replace the first string. Can anyone help me how to save the string into the second slot based on my coding?
If you're talking about the b ArrayList, then you're creating a new one each time and storing the new ArrayList in Session("Transaction")
Maybe you mean something like this instead...
Dim b as ArrayList = Session("Transaction")
If b Is Nothing Then
b = new ArrayList
End If
...
Session("Transaction") = b
Although it's difficult to say exactly, because your code is very messy and not clear
You put the array list in a session variable, but you never read it back. You create a new array list each time, so it will always be empty and replace the previous one.
Get the array list from the session variable if there is one:
Dim b As ArrayList = Session("Transaction")
If b Is Nothing Then b = New ArrayList

Resources