How to tell what row a db table is reading from - vb.net

Is there a way to determine the row a set of data has been collected from in a DataTable?
I currently have this code
expression = "date = '" & numericYear & "-" & doubleMonth & "-20'"
foundRows = dbTable.Select(expression)
For count = 0 To foundRows.Length - 1
tableRow =
MessageBox.Show(dbTable.Rows(count).Item(5).ToString())
Next count
The issue is the messagebox shows row 0 then 1 then 2 etc. How can i get it to show the row being read from the Data Table? For example if the event being read is on row 52 of the data table how would i tell that?

you can use the indexof method:
foundRows = dbTable.Select(expression)
For count = 0 To foundRows.Length - 1
rowIndex = dbTable.Rows.IndexOf(foundRows(count))
MessageBox.Show("Row " & cstr(rowIndex) & " " & foundRows(count).Item(5).ToString())
Next count

Related

Array out of bounds error Visual basic forms

Hi im new to this but my code keeps giving me the same error after ive entered three countries and their details. Once i click Ok on my third data entry i get an out of bounds error message.
here is my code if anyone can help
Dim countries(2) As employee
Dim row As Integer
For row = 0 To 2
countries(row).CountryName = InputBox("row" & row & " Enter name of country")
countries(row).population = InputBox("row" & row & " Enter population")
countries(row).Capital = InputBox("row" & row & " enter capital city")
countries(row).GDP = InputBox("row" & row & " Enter GDP value ")
countries(row).worldRanking = InputBox("row" & row & " GDP world rank")
countries(row).Democracy = InputBox("row" & row & " Democracy based? (1 = yes 2 = no")
Next row
For row = 0 To 4
If countries(row).worldRanking < 100 Then
ListBox1.Items.Add(countries(row).CountryName)
End If
Next row
You've defined a 3-element array here:
Dim countries(2) As employee
(2) = 0 to 2 = three elements.
So countries(row) where row > 2 isn't defined.
Arrays aren't always the best choice for collections. Have a look at IEnumerable, List, etc which have more flexibility (IMHO).
You could use GetUpperBound() in your loops, instead of hard-coding a number:
For row = 0 To countries.GetUpperBound(0)

VBA ACCESS Comparing String as they are integer

I am trying to prompt the user to input a range and display all the instruments that are within that range in a subform.
Problem: The upper and lower range is a text field (because some of the range cannot be expressed in integer). As seen in the screenshot, the comparison only compare the first character of the field.
User's input: 5 - 3
On the subform: 36 - 4
It compares 5 and 3 instead of 36
I know vba is doing what it has been told but how can I achieve the result I want?
Here is my code for requering the subform:
Dim Up As Integer
Dim Low As Integer
If Me.Text_L = "" Or IsNull(Me.Text_L) Or Me.Text_U = "" Or IsNull(Me.Text_U) Then
MsgBox ("Please choose a valid range!")
Else
Up = Me.Text_U
Low = Me.Text_L
SQL = SQL_Origin & " WHERE [qry_View_Search].[Upper_Range] <= '" & Up & "' " _
& "AND [qry_View_Search].[Lower_Range] >= '" & Low & "';"
subform_View_Search.Form.RecordSource = SQL
subform_View_Search.Form.Requery
End If
so what i did is made a new column in the query for
IIf(IsNumeric([Upper]), Val([Upper]), Null)
to get all the numeric result.
Then in the vba, I re query the subform as below
SQL = SQL_Origin & " WHERE [qry_View_Search].[Upper] <= cint(Forms![frm_View_Search]![Text_U]) " _
& "AND [qry_View_Search].[Lower] >= cint(Forms![frm_View_Search]![Text_L]);"
Thanks #HansUp !
I have successfully for those cases used Val only:
Value: Val([FieldName])
or:
Value: Val(Nz([FieldName]))

For loop over text boxes in VB

