I have
Table student, student_subject and subject_bsit
"student"
-----------------------
|studentID | FullName |
-----------------------
|1234 | John |
|1235 | Michael |
|1236 | Bryce |
"subject_bsit"
-----------------------------------
|subject_id| subject_name |grade |
-----------------------------------
| 1 | Programming | 3 |
| 2 | Networking | 2.5 |
| 3 | Algorithm | 1.75|
| 4 | Physical Educ | 2 |
This is the Junction table to connect the
two now.
"student_subject"
----------------------------
| student_id | subject_id |
----------------------------
| 1235 | 1 |
| 1235 | 2 |
| 1235 | 3 |
| 1234 | 1 |
As you can see the table ID 1235 is michael He has three three subjects, subject_id 1,2 and 3. What I want to do is to display all the subject name and grades of michael in textboxes, not in a datagrid view.
As of now I still have failed to output it to textboxes. This is my sample query
sql = "SELECT subject_name " & _
" FROM student_subject " & _
" INNER JOIN subject_bsit ON subject_bsit.subject_id = student_subject.sub_id" & _
" where student_subject.student_id='" & Txtbox.Text & "'"
The Txtbox.text in the last query is where the user will input the ID number.
This is my code on displaying the data to the textbox. I don't have any idea or approach on how can i loop on the textbox and display it on each textbox.
cmd = New MySqlCommand(sql, myconn)
dr = cmd.ExecuteReader
While dr.Read
TextBox1.Text = dr.Item("subject_name").ToString
TextBox2.Text = dr.Item("subject_name").ToString
End While
This is the sample User Interface of what i am trying to achieve. Thank you so much.
When you read a query's resultset, you use a loop as you know.
While dr.Read
' run this for every row in your resultset
...
End While
The While loop keeps going until you have read all the rows.
You don't have to use a loop. If you wish you can read the rows one at a time, like this
If dr.Read
' just the first row
End If
If dr.Read
' just the second row
End If
If dr.Read
' just the third row
End If
...
From your question I guess you have Textbox1, Textbox2, ... Textbox5 on your form. I also guess you have Grade1, Grade2 ....
To handle both of the subject name and grade, change the first line of your query to
sql = "SELECT subject_name, grade " & _
You can populate those items like this:
If dr.Read
TextBox1.Text = dr.Item("subject_name").ToString
Grade1.Text = dr.Item("grade").ToString
End If
If dr.Read
TextBox2.Text = dr.Item("subject_name").ToString
Grade2.Text = dr.Item("grade").ToString
End If
If dr.Read
TextBox3.Text = dr.Item("subject_name").ToString
Grade3.Text = dr.Item("grade").ToString
End If
' more of these sets of four lines to fill your whole form.
This solves your problem. But you probably notice it is absurdly repetitive. What you really need is an array (actually two arrays) of textboxes. You create, and then fill in, these texboxes in your program. I have not debugged this: that is for you do to.
Dim Subjects As Textbox()
Dim Grades As Textbox()
...
Dim rownumber, Y
rownumber = 0
Y = 200
Dim Subject
Dim Grade
While dr.Read
Subject = New Textbox
Subject.Text = dr.Item("subject_name").ToString
Subject.Width = 200
Subject.Height = 40
Subject.X = 175
Subject.Y = Y
Subjects(rownumber) = Subject
Form.Controls.Add(Subject)
Grade = New Textbox
Grade.Text = dr.Item("grade").ToString
Grade.Width = 50
Grade.Height = 40
Grade.X = 400
Grade.Y = Y
Grades(rownumber) = Grade
Form.Controls.Add(Grade)
rownumber = rownumber + 1
Y = Y + 50
End While
When this runs you will have two columns of controls, one for each subject. But this code is complex, and you have to do all the layout of your form with Something.Y = value and then Y = Y + 50 arithmetic.
That's why grid controls exist. They take care of that kind of thing.
If you are looking to create Textboxes dynamically then you should refer to the #OJones answer
You can simply loop over Me.Controls.OfType(Of TextBox)()
cmd = New MySqlCommand(sql, myconn)
dr = cmd.ExecuteReader
While dr.Read
For Each txt As TextBox In Me.Controls.OfType(Of TextBox)()
txt.Text = dr.Item("subject_name").ToString
Next
End While
Or you can do a similar approach if you need to fill the first subjects name inside the textboxes (if returned subjects are more than textboxes additional subjects will be ignored):
While dr.Read = True
Dim txt As New TextBox = DirectCast(Me.Controls.Find(string.Format("Textbox{0}", cnt ),false).FirstOrDefault(),Textbox);
If Not txt Is Nothing Then txt.Text = dr.Item("subject_name").ToString
cnt += 1
End While
dr.Close()
Related
I have a AWS RDS instance using MySQL. The login has full admin right.
I am trying to perform a SELECT * FROM table and output all the contents of the table onto an Excel worksheet using VBA. Still kind of new to this so I am starting with the basics.
I am using the chunk of code below:
Sub test()
Dim Server_Name As String, DB_Name As String, User_ID As String, User_Pass As String
Dim Rs As Variant, Cn As Variant
Dim sqlStr As String
Dim includeField As Boolean
Dim tgtCell As Range
Dim col As Long
Server_Name = "arachnophobia.blabla.rds.amazonaws.com"
DB_Name = "Spidey"
User_ID = "Peter"
User_Pass = "Parker"
sqlStr = "SELECT * FROM crime"
Set Cn = CreateObject("ADODB.Connection")
Cn.Open "Driver={MySQL ODBC 8.0 Unicode Driver};" & _
";Server=" & Server_Name & _
";Database=" & DB_Name & _
";Uid=" & User_ID & _
";Pwd=" & User_Pass
Set Rs = CreateObject("ADODB.Recordset")
Set Rs = Cn.Execute(sqlStr)
Set tgtCell = Sheets("Main").Range("A1")
includeField = True
If includeField Then
tgtCell.Offset(1, 0).CopyFromRecordset Rs
For col = 0 To Rs.Fields.Count - 1
Sheets(tgtCell.Parent.Name).Cells(1, col + 1).Value = Rs.Fields(col).Name
Next
Else
tgtCell.CopyFromRecordset Rs
End If
End Sub
The crime table consists of 4 column:
|S/N (PK) |DateID |CrimeID |Reason |
|1 |01/02/19 |32155 |Fun |
|2 |03/02/19 |32255 |Bored |
|3 |06/02/19 |32555 |Meh |
|4 |07/02/19 |32755 |Duh |
|5 |09/02/19 |32855 |Null |
I executed the code above and the output on the Excel sheet is:
|S/N (PK) |DateID |CrimeID |Reason |
|1 | | | |
|2 | | | |
|3 | | | |
|4 | | | |
|5 | | | |
Basically, I am only getting the Field names and the Primary Key values but not anything else.
I tried running the same code on my local server and it works just fine.
Is there anything I did not take into consideration in the code that causes all the missing column information?
Update:
I have done more testing. tgtCell.CopyFromRecordset Rs results in the output above. However, if I try looping through the recordset using this:
xlrow = 1
Do While Not Rs.EOF
xlcol = 1
For col = 1 To Rs.Fields.Count
tgtCell.Offset(xlrow, xlcol - 1).Value = Rs(col - 1).Value
xlcol = xlcol + 1
Next
Rs.movenext
xlrow = xlrow + 1
Loop
I will end up with my desired output. I don't quite understand why this is so? Was I missing some kind of library reference?
what happens if you remove the following code?
For col = 0 To Rs.Fields.Count - 1
Sheets(tgtCell.Parent.Name).Cells(1, col + 1).Value = Rs.Fields(col).Name
Next
To me, your line tgtCell.Offset(1, 0).CopyFromRecordset Rs should just copy the data straight in so I'm wondering if your subsequent code is overwriting/clearing the data.
i am having trouble im using visual studio in my other windows form same code it is working properly but i am using it now on another form and it doesn't filter anymore i don't know why.
I am trying to display a list in datagrid view and filter it using two combobox.
Here is a example database of the subject:
-------------------------------------------------------------------------------
|subject_id|subject_name|subject_code|subject_units| sem |year_level
------------------------------------------------------------------------------
| 1 | MATH | Math101 | 3 |First Semester | First Year
| 2 | English | ENG101 | 3 |First Semester | First Year
| 3 | Prgrming | IT101 | 3 |Second Semester| First Year
| 4 | Networking| IT203 | 3 |Second Semester| First Year
Here is my code.
myconn = New MySqlConnection
myconn.ConnectionString = connstring
myconn.Open()
tables = ds.Tables
ds = New DataSet
tables = ds.Tables
Dim Query As String
Query = "selct * from subject_bsit"
'*** CHECKING IF ALL REQUIRED FIELDS ARE PRESENT *****
If ComboBox1.Text = "" Or ComboBox2.Text = "" Then
MessageBox.Show("Complete all fields.")
Exit Sub
End If
If (ComboBox1.Text = "All") And (ComboBox2.Text = "First Semester") Then
da = New MySqlDataAdapter("Select subject_id as 'ID',subject_name as 'SUBJECT',subject_code as 'SUBJECT CODE',subject_units as 'UNITS',sem as 'Semester',year_level as 'YEAR LEVEL' from subject_bsit where sem = '" + ComboBox2.Text + "' or year_level = '" + ComboBox1.Text + "' ", myconn)
da.Fill(ds, "subject_bsit")
Dim view As New DataView(tables(0))
source1.DataSource = view
DataGridView1.DataSource = view
DataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)
End If
As you can see in the sample image the results must be
All year Level First year to Fourth year but only ALL First Semester subject
but in the picture it also show the Second semester.
It makes me confuse because i have the exact same code in other form but it is working properly. Please help thank you so much.
You just need to replace the logical operator “or” with “and” in your sql string like this way:
from subject_bsit where sem = '" + ComboBox2.Text + "' and year_level = '" + ComboBox1.Text + "' ", myconn)
I hope this can help you bro, ^_^
Restarting Visual Studio solves the problem.
I am trying to concatenate a list of attributes for same products which are in different rows.
For example:
Column A (fruit_name) has fruit names and Column B (fruit_colors) has colors.
I want fruit color on the same row as the fruit.
|**fruit_name** | **fruit_colors** |
|----------------|------------------|
|Apple |Red |
|Apple |Yellow |
|Apple |Green |
|Apple |White |
|Banana |Red |
|Banana |Yellow |
|Banana |Green |
|Banana |White |
|Plum |White |
|Plum |Bluish |
|Plum |Purple |
The result should be:
|**name** | **colors** |
|----------------|---------------------------|
|Apple | Red, Yellow, Green, White |
|Banana | Red, Yellow, Green, White |
|Plum | White, Bluish, Purple |
This is what I have:
Set fruit_name = rstsource.Fields("fruits")
Set source_fruit = rstsource.Fields("fruits_list_type")
rstsource.MoveFirst
count = rstsource.RecordCount
counter = 0
fruit_name = source_fruit
result = source_table
Do
Do
counter = counter + 1
result = result & ", " & source_table
rstsource.MoveNext
Loop Until counter = count Or fruit_name <> source_fruit
rstdest.AddNew
rstdest.Fields("names") = fruit_name
rstdest.Fields("colors") = result
rstdest.Update
fruit_name = source_fruit
result = " "
Loop Until rstsource.EOF
This is the result - Some has comma on the front.
Banana - White, White
Apple - ,Yelow, Red
Banana- ,Red
Banana - White, White
Apple , Green
Plum - ,Green
Plum - ,Red
Banana - ,Red
At the end there is a
Run time error 3021.
I would have a read and download of Allen Browne's Concat function http://allenbrowne.com/func-concat.html - It will do exactly what you want.
This will be for report or display purposes only - you shouldn't store the data like this.
How to create this query to combine values?
I have a table with the following structure and values:
EventID PersonName
----------- ------------
1 John
1 Peter
1 Sylvia
2 John
2 Sylvia
3 Peter
3 June
I'd like to run a query and get results in the following format:
EventID PersonNames
-------- ---------------
1 John, Peter, Sylvia
2 John, Sylvia
3 Peter, June
Is there a query that will accomplish this?
Concatenate fields in same table
Author(s) Dev Ashish
(Q) I need to concatenate a field in the format "Value1; Value2; Value3" etc. for each unique value of another field in the same table. How can I do this?
(A) Using the fConcatFld function, in the Northwind database, the following query should return a concatenated list of all CustomerIDs if you group by ContactTitle.
SELECT ContactTitle, fConcatFld("Customers","ContactTitle","CustomerID","string",[ContactTitle]) AS CustomersFROM CustomersGROUP BY ContactTitle;
'************ Code Start **********
'This code was originally written by Dev Ashish
'It is not to be altered or distributed,
'except as part of an application.
'You are free to use it in any application,
'provided the copyright notice is left unchanged.
'
'Code Courtesy of
'Dev Ashish
'
Function fConcatFld(stTable As String, _
stForFld As String, _
stFldToConcat As String, _
stForFldType As String, _
vForFldVal As Variant) _
As String
'Returns mutiple field values for each unique value
'of another field in a single table
'in a semi-colon separated format.
'
'Usage Examples:
' ?fConcatFld(("Customers","ContactTitle","CustomerID", _
' "string","Owner")
'Where Customers = The parent Table
' ContactTitle = The field whose values to use for lookups
' CustomerID = Field name to concatenate
' string = DataType of ContactTitle field
' Owner = Value on which to return concatenated CustomerID
'
Dim lodb As Database, lors As Recordset
Dim lovConcat As Variant, loCriteria As String
Dim loSQL As String
Const cQ = """"
On Error GoTo Err_fConcatFld
lovConcat = Null
Set lodb = CurrentDb
loSQL = "SELECT [" & stFldToConcat & "] FROM ["
loSQL = loSQL & stTable & "] WHERE "
Select Case stForFldType
Case "String":
loSQL = loSQL & "[" & stForFld & "] =" & cQ & vForFldVal & cQ
Case "Long", "Integer", "Double": 'AutoNumber is Type Long
loSQL = loSQL & "[" & stForFld & "] = " & vForFldVal
Case Else
GoTo Err_fConcatFld
End Select
Set lors = lodb.OpenRecordset(loSQL, dbOpenSnapshot)
'Are we sure that duplicates exist in stFldToConcat
With lors
If .RecordCount <> 0 Then
'start concatenating records
Do While Not .EOF
lovConcat = lovConcat & lors(stFldToConcat) & "; "
.MoveNext
Loop
Else
GoTo Exit_fConcatFld
End If
End With
'That's it... you should have a concatenated string now
'Just Trim the trailing ;
fConcatFld = Left(lovConcat, Len(lovConcat) - 2)
Exit_fConcatFld:
Set lors = Nothing: Set lodb = Nothing
Exit Function
Err_fConcatFld:
MsgBox "Error#: " & Err.Number & vbCrLf & Err.Description
Resume Exit_fConcatFld
End Function
'************ Code End **********
Copy and paste the fConcatFld( ) function into a code module. Change the
following VBA line of code:
lovConcat = lovConcat & lors(stFldToConcat) & "; "
to:
lovConcat = lovConcat & lors(stFldToConcat) & ", "
... then save it and compile the code.
Next, create a new query and open the query in SQL View and paste the
following SQL statement into the SQL View pane:
SELECT EventID, fConcatFld("MyTable","EventID","PersonName","Long", EventID)
AS PersonNames
FROM MyTable
GROUP BY EventID;
... and replace "MyTable" with the name of your table. If the "EventID"
data type isn't Long, then you'll need to replace this in the SQL statement,
too, with whatever data type your field is using.
Save and run the query. Voila! Comma separated list.
I created a VBA script to pull prices from websites by getting the value within an HTML Class.
Please see VBA Script pull data from website for more context.
This works really well however there are some cases where there is only 1 price (no RRP & sale price) and therefore i need to somehow incorporate an if statement to look for the a class name, if that doesn't exist look for another.
For example I have the following spreadsheet:
| A | B | C |
| | Item | Price |
| | bfd/garden-structures/arbours/arbours-sunflower | |
| | bfd/garden-structures/arbours/tatton-corner-arbour-seat | |
| | bsd/garden-storage/wooden-storage/4-x-2-windsor-garden-storage-chest | |
In this example the first 2 work with the code below: (looking int class VariantPrice & NowValue) however the 3rd example doesn't work as the classes VariantPrice & NowValue do not exist, however it does have the class price & SinglePrice.
The code I have used is below:
Sub BuyDeckingDirect()
Dim ie As New InternetExplorer
Dim doc As HTMLDocument
Dim result As IHTMLElement
Dim result2 As IHTMLElement
Dim item As String
Dim lRow As Long
'ie.Visible = True'
lRow = 2
item = Worksheets("BuyDeckingDirect").Range("B" & lRow).Value
MsgBox "Price Dump Started"
Do Until item = ""
ie.navigate "http://www.buydeckingdirect.co.uk/" & item
Do
DoEvents
Loop Until ie.readyState = READYSTATE_COMPLETE
Set doc = ie.document
Set result = doc.querySelector(".VariantPrice")
Set result2 = result.querySelector(".NowValue")
Worksheets("BuyDeckingDirect").Range("C" & lRow).Value = result2.innerText
lRow = lRow + 1
item = Worksheets("BuyDeckingDirect").Range("B" & lRow).Value
Loop
MsgBox "BuyDeckingDirect Price Dump Complete"
End Sub
Any help would be really appreciated!
Thanks
Jess
Combine both classes in the call to querySelector and if result is Nothing, call it again with the alternative class.
Example:
' ...
Set result = doc.querySelector(".VariantPrice .NowValue")
If result Is Nothing Then
Set result = doc.querySelector(".VariantPrice .price")
End If
' You should consider the fact that you can have neither
If result Is Nothing Then
Worksheets(...etc...).Value = "N/A"
Else
Worksheets(...etc...).Value = result.innerText
End If
Of course you can also check for the existence of the NowValue class after setting result like so:
' ...
Set result = doc.querySelector(".VariantPrice")
If IsNull(result.querySelector(".NowValue")) Then
Set result2 = result.querySelector(".price")
Else
Set result2 = result.querySelector(".NowValue")
End If
Personally, I prefer the 1st option but it's up to your use case.
I've been trying to output my results from a table as a String for awhile now. Whenever I use a query in my table and call the Field Table Adapter, it will always show a foreign key constraint exception. I have deleted all my primary and foreign keys to test but it still shows the same exception. I have tried using this code to output to a textbox :
Public Sub listfields()
Dim ds As New DataSet
Dim dt As DataTable = ds.Tables.Item("")
Dim fieldname As String = Field_nameComboBox.SelectedItem
dt = FieldvalueTableAdapter.GetData
Dim i As Integer = 0
While i < dt.Rows.Count
txtbx_field_list.Text = dt.Rows(i).Item("field_name")
txtbx_field_list2.Text = dt.Rows(i).Item("field_value")
txtbx_field_list3.Text = dt.Rows(i).Item("sort_priority")
i += 1
End While
End Sub
However, this shows the last item in the array only. Is there a way to either use a query to output data I want as a string or a method of placing the results into a string?
Thank you.
if you want to show all you records in one textBox with delimiter |
use :
Dim i As Integer = 0
While i < dt.Rows.Count - 1
txtbx_field_list.Text += " | " & dt.Rows(i).Item("field_name") & " | " & Environment.NewLine
txtbx_field_list2.Text += " | " & dt.Rows(i).Item("field_value") & " | " & Environment.NewLine
txtbx_field_list3.Text += " | " & dt.Rows(i).Item("sort_priority") & " | " & Environment.NewLine
i += 1
End While
I still don;t uderstand what you want:
+---------------------+------------------------------+---------------------+
|Name 1 | Name2 | Name 3 | Val 1 Val2 Val3|sort1 sort2 sort3|
or you want
Name1 | val1 | sort1 |
Name2 | val2 | sort2 | etc..
You are overriding each of the text Box variables on each loop iteration.
Change the '=' to '+=' to get all items,
add delimiters if necessary.