Issue with connecting MySQL to VB.NET when multiple users - mysql

I'm doing a computing project in VB.NET which requires a user to login before the application runs. I also need to use databases throughout so my weapon of choice was MySQL.
This is the code I am using for when the user presses the login button which connects and opens the database.
Private Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click
MySqlConn.ConnectionString = "server=localhost;" _
& "user id=" & txtUsername.Text & ";" _
& "password=" & txtPassword.Text & ";" _
& "database=main"
Try
MySqlConn.Open()
MessageBox.Show("Connection successful!")
Catch ex As Exception
MessageBox.Show("Cannot connect to the database: " & ex.Message)
End Try
End Sub
This is all well and fine but when I want to execute querys later (and in different forms) etc I will have to pretty much write the same code again. I thought of putting it in a seperate class and calling it when I needed but I couldn't see how it could grab the details form the text box for the connnection string. And I cant use static parameters as their could be use multiple users.
Thanks in advance,
Robin

You can create MySqlConn as a global, that way it can be seen from anywhere in your application.
http://msdn.microsoft.com/en-us/library/ms973875.aspx
Once you've connected (using the user name and password) you shouldn't need to reference the text boxes again.

Related

MS Access Report from MYSQL DB

I'm trying to get some information from a mysql database to a report in access. But I can't figure out how to get the information there since I'm using DAO connections in vba and cant use linked tables.
I've tried storing the information into a string from the form that I already have the information at through a DAO connection directly to mysql db with no luck.
Private Sub Command67_Click()
DoCmd.Save
DoCmd.GoToRecord , , acNewRec
Me.Label39.Visible = True
Dim strWhere As String
strWhere = "[ID] = " & Me.[Id]
DoCmd.OpenReport "MyReport", acViewPreview, , strWhere
End Sub
I use preview in that code to see some result but what I would like to do is print directly to the printer since this is a client turn receipt i need those to print fast.
Again I can't use linked tables.
After investigating on your former questions (some should be linked to that question), I see the problem. You don't link the MySQL-Tables what would make things easier for you.
But you can still use queries! Just put your connection string (maybeGlobales.ConnStringin former questions) in the queriesODBC Connection Stringin query design->properties. That makes the query a passthrough-query that is passed to MySQL-Server directly, not using MDAC.
Just set the reportsRecordSourceto the name of the query.
You can also build the query in VBA, but you can't use a temporary QueryDef("") as you can't set the Reports-Recordset, so use a non temp one.
Example (assumes there is a QueryDef named QueryForReport):
Sub EditQueryDefPassthrough()
With CurrentDb.QueryDefs("QueryForReport")
.Connect = "ODBC;Driver={MySQL ODBC 5.3 ANSI Driver};" _
& "Server=YourServerName;" _
& "Database=YourDatabaseName;" _
& "User=YourMysqlUserName;" _
& "Password=MysqlPwdForUser;" _
& "Option=3;" ' adapt this to your MySQL ODBC Driver Version and server settings
.SQL = "SELECT `Field` FROM `TABLE` LIMIT 1,1;" 'put SQL here (MySQL SQL Dialect, not MS-Access!). You can't use Access functions here (like Replace(), ..., but those of MySQL like Concat().
End With
End Sub
The QueryDef needs to be set before the Report_Load Event, but in Report_Open should be sufficent (e.g. if you want to use OpenArgs for building the SQL-String)

Slow remote mysql with VB.net- need to speed up

I'm using vb.net and mysql( from a shared hosting) with the following code
Public conn As OdbcConnection
Public da As OdbcDataAdapter
Public ds As DataSet
Public dr As OdbcDataReader
Public cmd As OdbcCommand
Public MysqlConn As MySqlConnection
Public xc As MySqlCommand
Public xd As MySqlDataAdapter
Public serv As String, user As String, pass As String, db As String
Sub connect()
serv = "xyz.com"
user = "abc"
pass = "mypasword"
db = "mydb"
MysqlConn = New MySqlConnection()
MysqlConn.ConnectionString = "server=" & serv & ";" & "UserID=" & user & ";" & "password=" & pass & ";" & "database=" & db & ";Character Set=utf8;"
Try
MysqlConn.Open()
MysqlConn.Close()
Catch myerror As Exception
MsgBox("Connection Error")
End Try
End Sub
Now any select, insert or update action takes more that 5 seconds and freezes the whole application. But my client wants it faster. How can I speed it up? is that the hosting or mysql or connection method - which is to upgrade or alter with other to make it faster?
Thanks
India:Canada -- 140ms seems reasonable. This means that every query sent to the server will take at least that long.
As for the "5 seconds"... Turn on the "General log" for a short while and run the app. Then look through the log. You may find that vb.net is injecting some extra commands, possibly in front of each query you run. This would further slow down your application. If that is the case, abandon vb.net, and be suspicious of any other 3rd party software.
I hope you are doing only one "connection" for an entire session?
Aside from that, the best thing to consider doing is to write Stored Routines (Procedures, Functions, Triggers, etc) whenever you need to perform more than one query in a row. That way, you can issue one query instead of multiple SQL statements, thereby fewer roundtrips.

Show Users on Access Database

I am trying to show all the users that is currently on my Access database. I am using a VBA code that I found online and am trying to modify it to my needs. I am trying to get all the available users and display it on List Box on my form called "ListUsers".
The code is able to output to the debug window but I'm unable to update my list box. I get the following error: "Run-time error '6014': The RowSourceType property must be set to 'Value List' to use this method." I looked on the property window for that list box and couldn't find anything related to RowSourceType. I have tried a few different suggestions online but I am still unable to update the list box, so I wanted to see if anyone here may have some ideas. My code is below, I placed the VBA code on a button click.
Option Compare Database
Option Explicit
Private Sub cmd_Users_Click()
Dim cn As New ADODB.Connection
Dim rs As New ADODB.recordset
Dim i, j As Long
Set cn = CurrentProject.Connection
' The user roster is exposed as a provider-specific schema rowset
' in the Jet 4.0 OLE DB provider. You have to use a GUID to
' reference the schema, as provider-specific schemas are not
' listed in ADO's type library for schema rowsets
Set rs = cn.OpenSchema(adSchemaProviderSpecific, _
, "{947bb102-5d43-11d1-bdbf-00c04fb92675}")
'Output the list of all users in the current database.
Debug.Print rs.Fields(0).Name, "", rs.Fields(1).Name, _
"", rs.Fields(2).Name, rs.Fields(3).Name
While Not rs.EOF
Debug.Print rs.Fields(0), rs.Fields(1), _
rs.Fields(2), rs.Fields(3)
ListUsers.AddItem "'" & rs.Fields(0) & "-" & rs.Fields(1) & "'"
rs.MoveNext
Wend
End Sub
I figured it out... I had to set the RowSourceType on the code. I added the following to the button click event:
Me.ListUsers.RowSourceType = "Value List"
There is also a good post here:
Ms Access AddItem with VBA

Multi-Page vs Multi-PDF Loop problems

I have a form that contains multiple partners that share a "pool". The partners are listed on a subform. After I'm done entering the information, I want a button to run a report for each of the partners with their specific information. But since it's multiple partners and I need one report for each (which I then want to email), I want to use a Loop to go through each of the partners.
EDIT1: Added entire code for review. I do have Option Explicit in and I have compiled it as well.
Private Sub btn_Run_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
strSQL = "Select * FROM Cobind_qryReport WHERE PartPoolName = """ & Me.TopLvlPoolName & """"
Debug.Print "strSQL: " & strSQL
Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL)
On Error GoTo Err_PO_Click
If MsgBox("Do you wish to issue the cobind invites?", vbYesNo + vbQuestion, "Confirmation Required") = vbYes Then
rs.MoveFirst
Do While rs.EOF = False
DoCmd.OutputTo acOutputReport, "Cobind_rptMain", acFormatPDF,_
"K:\OB MS Admin\Postage\CoBind Opportunities\Sent Invites\" _
& rs!CatCode & "_" & rs!PartPoolName "Cobind Invite_" & _
Format(Now(), "mmddyy") & ".pdf"
DoCmd.SendObject acSendReport, "Cobind_rptMain", acFormatPDF, ,_
, , " Cobind Invite", "Please find the cobind invite attached._
Response is needed by " & [RSVP] & ". Thank you.", True
rs.MoveNext
Loop
End If
Exit_PO_Click:
MsgBox ("It didn't work")
rs.Close
Set rs = Nothing
Set db = Nothing
Exit Sub
Err_PO_Click:
MsgBox Err.Description
Resume Exit_PO_Click
End Sub
This should allow me to create a report for each record in my query, save it to my server, then open an email to send it out. Right now, it appears that the [PartPoolName] is hanging up the code because I'm getting a "Microsoft Office Access can't find the field "|" referred to in your expression." If I take out the [PartPoolName], it'll create a PDF with four pages (each page showing a partner), where I want to end up with four separate PDFs.
The first thing you should do is add Option Explicit to the Declarations section of your module.
Then, from the Visual Basic editor's main menu, select Debug->Compile [your project name here]
Fix all the problems the compiler complains about. I suspect one of the compiler's first complaints may be triggered by this section of your code:
rs.MoveFirst
Do While Recordset.EOF = False
Do you have two recordset objects open, or one?
After you fix everything the compiler complains about, try your revised code.
If you get runtime errors, show us the exact error message and which code line is highlighted.
If the part of your code you haven't shown us includes an error hander, you can disable that error handler like so:
'On Error GoTo Err_PO_Click
Error handlers are great for production to shield users from errors. However, during development you really need to be able to identify which code line causes the error.
Alternatively, you can leave your error handler active and select Tools->Options from the editor's main menu. In the Options dialog, select the General tab, then select the "Break on All Errors" radio button and click OK. You can switch that option back to "Break on Unhandled Errors" after you finish your testing.
Update: You wrote: Right now, it appears that the [PartPoolName] is hanging up the code because I'm getting a "Microsoft Office Access can't find the field "|" referred to in your expression."
What is [PartPoolName]? If it's a field in the recordset, you can reference its value as rs!PartPoolName If it's something else, perhaps a global variable, give us more information about it.
Update2: Whenever your current code completes without error, you will hit this:
Exit_PO_Click:
MsgBox ("It didn't work")
Can that be right?
Update3: This OutputTo statement is your issue now, right?
DoCmd.OutputTo acOutputReport, "Cobind_rptMain", acFormatPDF,_
"K:\OB MS Admin\Postage\CoBind Opportunities\Sent Invites\" & _
"Cobind Invite_" & Format(Now(), "mmddyy") & ".pdf"
Cobind_rptMain is a report. It has a RowSource for its data. You're calling OutputTo with that report 4 times (once for each of the 4 rows in the recordset). Yet you expect 4 different versions of that report ... a separate report for each PartPoolName value?
To finish off the fine work by HansUp visit a page on how to print a report for a single record and how to generate reports to attach to emails. See the Emailing reports as attachments from Microsoft Access page.

MS Access - check sub-form before entry for duplicate

I've got a subform (customersAnswersSub) inside of a main form (customersAnswers). Upon someone entering a new customerAnswersSub entry - I wanted it to check for duplicates first.
It has to check across 4 different fields to match first.
This is what I've got so far.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim rsGlobals As ADODB.Recordset
Dim sql
Set rsGlobals = New ADODB.Recordset
sql = "Select * From CustomerAnswerD where subscriptionNo=" & _
Me.subscriptionNo & " AND journal=" & Me.Journal & _
" AND volume=" & Me.volume & " AND issue=" & Me.issue
rsGlobals.Open sql, CurrentProject.Connection, adOpenDynamic, adLockOptimistic, adCmdText
If Not rsGlobals.BOF And Not rsGlobals.EOF Then
MsgBox ("Already entered")
Cancel = True
Me.Undo
End If
End Sub
it doesn't do anything - just sits there. when I close the form it'll pop up a - id already exists box.
Any idea, i'm pretty unexperienced when it comes to Access VB.
thank you
it doesn't do anything - just sits there
Just checking, since you said you're inexperienced with Access ... the form update event is not triggered until the record save is attempted. That may not happen automatically as soon as the user enters data into all the fields. However, you can trigger the update by navigating to a different record in the subform, or by a method such as choosing Records->Save Record from Access' (2003) main menu.
I don't see anything wrong with your BeforeUpdate procedure. Still I would convert it use the DCount() function instead of opening an ADO recordset. (See Access' help topic for DCount)
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim strCriteria As String
strCriteria = "subscriptionNo=" & Me.subscriptionNo & " AND journal=" & Me.Journal & _
" AND volume=" & Me.volume & " AND issue=" & Me.issue
Debug.Print strCriteria
If Dcount("subscriptionNo", "CustomerAnswerD", strCriteria) > 0 Then
MsgBox ("Already entered")
Cancel = True
Me.Undo
End If
End Sub
That assumes your table's subscriptionNo, journal, volume, and issue fields are all numeric data types. If any of them are text type, you will need to enclose the values in quotes within strCriteria.
I added Debug.Print strCriteria so you can view the completed string expression in the Immediate Window. You can also troubleshoot that completed string by copying it and pasting it into SQL View of a new query as the WHERE clause.
Also, consider adding a unique index on subscriptionNo, journal, volume, and issue to your CustomerAnswerD table design. That way you can enforce uniqueness without relying solely on your form to do it. The index will also give you faster performance with the DCount function, or your original recordset SELECT statement.
If you keep your original recordset approach, close the recordset and set the object variable = Nothing before exiting the procedure.