For a = 1 To row
For b = 1 To clmn
Form1.Controls("A" & CStr(a) & "T" & CStr(b)).Text = table.Rows(a)(b)
Next
Next
I'm getting an error "System.NullReferenceException"
My text box names are A1T1, A1T2,A1T3,....
How to use for loop over these text boxes?
Eventhough when i start table index from 0,0 the error remains same
The DataTable use zero-based indexing. So your first row/column indices are 0, not 1.
Dim key As String
For a As Integer = 0 To (table.Rows.Count - 1)
For b As Integer = 0 To (table.Columns.Count - 1)
key = String.Format("A{0}T{1}", (a + 1), (b + 1))
If (Me.Controls.ContainsKey(key)) Then
Me.Controls.Item(key).Text = Convert.ToString(table.Rows(a)(b))
Else
Throw New ApplicationException("You need to create a control named: '" & key & "'")
End If
Next
Next

Append text to existing row in datatable

I'm trying to make a calendar in vb.net and I have come across this problem. I want to append some text into an existing datatable row. When I watch my debugger it says:"In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user.".
Dim aantalRijen As Integer = 1
For x = 0 To 6
Dim dttopdrachten As New DataTable
dttopdrachten = opdrachtendao.getOpdrachtenByDate(Today.AddDays(x))
If dttopdrachten.Rows.Count > aantalRijen Then
aantalRijen = dttopdrachten.Rows.Count
End If
Next
For z = 0 To aantalRijen - 1
Dim r As DataRow
r = dttAgenda.NewRow()
dttAgenda.Rows.InsertAt(r, z)
Next
For i = 0 To 6
Dim aantalItems As Integer = 0
Dim dttopdrachten As New DataTable
dttopdrachten = opdrachtendao.getOpdrachtenByDate(Today.AddDays(i))
aantalItems = dttopdrachten.Rows.Count
For j = 0 To aantalItems - 1
Dim info As String = dttopdrachten.Rows(j).Item(0).ToString & vbCrLf & dttopdrachten.Rows(j).Item(2).ToString & vbCrLf & dttopdrachten.Rows(j).Item(3).ToString & vbCrLf & dttopdrachten.Rows(j).Item(4).ToString & vbCrLf & dttopdrachten.Rows(j).Item(5).ToString & vbCrLf & dttopdrachten.Rows(j).Item(6).ToString
dttAgenda.Rows(j).Item(i) = info
Next
Next
dgvAgenda.DataSource = dttAgenda
In the code above, I first count how many rows I have to make. Afterwards I add the amount of rows to the datatable (columns are added before). Until here it works, but then when I keep debugging I get the error. I tried googling but nothing could help me so far.
Seem problem has been solved without changing anything. So if someone want to make a calendar. Here's the solution ;)

How can I change SQL data order from rows to columns?

I have a snippet of code that writes the data alphabetically from a database ACROSS 3 columns on a web page.
Example:
a result b result c result
d result e result f result
g result h result i result
I need instead to display it alphabetically DOWN the columns, like this:
a result d result g result
b result e result h result
c result f result i result
Keeping in mind I have about 100 data results, it would display the first 1/3 in column one descending, then start a new column and continue, breaking it into 3 equal parts.
The code I have now that sorts across the rows is:
<%
GL="<table width="+Z+"100%"+Z+"border=0 cellpadding=3 celspacing=3>"
sql="select * from guideDef order by guideDesc;"
rs.open sql,adoCon
colCount=0
do while not rs.eof
colCount=(colCount+1) mod 3
if colCount=1 then GL=GL+"<tr>"
GL=GL+"<td valign=middle id=menu1 width="+Z+"33%"+Z+">"+E
GL=GL+"<a href="+Z+"shop.asp?guide="+rs("guide")+"&city=Plantation"+Z+">"+E
GL=GL+rs("guideDesc")+"</a></td>"
if colCount=0 then GL=GL+"</tr>"
GL=GL+E
rs.moveNext
loop
rs.close
if colCount=1 then GL=GL+"<td> </td><td> </td></tr>"+E
if colCount=2 then GL=GL+"<td> </td></tr>"+E
GL=GL+"</table>"
response.write GL
%>
Thanks in advance for any help. I don't write code, so I have tried for hours to change this without success.
Maybe a better solution is to leave the SQL as is and handle this in the application code rather than as a result of the query.
I believe this code will solve your problem:
<%
Set rs = Server.CreateObject("ADODB.RecordSet")
Set adoCon = Server.CreateObject("ADODB.Connection")
adoCon.Open "your connection string here"
Const COLUMN_COUNT = 3
Const adOpenStatic = 3
sql = "SELECT guide, guideDesc FROM guideDef ORDER BY guideDesc;"
rs.Open sql, adoCon, adOpenStatic
CellsRemain = rs.RecordCount Mod COLUMN_COUNT
RowCount = (rs.RecordCount - CellsRemain) / COLUMN_COUNT
Response.Write "<div>Rendering " & rs.RecordCount & " records to a " & _
COLUMN_COUNT & " x " & RowCount & " table with " & _
CellsRemain & " stand-alone cells.</div>"
Response.Write "<table width=""100%"" border=""0"" cellpadding=""3"" celspacing=""3"">" & vbCrLf
done = 0
cell = 0
While done < rs.RecordCount
Response.Write "<tr>" & vbCrLf
While cell < COLUMN_COUNT And done < rs.RecordCount
cell = cell + 1
done = done + 1
guide = "" & rs("guide")
guideDesc = "" & rs("guideDesc")
url = "shop.asp?guide=" + Server.UrlEncode(guide) + "&city=Plantation"
Response.Write "<td>"
Response.Write "<a href=""" & Server.HtmlEncode(url) & """>"
Response.Write Server.HtmlEncode(guideDesc)
Response.Write "</td>" & vbCrLf
If cell < COLUMN_COUNT Then rs.Move RowCount
Wend
If done < rs.RecordCount Then
rs.Move -1 * ((COLUMN_COUNT - 1) * RowCount - 1)
cell = 0
Else
While cell < COLUMN_COUNT
Response.Write "<td> </td>" & vbCrLf
cell = cell + 1
Wend
End If
Response.Write "</tr>" & vbCrLf
Wend
Response.Write "</table>" & vbCrLf
%>
This renders your table the way you want it:
A E H
B F I
C G J
D
You can use the COLUMN_COUNT constant to control how many columns will be made. The algorithm flexibly adapts to that number.
What the code does is basically this:
open a static RecordSet object so we can jump around in it freely
calculate how many rows and columns we need to show all records
<tr>
jump down the RecordSet in RowCount steps, painting <td>s until <tr> is full
jump back to the record that's after the one we started with in step 4
</tr>
if there are still records left, go to step 3
render as many empty cells as we need to make the table well-formed
done.
Look at using the PIVOT AND UNPIVOT commands.
Ignore all the answers about using crosstab, they aren't reading your question.
What I would do is get your results as a giant table and divide them into three different collections, then go though each row inserting item one from collection one, then collection two, then collection three, ect, until you have exhausted all three collections.
The other option would be to write code that would go down one column until one third of the results were used, then move on to the next column, but given the way HTML is ordered, that would be a little more difficult to write.
You could divide the results up into 3 parts (if you know the row count). Print them as 3 separate tables within separate div elements. You could then float the div elements next to each other using CSS.
if this sounds like what you want to do, (since you say you don't write code) let me know if you need help with this.
This is also referred to as crosstab queries. You need to use a case statement with some aggregate function see here
http://www.paragoncorporation.com/ArticleDetail.aspx?ArticleID=25
something like this would be what I would do (in c#):
const int columns = 3;
string[] cells = GetCells(); // load your sql into this
string ret = "<table>";
int numRows = (cells.Length + columns - 1) / columns; // round up
for (int y = 0; y < numRows; y++)
{
ret += "<tr>";
for (int x = 0; x < columns; x++)
{
int elem = x*numRows + y;
if (elem < cells.Length)
ret += "<td>" + cells[elem] + "</td>";
else
ret += "<td> </td>";
}
ret += "</tr>";
}
ret += "</table>";
and GetCells() would look something like:
string[] GetCells()
{
string sql = "SELECT guide, guideDesc FROM guideDef ORDER BY guideDesc";
rs.Open(sql, adoCon, adOpenStatic);
string[] ret = new string[rs.RecordCount]
for (int i=0; i<rs.RecordCount; i++)
{
ret[i] = "<a href=...></a>";
}
return ret;
}